Read more

Upgrading Cucumber and Capybara to the latest versions available for Rails 2

Ulrich Berkmueller
March 23, 2011Software engineer

Specify these gem versions in your Gemfile:

gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'
Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

With these versions set, selenium-webdriver will be at version 2.35.1. This is because all later versions depend on rubyzip 1+. More info Show archive.org snapshot .

After upgrading, delete capybara* from .gitignore. Capybara 1+ will write temp files to tmp/ and having that line in .gitignore will ignore e.g. the capybara emulation file below.

Problems and Solutions while upgrade capybara and cucumber

problems with capybara javascript emulation
Remove the following line from your features/support/env.rb file if present.

require 'cucumber/rails/capybara_javascript_emulation'

When you still have problems with teh capybara javascript emulation, please download capybara_javascript_emulation.rb to features/support/.


undefined method click' for class Capybara::Driver::RackTest::Node' (NameError)

Capybara::Driver::RackTest namespace moved to Capybara::RackTest


WARNING: Using 'Given/When/Then' in step definitions is deprecated, use 'step' to call other steps instead

Replace Given/When/Then/And/But methods within your step definition steps with the step-method.
When you have more than one delegation step in your step definition, you can use a syntax like this:

steps <<-CUCUMBER
  When I go to the admin users page
    And I fill in "name" with "#{name}"
    And I press "Save"
CUCUMBER

undefined method node for #Capybara::Node::Element:0xe8abd90 (NoMethodError)

The method node has been removed and some kind of replaced by native. Normally you don't need to call .native on a node (e.g. found by page.find(selector)).

# old
element.node.attribute("title").value
field.value

# new
element["title"] # attributes are directly accessible by `node[attribute_name]`
field["value"]

undefined method last_request for #Capybara::RackTest::Driver:0x7b1c8b0 (NoMethodError)

Maybe you have a step definition like this:

When(/^I go back$/) do
  # visit page.driver.last_request.env['HTTP_REFERER'] # old
  visit page.driver.request.env['HTTP_REFERER'] # new
  
  # or for javascript tests:
  page.execute_script('window.history.back()')
end

undefined method locate for #Capybara::Session (NoMethodError)

Use page.find instead of page.locate.


find_field (and other find methods) raise an exception if the element could not be found

Use has_field (and other has methods) if you like to check for a field to be present.
For example you can use steps like page.should_not have_field(label) to check that a field is not present.


Checking for Selenium with Capybara.current_session.driver.is_a? Capybara::Driver::Selenium

Now the selenium driver is located by Capybara::Driver::Selenium. A better-looking approach would be:
Capybara.current_driver == :selenium


page.response_headers['Content-Disposition']

should be page.response.headers['Content-Disposition']


undefined method process for #Capybara::RackTest::Driver:0x7a5edb0 (NoMethodError)

page.driver.process(:put, my_resource_path) => page.driver.browser.process(:put, my_resource_path)
When you like to follow redirects as well, look at browser's visit, submit and follow methods.


steps failing which contain page.body

page.body is now wrapped by a html document skeleton. Use page.text instead. (e.g. when you are testing correct JSON which is in fact not wrapped by a html sceleton)


An element can't be clicked although it is present in the response html

Only visible elements can be clicked. Maybe you need to resize your browser or really need to improve the layout for smaller screens (e.g. navigation items not be shown because of a too small window width).

Ulrich Berkmueller
March 23, 2011Software engineer
Posted by Ulrich Berkmueller to makandra dev (2011-03-23 14:09)