From b874b493367f1d7e7028583d3cb768f6d05c98fe Mon Sep 17 00:00:00 2001 From: Reinier Balt Date: Fri, 27 Jan 2012 11:23:36 +0100 Subject: [PATCH] update cucumber config for capybara --- Gemfile | 7 +- Gemfile.lock | 29 ++- config/cucumber.yml | 6 +- config/environments/cucumber.rb | 3 +- features/step_definitions/web_steps.rb | 310 ++++++++++--------------- features/support/env.rb | 17 +- features/support/paths.rb | 14 +- 7 files changed, 167 insertions(+), 219 deletions(-) diff --git a/Gemfile b/Gemfile index 92d8ee9f..e352d66e 100644 --- a/Gemfile +++ b/Gemfile @@ -28,7 +28,7 @@ end group :development do if RUBY_VERSION.to_f >= 1.9 - gem "ruby-debug19" + gem "ruby-debug19" gem "mongrel", "1.2.0.pre2" else gem "ruby-debug" @@ -46,8 +46,7 @@ group :test do gem "rspec-rails", "~>1.3.3" gem "thoughtbot-factory_girl" gem 'memory_test_fix', '~>0.1.3' - gem "selenium-client" - gem "webrat", ">=0.7.0" + gem "capybara", ">=0.3.5" gem "database_cleaner", ">=0.5.0" - gem "cucumber-rails", "~>0.3.0" + gem "cucumber-rails", "~>0.3.2" end diff --git a/Gemfile.lock b/Gemfile.lock index 27b98074..23bbbfc4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,16 @@ GEM acts_as_list (0.1.4) bcrypt-ruby (2.1.4) builder (3.0.0) + capybara (1.1.2) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (~> 2.0) + xpath (~> 0.1.4) cgi_multipart_eof_fix (2.5.0) + childprocess (0.3.0) + ffi (~> 1.0.6) columnize (0.3.4) cucumber (1.0.2) builder (>= 2.1.2) @@ -32,6 +41,7 @@ GEM database_cleaner (0.6.7) diff-lcs (1.1.2) fastthread (1.0.7) + ffi (1.0.11) flexmock (0.9.0) gem_plugin (0.2.3) gherkin (2.4.11) @@ -59,6 +69,7 @@ GEM daemons (>= 1.0.3) fastthread (>= 1.0.1) gem_plugin (>= 0.2.3) + multi_json (1.0.4) mysql (2.8.1) nokogiri (1.4.7) polyglot (0.3.2) @@ -90,9 +101,14 @@ GEM actionpack (~> 2.3.0) activerecord (~> 2.3.0) activesupport (~> 2.3.0) + rubyzip (0.9.5) sanitize (1.2.1) nokogiri (~> 1.4.1) - selenium-client (1.2.18) + selenium-webdriver (2.17.0) + childprocess (>= 0.2.5) + ffi (~> 1.0.9) + multi_json (~> 1.0.4) + rubyzip soap4r (1.5.8) httpclient (>= 2.1.1) sqlite3 (1.3.4) @@ -103,11 +119,9 @@ GEM treetop (1.4.10) polyglot polyglot (>= 0.3.1) - webrat (0.7.3) - nokogiri (>= 1.2.0) - rack (>= 1.0) - rack-test (>= 0.5.3) will_paginate (2.3.16) + xpath (0.1.4) + nokogiri (~> 1.3) yard (0.7.3) PLATFORMS @@ -119,7 +133,8 @@ DEPENDENCIES aasm (~> 2.2.0) acts_as_list (~> 0.1.4) bcrypt-ruby (~> 2.1.4) - cucumber-rails (~> 0.3.0) + capybara (>= 0.3.5) + cucumber-rails (~> 0.3.2) database_cleaner (>= 0.5.0) flexmock has_many_polymorphs (~> 2.13) @@ -140,11 +155,9 @@ DEPENDENCIES rubycas-client (~> 2.2.1) rubyjedi-actionwebservice sanitize (~> 1.2.1) - selenium-client soap4r (~> 1.5.8) sqlite3 test-unit (= 1.2.3) thoughtbot-factory_girl - webrat (>= 0.7.0) will_paginate (~> 2.3.15) yard diff --git a/config/cucumber.yml b/config/cucumber.yml index 038cbe30..621a14ce 100644 --- a/config/cucumber.yml +++ b/config/cucumber.yml @@ -3,8 +3,6 @@ rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip" %> -default: <%= std_opts %> features --tags ~@selenium -selenium: <%= std_opts %> features --tags @selenium -selenium_wip: features --wip --tags @wip:10 --tags @selenium -wip: --wip --tags @wip:10 --tags ~@selenium features +default: <%= std_opts %> features +wip: --tags @wip:3 --wip features rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/config/environments/cucumber.rb b/config/environments/cucumber.rb index d2f604d6..31397036 100644 --- a/config/environments/cucumber.rb +++ b/config/environments/cucumber.rb @@ -24,5 +24,4 @@ config.action_mailer.delivery_method = :test # Unique cookies # Unique cookies and use cookies for session config.action_controller.session_store = :cookie_store -config.action_controller.session = { :key => 'TracksCucumber', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil } - +config.action_controller.session = { :key => 'TracksCucumber', :secret => SITE_CONFIG['salt'] * (30.0 / SITE_CONFIG['salt'].length).ceil } \ No newline at end of file diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index b7570961..0f0af8aa 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -9,8 +9,12 @@ require 'uri' require 'cgi' require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) -# Commonly used webrat steps -# http://github.com/brynary/webrat +module WithinHelpers + def with_scope(locator) + locator ? within(locator) { yield } : yield + end +end +World(WithinHelpers) Given /^(?:|I )am on (.+)$/ do |page_name| visit path_to(page_name) @@ -20,24 +24,28 @@ When /^(?:|I )go to (.+)$/ do |page_name| visit path_to(page_name) end -When /^(?:|I )press "([^"]*)"$/ do |button| - click_button(button) +When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| + with_scope(selector) do + click_button(button) + end end -When /^(?:|I )follow "([^"]*)"$/ do |link| - click_link(link) +When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| + with_scope(selector) do + click_link(link) + end end -When /^(?:|I )follow "([^"]*)" within "([^"]*)"$/ do |link, parent| - click_link_within(parent, link) +When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector| + with_scope(selector) do + fill_in(field, :with => value) + end end -When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value| - fill_in(field, :with => value) -end - -When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field| - fill_in(field, :with => value) +When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector| + with_scope(selector) do + fill_in(field, :with => value) + end end # Use this to fill in an entire form with data from a table. Example: @@ -51,209 +59,139 @@ end # TODO: Add support for checkbox, select og option # based on naming conventions. # -When /^(?:|I )fill in the following:$/ do |fields| - fields.rows_hash.each do |name, value| - When %{I fill in "#{name}" with "#{value}"} - end -end - -When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field| - select(value, :from => field) -end - -# Use this step in conjunction with Rail's datetime_select helper. For example: -# When I select "December 25, 2008 10:00" as the date and time -When /^(?:|I )select "([^"]*)" as the date and time$/ do |time| - select_datetime(time) -end - -# Use this step when using multiple datetime_select helpers on a page or -# you want to specify which datetime to select. Given the following view: -# <%= f.label :preferred %>
-# <%= f.datetime_select :preferred %> -# <%= f.label :alternative %>
-# <%= f.datetime_select :alternative %> -# The following steps would fill out the form: -# When I select "November 23, 2004 11:20" as the "Preferred" date and time -# And I select "November 25, 2004 10:30" as the "Alternative" date and time -When /^(?:|I )select "([^"]*)" as the "([^"]*)" date and time$/ do |datetime, datetime_label| - select_datetime(datetime, :from => datetime_label) -end - -# Use this step in conjunction with Rail's time_select helper. For example: -# When I select "2:20PM" as the time -# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat -# will convert the 2:20PM to 14:20 and then select it. -When /^(?:|I )select "([^"]*)" as the time$/ do |time| - select_time(time) -end - -# Use this step when using multiple time_select helpers on a page or you want to -# specify the name of the time on the form. For example: -# When I select "7:30AM" as the "Gym" time -When /^(?:|I )select "([^"]*)" as the "([^"]*)" time$/ do |time, time_label| - select_time(time, :from => time_label) -end - -# Use this step in conjunction with Rail's date_select helper. For example: -# When I select "February 20, 1981" as the date -When /^(?:|I )select "([^"]*)" as the date$/ do |date| - select_date(date) -end - -# Use this step when using multiple date_select helpers on one page or -# you want to specify the name of the date on the form. For example: -# When I select "April 26, 1982" as the "Date of Birth" date -When /^(?:|I )select "([^"]*)" as the "([^"]*)" date$/ do |date, date_label| - select_date(date, :from => date_label) -end - -When /^(?:|I )check "([^"]*)"$/ do |field| - check(field) -end - -When /^(?:|I )uncheck "([^"]*)"$/ do |field| - uncheck(field) -end - -When /^(?:|I )choose "([^"]*)"$/ do |field| - choose(field) -end - -# Adds support for validates_attachment_content_type. Without the mime-type getting -# passed to attach_file() you will get a "Photo file is not one of the allowed file types." -# error message -When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field| - type = path.split(".")[1] - - case type - when "jpg" - type = "image/jpg" - when "jpeg" - type = "image/jpeg" - when "png" - type = "image/png" - when "gif" - type = "image/gif" - end - - attach_file(field, path, type) -end - -Then /^(?:|I )should see "([^"]*)"$/ do |text| - if response.respond_to? :should - response.should contain(text) - else - assert_contain text - end -end - -Then /^(?:|I )should see "([^"]*)" within "([^"]*)"$/ do |text, selector| - within(selector) do |content| - if content.respond_to? :should - content.should contain(text) - else - hc = Webrat::Matchers::HasContent.new(text) - assert hc.matches?(content), hc.failure_message +When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields| + with_scope(selector) do + fields.rows_hash.each do |name, value| + When %{I fill in "#{name}" with "#{value}"} end end end -Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp| +When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector| + with_scope(selector) do + select(value, :from => field) + end +end + +When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + check(field) + end +end + +When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + uncheck(field) + end +end + +When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + choose(field) + end +end + +When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector| + with_scope(selector) do + attach_file(field, path) + end +end + +Then /^(?:|I )should see JSON:$/ do |expected_json| + require 'json' + expected = JSON.pretty_generate(JSON.parse(expected_json)) + actual = JSON.pretty_generate(JSON.parse(response.body)) + expected.should == actual +end + +Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_content(text) + else + assert page.has_content?(text) + end + end +end + +Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector| regexp = Regexp.new(regexp) - if response.respond_to? :should - response.should contain(regexp) - else - assert_match(regexp, response_body) - end -end - -Then /^(?:|I )should see \/([^\/]*)\/ within "([^"]*)"$/ do |regexp, selector| - within(selector) do |content| - regexp = Regexp.new(regexp) - if content.respond_to? :should - content.should contain(regexp) + with_scope(selector) do + if page.respond_to? :should + page.should have_xpath('//*', :text => regexp) else - assert_match(regexp, content) + assert page.has_xpath?('//*', :text => regexp) end end end -Then /^(?:|I )should not see "([^"]*)"$/ do |text| - if response.respond_to? :should_not - response.should_not contain(text) - else - assert_not_contain(text) - end -end - -Then /^(?:|I )should not see "([^"]*)" within "([^"]*)"$/ do |text, selector| - within(selector) do |content| - if content.respond_to? :should_not - content.should_not contain(text) +Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_no_content(text) else - hc = Webrat::Matchers::HasContent.new(text) - assert !hc.matches?(content), hc.negative_failure_message + assert page.has_no_content?(text) end end end -Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp| +Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector| regexp = Regexp.new(regexp) - if response.respond_to? :should_not - response.should_not contain(regexp) - else - assert_not_contain(regexp) - end -end - -Then /^(?:|I )should not see \/([^\/]*)\/ within "([^"]*)"$/ do |regexp, selector| - within(selector) do |content| - regexp = Regexp.new(regexp) - if content.respond_to? :should_not - content.should_not contain(regexp) + with_scope(selector) do + if page.respond_to? :should + page.should have_no_xpath('//*', :text => regexp) else - assert_no_match(regexp, content) + assert page.has_no_xpath?('//*', :text => regexp) end end end -Then /^the "([^"]*)" field should contain "([^"]*)"$/ do |field, value| - field_value = field_labeled(field).value - if field_value.respond_to? :should - field_value.should =~ /#{value}/ - else - assert_match(/#{value}/, field_value) +Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value| + with_scope(selector) do + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value + if field_value.respond_to? :should + field_value.should =~ /#{value}/ + else + assert_match(/#{value}/, field_value) + end end end -Then /^the "([^"]*)" field should not contain "([^"]*)"$/ do |field, value| - field_value = field_labeled(field).value - if field_value.respond_to? :should_not - field_value.should_not =~ /#{value}/ - else - assert_no_match(/#{value}/, field_value) +Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value| + with_scope(selector) do + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value + if field_value.respond_to? :should_not + field_value.should_not =~ /#{value}/ + else + assert_no_match(/#{value}/, field_value) + end end end -Then /^the "([^"]*)" checkbox should be checked$/ do |label| - field = field_labeled(label) - if field.respond_to? :should - field.should be_checked - else - assert field.checked? +Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector| + with_scope(selector) do + field_checked = find_field(label)['checked'] + if field_checked.respond_to? :should + field_checked.should be_true + else + assert field_checked + end end end -Then /^the "([^"]*)" checkbox should not be checked$/ do |label| - field = field_labeled(label) - if field.respond_to? :should_not - field.should_not be_checked - else - assert !field.checked? +Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector| + with_scope(selector) do + field_checked = find_field(label)['checked'] + if field_checked.respond_to? :should + field_checked.should be_false + else + assert !field_checked + end end end - + Then /^(?:|I )should be on (.+)$/ do |page_name| current_path = URI.parse(current_url).path if current_path.respond_to? :should @@ -268,7 +206,7 @@ Then /^(?:|I )should have the following query string:$/ do |expected_pairs| actual_params = query ? CGI.parse(query) : {} expected_params = {} expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} - + if actual_params.respond_to? :should actual_params.should == expected_params else diff --git a/features/support/env.rb b/features/support/env.rb index 536cac89..2b87c0ad 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -13,14 +13,15 @@ require 'cucumber/rails/world' require 'cucumber/rails/active_record' require 'cucumber/web/tableish' -require 'webrat' -require 'webrat/core/matchers' - -Webrat.configure do |config| - config.mode = :rails - config.open_error_files = false # Set to true if you want error pages to pop up in the browser -end - +require 'capybara/rails' +require 'capybara/cucumber' +require 'capybara/session' +require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript +# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In +# order to ease the transition to Capybara we set the default here. If you'd +# prefer to use XPath just remove this line and adjust any selectors in your +# steps to use the XPath syntax. +Capybara.default_selector = :css # If you set this to false, any error raised from within your app will bubble # up to your step definition and out to cucumber unless you catch it somewhere diff --git a/features/support/paths.rb b/features/support/paths.rb index 1c06e6ee..16cf8de8 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -9,7 +9,7 @@ module NavigationHelpers options = @mobile_interface ? {:format => :m} : {} options = {:locale => @locale}.merge(options) if @locale @source_view = nil - + case page_name when /the home\s?page/ @@ -109,12 +109,12 @@ module NavigationHelpers tag_path($1, options) when /the change password page/ change_password_user_path @current_user - - # Add more mappings here. - # Here is an example that pulls values out of the Regexp: - # - # when /^(.*)'s profile page$/i - # user_profile_path(User.find_by_login($1)) + + # Add more mappings here. + # Here is an example that pulls values out of the Regexp: + # + # when /^(.*)'s profile page$/i + # user_profile_path(User.find_by_login($1)) else begin