Opinionated Programmer - Jo Liss's musings on enlightened software development.

Capybara (and Selenium) with RSpec & Rails 3: quick tutorial

Here is how to set up Capybara with RSpec 2 and Ruby on Rails 3. Further down I’ll also show you how to drive Selenium through Capybara. The only assumption is that you have a bare-bones Rails 3 application set up.

First, add Capybara to your Gemfile:

1
2
3
4
group :development, :test do
  gem 'rspec-rails'
  gem 'capybara'
end

Run bundle install (and if you have not installed RSpec, also run rails generate rspec:install to set up your spec directory).

In spec/spec_helper.rb, add two require calls for Capybara near the top:

1
2
3
4
5
6
7
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'

# Add this to load Capybara integration:
require 'capybara/rspec'
require 'capybara/rails'

You’re all set! Capybara’s DSL will be available in all RSpec examples in the spec/requests and spec/integration directory. So, for example, in spec/integration/home_spec.rb you might write:

1
2
3
4
5
6
7
8
require 'spec_helper'

describe 'home page' do
  it 'welcomes the user' do
    visit '/'
    page.should have_content('Welcome')
  end
end

Run rake spec to run it.

And now with Selenium!

To run any example or example group through Selenium, just set :js => true:

1
2
3
4
5
6
7
8
9
10
describe 'blog post page' do
  it 'lets the user post a comment', :js => true do
    visit blog_post_path(blog_posts(:first_post).id)
    fill_in 'Author', :with => 'J. Random Hacker'
    fill_in 'Comment', :with => 'Awesome post!'
    click_on 'Submit'  # this be an Ajax button -- requires Selenium
    page.should have_content('has been submitted')
    page.should have_content('Awesome post!')
  end
end

If you run rake spec now, a Firefox should automatically fire up and run your test with Selenium.

You could make Capybara run all your tests in Selenium by setting Capybara.default_driver = :selenium, but I don’t recommend doing this: You can transparently switch between using Rack::Test (the default driver) and Selenium (the JavaScript driver) by setting the :js attribute, since both are driven through the exact same Capybara DSL, and your tests will run much faster if you use Selenium only for those tests that actually require JavaScript. The only difference (in theory) is that Rack::Test won’t run any JavaScript.

Update: You will also need DatabaseCleaner, since transactional fixtures do not work with Selenium. Add the database_cleaner gem to the :test group of your Gemfile and put the following code into spec/support/database_cleaner.rb:

1
2
3
4
5
6
7
8
9
10
11
DatabaseCleaner.strategy = :truncation

RSpec.configure do |config|
  config.use_transactional_fixtures = false
  config.before :each do
    DatabaseCleaner.start
  end
  config.after :each do
    DatabaseCleaner.clean
  end
end

See the comments at the bottom for a longer discussion.

What’s next?

If you haven’t done so, I recommend that you read the Capybara README (especially the section titled “The DSL”) to familiarize yourself with Capybara. It might seem a bit daunting at first, but reading it will help you get started so much faster.