Use Capybara-webkit in Rails RSpec

Dec 21, 2014

About Capybara-webkit

Capybara-webkit is a headless browser. It can execute javascript. (capybara can’t execute javascript.) If you want to do integration test you had better use capybara-webkit instead of capybara.

Prepare Gems

group :test do
  gem 'factory_girl_rails'
  gem 'capybara'
  gem 'capybara-webkit'   # add capybara-webkit
  gem 'database_cleaner'  # add database cleaner
end

You need to add database_cleaner. It makes database clean every test case.

Database clear vs Shared Connection

http://robots.thoughtbot.com/ said that…

When running your tests by default, Rails wraps each scenario in a database transaction. This means, at the end of each test, Rails will rollback any changes to the database that happened within that spec. Unfortunately, when we use a JavaScript driver, the test is run in another thread. This means it does not share a connection to the database.

There are 2 ways to use same data between capybara and capybara-webkit threads.

http://robots.thoughtbot.com/ recommended former (commit and delete data). If you want to know why ? You should read this article.

Change config

spec/rails_helper.rb

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require 'spec_helper'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!
Capybara.javascript_driver = :webkit # add this line.
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }  # comment in this line.

# Checks for pending migrations before tests are run.
# If you are not using ActiveRecord, you can remove this line.
ActiveRecord::Migration.maintain_test_schema!
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false # set false

Add Helper

Use capybara-webkit

  feature "new todo title is inputed" do
    scenario "new todo should create in html" , js:true do
      visit "/"
      ....
      ....
    end
  end

Ajax test

  feature "todo's all-completed checkbox is clicked" do
    scenario "all todos should be deleted in html", js: true do
      visit "/"
      click_button("delete button") # request delete to server using ajax
      wait_for_ajax
      expect().to be XXXX
    end
  end

Sample

I created integration test useing capybara-webkit.

kashiro/todomvc_on_rails_fork (feature/update branch)

git clone [email protected]:kashiro/todomvc_on_rails_fork.git
cd todomvc_on_rails_fork
git checkout feature/update
brew install qt
bundle install
rspec spec

Reference