Delete all MySQL records while keeping the database schema

You will occasionally need to clean out your database while keeping the schema intact, e.g. when someone inserted data in a migration or when you had to kill -9 a frozen test process.

Old Capybara versions already have the Database Cleaner gem as dependency. Otherwise add database_cleaner to your *Gemfile`. This lets you say this from the Rails console:

DatabaseCleaner.strategy = :truncation
DatabaseCleaner.cl...

Synchronize a Selenium-controlled browser with Capybara

When you click a link or a press a button on a Selenium-controlled browser, the call will return control to your test before the next page is loaded. This can lead to concurrency issues when a Cucumber step involves a Selenium action and a Ruby call which both change the same resources.

Take the following step which signs in a user through the browser UI and then sets a flag on the user that was just signed in:

Given /^the user "([^"]*)" signed in (\d) days ago$/ do |name, days|
  visit new_session_path
  fill_in 'Username', :w...

plus2/whereuat - GitHub

Adds a slide out panel to your Rails application that directs clients to test stories that have been marked as 'delivered' in Pivotal Tracker.

Traversing the DOM tree with jQuery

jQuery offers many different methods to move a selection through the DOM tree. These are the most important:

$element.find(selector)
Get the descendants of each element in the current set of matched elements, filtered by a selector. Does not find the current element, even it matches. If you wanted to do that, you need to write $element.find(selector).addBack(selector).

$element.closest(selector)
Get the first ancestor el...

Unexpected behavior when changing both an association and its foreign key attribute in ActiveRecord

When you set both a record's association and that association's foreign key attribute, Rails does not realize you are talking about the same thing. The association change will win in the next save, even if the foreign key attribute was changed after the association.

As an example, assume you have these two models:

class Group < ActiveRecord::Base
  has_many :users
end

class User < ActiveRecord::Base
  validates_presence_of :group_id
  belongs_to :group
end

We will now load a User and change both its `g...

Why two Ruby Time objects are not equal, although they appear to be

So you are comparing two Time objects in an RSpec example, and they are not equal, although they look equal:

expected: Tue May 01 21:59:59 UTC 2007,
     got: Tue May 01 21:59:59 UTC 2007 (using ==)

The reason for this is that Time actually tracks fractions of a second, although #to_s doesn't say so and even though you probably only care about seconds. This means that two consecutive calls of Time.now probably return two inequal values.

Consider freezing time in your tests so it is not dependent on the speed of the executi...

Check that a Range covers an element in both Ruby 1.9 and 1.8.7

In order to cover some edge cases you rarely care about, Range#include? will become very slow in Ruby 1.9:

Range#include? behaviour has changed in ruby 1.9 for non-numeric ranges. Rather than a greater-than/less-than check against the min and max values, the range is iterated over from min until the test value is found (or max) [...] Ruby 1.9 introduces a new method Range#cover? that implements the old include? behaviour, however this method isn’t available in 1.8.7.

The attached ...

Check that an element is hidden via CSS with Spreewald

If you have content inside a page that is hidden by CSS, the following will work with Selenium, but not when using the Rack::Test driver. The Selenium driver correctly only considers text that is actually visible to a user.

Then I should not see "foobear"

This is because the Rack::Test driver does not know if an element is visible, and only looks at the DOM.

Spreewald offers steps to check that an element is hidden by CSS:

Then "foo" should be hidden

You can also check that an el...

Closures in Ruby

If you want to get a deep understanding of how closures, blocks, procs & lambdas in Ruby work, check out the code at the attached link.

Here the summary:

^
---------------------------- Section 6: Summary ----------------------------

 So, what's the final verdict on those 7 closure-like entities?          

                                                     "return" returns from closure
                                    True closure?    or declaring context...?         Arity check?
                         ...

Insert an ndash and other special characters using the Compose key on Linux

Although you can access many symbols using the AltGr key you may be missing some, like the en-dash (–) or em-dash (—). You can use a compose key for them instead.

First, make sure you have a compose key configured.

Configuring a compose key

I suggest using the "Menu" key which is located between the right Meta and Ctrl key.

Ubuntu / MATE

Control Center → Keyboard → Layout → Options → Position of Compos...

Configuring User Agents with Capybara + Selenium Webdriver

A while ago we were working on an application that had an entire version specially created for mobiles, such as the iPhone. This specific application was entirely tested with Capybara, Steak and Selenium Webdriver. Although the test suite wasn’t the fastest one in the world, the web application was very well tested, and to guarantee that we would also be testing the mobile version, we would have to simulate an iPhone user agent accessing the application.

But wait, you might be thinking that we are not able to change browser headers while ...

Simple database lock for MySQL

Note: For PostgreSQL you should use advisory locks. For MySQL we still recommend the solution in this card.


If you need to synchronize multiple rails processes, you need some shared resource that can be used as a mutex. One option is to simply use your existing (MySQL) database.

The attached code provides a database-based model level mutex for MySQL. You use it by simply calling

Lock.acquire('string to synchronize on') do
  # non-th...

RSpec < 2.11: ActiveRecord scopes must be loaded before using the "=~" matcher

To test whether two arrays have the same elements regardless of order, you can use the =~ matcher in RSpec < 2.11:

actual_array.should =~ expected_array

If either side is an ActiveRecord scope rather than an array, you should call to_a on it first, since =~ does not play nice with scopes:

actual_scope.to_a.should =~ expected_scope.to_a

If you use RSpec >= 2.11 we recommend using the match_array or contain_exactly matchers instead of =~.
Use the eq matcher only if the order of records matters.

Test that a select field contains an option with Cucumber

This note describes a Cucumber step definition that lets you say:

Then "Mow lawn" should be an option for "Activity"
But "Reply support mail" should not be an option for "Activity"

Note that this step checks whether an option is available, not that it is selected. There is a separate step to test that an option is selected.

Capybara (0.4.1 or higher)

Then /^"([^"]*)" should( not)? be an option for "([^"]*)"(?: within "([^\...

Fix errors when rendering PDF output

If you run specs or your application and get an error like:
ActionController::MissingFile in 'ProductsController#show, should render PDF'
Cannot read file /some/file.pdf

You may be missing the HTMLDOC binary on your system. Install it like this on Debian/Ubuntu:
sudo apt-get install htmldoc

babushka: test-driven sysadmin

The idea is this: you take a job that you'd rather not do manually, and describe it to babushka using its DSL. The way it works, babushka not only knows how to accomplish each part of the job, it also knows how to check if each part is already done. You're teaching babushka to achieve an end goal with whatever runtime conditions you throw at it, not just to perform the task that would get you there from the very start.

Testing if two date ranges overlap in Ruby or Rails

A check if two date or time ranges A and B overlap needs to cover a lot of cases:

  1. A partially overlaps B
  2. A surrounds B
  3. B surrounds A
  4. A occurs entirely after B
  5. B occurs entirely after A

This means you actually have to check that:

  • neither does A occur entirely after B (meaning A.start > B.end)
  • nor does B occur entirely after A (meaning B.start > A.end)

Flipping this, A and B overlap iff A.start <= B.end && B.start <= A.end

The code below shows how to implement this in Ruby on Rails. The example is a class `Interv...

Rails: When defining scopes with class methods, don't use `self`

Sometimes it is useful to define a named scope by implementing a static method with the scope's name on the scoped class. For instance, when a method should decide which existing scope should be the next link in the scope chain. Take this class for example:

class Meal < ActiveRecord::Base

  named_scope :for_date, lambda { |date| :conditions => { :date => date }}
  named_scope :with_meat, :conditions => { :meat => true }
  named_scope :without_meat, :conditions => { :meat => false }

  def self.suitable_for(user)
    if user.vegetar...

Split an array into groups

Given group size

If you would like to split a Ruby array into pairs of two, you can use the Rails ActiveSupport method in_groups_of:

>> [1, 2, 3, 4].in_groups_of(2)
=> [[1, 2], [3, 4]]

>> [1, 2, 3, 4, 5].in_groups_of(2)
=> [[1, 2], [3, 4], [5, nil]]

>> [1, 2, 3, 4, 5].in_groups_of(2, 'abc')
=> [[1, 2], [3, 4], [5, 'abc']]

>> [1, 2, 3, 4, 5].in_groups_of(2, false)
=> [[1, 2], [3, 4], [5]]

Given group cou...

Test the status code of a response in Cucumber

Webrat

Then /^I should get a response with status (\d+)$/ do |status|
  response.status.should include(status)
end

Capybara

Then /^I should get a response with status (\d+)$/ do |status|
  page.status_code.should include(status.to_i)
end

Perform HTTP basic authentication in Cucumber (with or without Selenium)

This card describes a Cucumber step that lets you say:

When I perform basic authentication as "username/password" and I visit the admin area

The path component ("... the admin area") is parsed through your path_to helper in features/support/paths.rb.

Capybara

The step definition is part of Spreewald. The step has been tested with multiple versions of Capybara, Rack::Test and Selenium.

Webrat (legacy)

This is a simpler version of the step above:

When /...

How to define constants with traits

When defining a trait using the Modularity gem, you must take extra steps to define constants to avoid caveats (like when defining subclasses through traits).

tl;dr

In traits, always define constants with explicit self.

If your trait defines a constant inside the as_trait block, it will be bound to the trait module, not the class including the trait.
While this may seem unproblematic at first glance, it becomes a problem when including trai...

Setting up Tomcat to use an existing OpenSSL certificate

This is for those who already own an SSL certificate (e.g. using it in the Apache HTTP Server) and need to feed it to a Tomcat application. The main issue is that you need to convert your OpenSSL certificate for Java to use it in its keystore.

Create a keystore

This is the place where the application usually gets its keys from. The keytool is able to read certificate files but does not understand private key files which you need to use y...

Speed up RSpec by deferring garbage collection

Update: This trick probably isn't very useful anymore in Ruby 2.x. The Ruby GC has improved a lot over the years.


Joe Van Dyk discovered that running the Ruby garbage collector only every X seconds can speed up your tests. I found that deferring garbage collection would speed up my RSpec examples by about 15%, but it probably depends on the nature of your tests. I also tried applying it to Cucumber f...