Disable the Java plugin in browsers to avoid drive-by attacks

Every now and then, Java is subject to security issues where code can break out of Java's sandbox and obtain more privileges than it should.
In almost all cases, such issues are actively being used for drive-by attacks via the Java browser plug-in, for example by malicious ad banners.

Since removing Java completely is not an option for us, make sure the Java plug-in is always disabled in every browser, even when you have updated Java on your machine.
Please re...

How to inspect controller filter chains in specs

Sometimes you need to look at the filter chain in specs. You can do it like that on Rails 2:

controller.class.filter_chain.map(&:method)

Note that we need to look at the controller's class since before_filter and after_filter stuff happens on the class level.

Also mind that the above code will give you all filters, both those run before and after an action. You can query before? and after? on the filter objects to scope down to only some of them:

controller.class.filter_chain.select(&:before?).map(&:method)

For Rails 3, ...

Rspec shared example group error: ensure_shared_example_group_name_not_taken

Never name your shared example group *_spec.rb. Otherwise rspec will try to load your example group as a spec and you will get the error above.

Limitations you should be aware of when Internet Explorer 9 parses CSS files

Internet Explorer until version 9 has some limitations when parsing CSS files

Summarized, these are:

  • Up to 31 CSS files or <style> tags per page.
  • Up to 4095 selectors per CSS file.
  • Up to 3 nested @import rules

To test the selector limit for a specific browser, check this CSS selector limitation test website.

When you run into this issue, the following links might be helpful to fix the problem. The Idea is to split up the css ...

Mock the browser time or time zone in Selenium features

In Selenium features the server and client are running in separate processes. Therefore, when mocking time with a tool like Timecop, the browser controlled by Selenium will still see the unmocked system time.

timemachine.js allows you to mock the client's time by monkey-patching into Javascript core classes. We use timemachine.js in combination with the Timecop gem to synchronize the local browser time to the ...

Why stubbing on associated records does not always work as expected

Be careful when stubbing out attributes on records that are defined by associations. Nothing is as it seems to be.

The associated record has its own universe of things; when delegating calls to it, you ca not stub methods on the associated record and expect them to be around. That is a general issue with this pattern/approach.

What's happening?

Consider these classes:

class Post < ActiveRecord::Base
  belongs_to :thread
  
  def thread_title
    thread.title
  end
end

class Thread < Acti...

Test your CSS rendering output with GreenOnion

No one wants to cry over regression issues in views; does testing HTML and CSS have to be such a back and forth between designers and devs? Why is it that the rest of the stack can have TDD and BDD but not the presentation layer? Well, GreenOnion is here to help you get the same results on testing front-end styling that you've enjoyed in your unit and integration tests up to now.
GreenOnion records 'skins', which are snapshots of the current state of a view (or any page that a browser can navigate to). The first time that it is run on a view...

rspec_candy 0.2.0 now comes with our most popular matchers

Our rspec_candy gem now gives you three matchers:

be_same_number_as

Tests if the given number is the "same" as the receiving number, regardless of whether you're comparing Fixnums (integers), Floats and BigDecimals:

100.should be_same_number_as(100.0)
50.4.should be_same_number_as(BigDecimal('50.4'))

Note that "same" means "same for your purposes". Internally the matcher compares normalized results of #to_s.

be_same_second_as

...

Gem development: When your specs don't see dependencies from your Gemfile

When you develop a gem and you have a Gemfile in your project directory, you might be surprised that your gem dependencies aren't already required in your specs. Here is some info that should help you out:

  • Bundler actually doesn't automatically require anything. You need to call Bundler.require(:default, :your_custom_group1, ...) for that. The reason why you never had to write this line is that Rails does this for you when it boots the environment.
  • That also means that if you have an embedded Rails app in your spec folder (like [h...

Consul 0.4.0 released

Consul 0.4.0 comes with some new features.

Dependencies

  • Consul no longer requires assignable_values, it's optional for when you want to use the authorize_values_for macro.
  • Consul no longer uses ActiveSupport::Memoizable because that's deprecated in newer Railses. Consul now uses Memoizer for this.

Temporarily change the current power

When you set Power.current to a power in an RS...

Check if an object is an ActiveRecord scope

Don't say is_a?(ActiveRecord::NamedScope::Scope) because that is no longer true in Rails 3 and also doesn't match unscoped ActiveRecord classes themselves (which we consider scopes for all practical purposes).

A good way is to say this instead:

object.respond_to?(:scoped)

Use the "paper_trail" gem to track versions of records

paper_trail is an excellent gem to track record versions and changes.

You almost never want to reimplement something like it yourself. If you need to log some extra information, you can add them on top.

It comes with a really good README file that holds lots of examples. I'll show you only some of its features here:

  • Setting up a model to track changes
    Just add has_paper_trail to it:
    class User < ActiveRecord::Base
    has_paper_trail
    end
  • Accessing a previous version
    Saying user.previous_version gi...

Updated: Remove quotes from Sass mixin arguments

When we looked at this card together a year ago, we were no longer sure if unquote is actually useful. I now found a good example for when you need unquote, and rewrote the card accordingly.

How to change will_paginate's "per_page" in Cucumber features

The will_paginate gem will show a default of 30 records per page.
If you want to test pagination in a Cucumber feature, you don't want to create 31 records just for that.

Instead, you probably want to modify the number of items shown, by saying something like this:

Given we paginate after 2 users

Using the following step definition, you now can! :)

require 'cucumber/rspec/doubles'

Given /^paginate after (\d+) (.*)$/ do |per_page, model_name|
  model = model_name.singularize.gsub(/...

jQuery.cssHooks – jQuery API

The $.cssHooks object provides a way to define functions for getting and setting particular CSS values. It can also be used to create new cssHooks for normalizing CSS3 features such as box shadows and gradients.

For example, some versions of Webkit-based browsers require -webkit-border-radius to set the border-radius on an element, while earlier Firefox versions require -moz-border-radius. A css hook can normalize these vendor-prefixed properties to let .css() accept a single, standard property name (border-radius, or with DOM property synt...

Updated: Capybara: Check that a page element is hidden via CSS

  • The step we used in the past (Then "foo" should not be visibile) doesn't reliably work in Selenium features.
  • I overhauled the entire step so it uses Javascript to detect visibility in Selenium.
  • The step has support for jQuery and Prototype projects, so it should be a drop-in replacement for all your projects.
  • For Rack::Test the step no longer uses XPath so you should be able to understand it when you are not a cyborg :)
  • There were some other cards detailing alternative steps to detect visibility. I deleted all these other cards s...

RubyMine: Using pinned tabs will increase your productivity

I highly recommend that you make use of RubyMine's feature to pin tabs.

When you pin all "important" files, you can follow method definitions, wildly open files from search results and have a ton of open tabs -- without the problem of finding the stuff you were working on before.

Guide

  1. Pin the tabs of files that are currently in the focus of your work (important models, specs, etc):
    • Right-click a tab and select "Pin tab"
    • Or use a shortcut (see below)
  2. Work as usual.
  3. Once you opened other tabs because you searched ...

Speed up large Cucumber test suites

Test suites usually grow over time as more and more development time is spent on a projects. Overall run-time and performance of Cucumber suites in turn increases, too.

You can use the very same way Henning suggested for speeding up RSpec some time ago.

Put the following into features/support/deferred_garbage_collection.rb

Before do
  DeferredGarbageCollection.start
end

After do
  DeferredGarbageCollection.reconsider
end

We...

When overriding #method_missing, remember to override #respond_to_missing? as well

When you use method_missing to have an object return something on a method call, always make sure you also redefine respond_to_missing?.

If you don't do it, nothing will break at a first glance, but you will run into trouble eventually.

Consider this class:

class Dog
  
  def method_missing(method_name, *args, &block)
    if method_name == :bark
      'woof!'
    else
      super
    end
  end
  
end

This will allow you to say:

Dog.new.bark
=> "woof!"

But:

Dog.new.respond_to? :bark
=> false
```...

How to: Specify size of Selenium browser window

Applications often show or hide elements based on viewport dimensions, or may have components that behave differently (like mobile vs desktop navigation menus).
Since you want your integration tests to behave consistently, you want to set a specific size for your tests' browser windows.

Using WebDriver options / Chrome device metrics

For Google Chrome, the preferred way is setting "device metrics". This allows you to configure dimensions larger than your display and enable/disable touch behavior.

Simply use register_driver to set up...

Run specific version of bundler

You can specify the version of bundler to execute a command (most often you need an older version of bundler, but don't want to uninstall newer ones):

bundle _1.0.10_ -v
Bundler version 1.0.10

An example is rails 3.2, which freezes bundler at version ~> 1.0:

Bundler could not find compatible versions for gem "bundler":
  In Gemfile: rails (~> 3.2) was resolved to 3.2.0, which depends on bundler (~> 1.0)

Current Bundler version: bundler (1.13.6)

You can solve this with:

gem install bundler -v 1....

Setup your terminal to not scroll when there is new output

When you are scrolling up to investigate a test failure it is super annoying when the terminal scrolls back down whenever the running test outputs another line. Luckily you can disable this behavior:

  • Gnome terminal: *Edit -> Profile preferences -> Scrolling", uncheck Scroll on output
  • Terminator: Right click on terminal screen, Preferences -> Profile -> (for each profile) -> Scrolling, uncheck Scroll on output

Updated: Test a gem in multiple versions of Rails

Updated the card with our current best practice (shared app code and specs via symlinks).

rake spec + rails_admin = weirdly failing specs

If you use rails_admin, your specs pass with the rspec binary, but not using rake spec (or rake parallel:spec etc), put this at the top of your spec_helper:

ENV['SKIP_RAILS_ADMIN_INITIALIZER'] = 'false'

Don't ask.

This is probably also true for cucumber, your env.rb would be the right place.