Like most Ruby on Rails developers, I write lots of test cases for my models and controllers. This lets me add new features quickly, without worrying about breakage: My test cases act as a safety net, warning me whenever existing code fails.

Sadly, it’s much harder to test client-side behavior. Sure, you know your controllers work, but what actually happens if a user clicks the Submit button? We need a better way to test the system end-to-end, including the actual JavaScript and web browsers.

This article shows how to combine Selenium, Selenium on Rails, and a custom patch to write client-side test cases in Ruby:

test.setup # Load fixtures
test.open :controller => 'customer',
          :action => 'list'
test.assert_title 'Customers'
test.click 'myLink', :wait => true
test.assert_title 'Customer: *'

These test cases actually run in your browser, loading pages and clicking links just as a user would. As the above example shows, you have full access to the Rails environment, including URL routing and configuration data.

Installing Selenium on Rails

First, install Jonas Bengtsson’s excellent Selenium on Rails, using the instructions at his site. Make sure you run his test cases. Once everything is installed, you can write test cases using a convenient table-like syntax:

|open|/selenium/setup|
|open|/customer/list|
|assertTitle|Customers|
|clickAndWait|myLink|
|assertTitle|Customer: *|

You also have the option of generating tables manually using regular rhtml templates.

However, both templating languages have limitations: The table-based language can’t access the Rails environment (or call url_for), and the rhtml-based language requires messing around with HTML. In the interest of simplicity, I’ve added a third templating language, inspired by rxml and rjs.

Patching to support native Ruby test cases

Once Selenium on Rails is installed, you can add support for native Ruby test cases by downloading my diff file and running patch from your Rails application directory (make sure you have a backup!):

my-system:~/src/myapp emk$ cat rselenese.diff | patch -p0

Obviously, you’ll need a copy of patch. It’s available on most Unix systems (including MacOS X), and can be installed on Windows using Cygwin.

To generate a sample test script, run:

my-system:~/src/myapp emk$ script/generate selenium login.rsel

Start a test server by typing:

my-system:~/src/myapp emk$ RAILS_ENV=test script/server

Now point your browser at http://localhost:3000/selenium/ and try running the new test case.

For documentation, see the file selenium_on_rails/rselenese.rb and the list of Selenium commands.

This is still very bleeding-edge software, so please report any problems or catastrophes below. This code is distributed under the same MIT license as Rails.

Update: For an alternate approach, see the Selenium Testing plugin for Rails. This offers particularly nice fixture integration.