diff --git a/topics.feature b/1_topics.feature similarity index 72% rename from topics.feature rename to 1_topics.feature index 046bfd1..a1b436b 100644 --- a/topics.feature +++ b/1_topics.feature @@ -3,17 +3,17 @@ Feature: Topics people need to be able to create and edit them Scenario: Getting to the new topic page - When I go to topics - And I follow "New topic" + When I go to the topics page + And I follow "New Topic" Then I should see a "Create" button Scenario: Creating a topic - Given I go to topics - And I follow "New topic" + Given I go to the topics page + And I follow "New Topic" When I fill in "Title" with "Rails Fixtures" And I fill in "Description" with "Introduce how to add test data with fixtures." And I press "Create" Then I should see "Rails Fixtures" - And I should be on topics + And I should be on the topics page diff --git a/topics_list_and_details.feature b/2_topics_list_and_details.feature similarity index 65% rename from topics_list_and_details.feature rename to 2_topics_list_and_details.feature index 5832439..016957d 100644 --- a/topics_list_and_details.feature +++ b/2_topics_list_and_details.feature @@ -4,19 +4,21 @@ Feature: Topics List and Details and see details about them Background: Make sure we have a topic in the list - Given I go to topics - And I follow "New topic" + Given I go to the topics page + And I follow "New Topic" When I fill in "Title" with "Rails Fixtures" And I fill in "Description" with "Introduce how to add test data with fixtures." And I press "Create" - Scenario: Clicking on the topic title - When I follow "Rails Fixtures" + Scenario: Viewing a topic detail page + When I go to the topics page + And I follow "Rails Fixtures" Then I should see "Introduce how to add test data with fixtures." - And I should not see "add a topic" + And I should not see "New Topic" Scenario: Deleting a topic + When I go to the topics page When I follow "Delete" Then I should not see "Rails Fixtures" - And I should see "New topic" + And I should see "New Topic" diff --git a/votes.feature b/3_votes.feature similarity index 67% rename from votes.feature rename to 3_votes.feature index cd63817..b474e65 100644 --- a/votes.feature +++ b/3_votes.feature @@ -3,16 +3,17 @@ Feature: Votes people need to be able to vote for the ones they like Background: Make sure that we have a topic - Given I go to topics - And I follow "New topic" - When I fill in "Title" with "Rails Fixtures" + Given I go to the topics page + And I follow "New Topic" + And I fill in "Title" with "Rails Fixtures" And I fill in "Description" with "Introduce how to add test data with fixtures." And I press "Create" Scenario: viewing votes already cast - When I go to topics + When I go to the topics page Then I should see "0 votes" Scenario: voting on a topic - When I follow "+1" + When I go to the topics page + And I follow "+1" Then I should see "1 vote" \ No newline at end of file diff --git a/authenticated_votes.feature b/4_authenticated_votes.feature similarity index 95% rename from authenticated_votes.feature rename to 4_authenticated_votes.feature index 4190c84..5a0dcac 100644 --- a/authenticated_votes.feature +++ b/4_authenticated_votes.feature @@ -4,8 +4,8 @@ Feature: Votes with authentication and since we know who they are, they can take back their vote! Background: Make sure that we have a topic - Given I go to topics - And I follow "New topic" + Given I go to the topics page + And I follow "New Topic" When I fill in "Title" with "Rails Fixtures" And I fill in "Description" with "Introduce how to add test data with fixtures." And I press "Create" diff --git a/step_definitions/new_webrat_steps.rb b/step_definitions/new_webrat_steps.rb deleted file mode 100644 index 4f914f9..0000000 --- a/step_definitions/new_webrat_steps.rb +++ /dev/null @@ -1,10 +0,0 @@ -require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths")) - - -Then /^I should see a "([^\"]*)" button$/ do |button_name| - webrat.current_scope.find_button(button_name) -end - -Then /^I should see a "([^\"]*)" link$/ do |link_name| - webrat.current_scope.find_link(link_name) -end diff --git a/step_definitions/topic_steps.rb b/step_definitions/topic_steps.rb new file mode 100644 index 0000000..233cb36 --- /dev/null +++ b/step_definitions/topic_steps.rb @@ -0,0 +1,3 @@ +Then /^I should see a "([^\"]*)" button$/ do |button_name| + find_button(button_name) +end \ No newline at end of file diff --git a/step_definitions/web_steps.rb b/step_definitions/web_steps.rb index ad0a26a..0f0af8a 100644 --- a/step_definitions/web_steps.rb +++ b/step_definitions/web_steps.rb @@ -6,10 +6,15 @@ 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) @@ -19,24 +24,28 @@ visit path_to(page_name) end -When /^(?:|I )press "([^\"]*)"$/ do |button| - click_button(button) -end - -When /^(?:|I )follow "([^\"]*)"$/ do |link| - click_link(link) +When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| + with_scope(selector) do + click_button(button) + end end -When /^(?:|I )follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent| - click_link_within(parent, link) +When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| + with_scope(selector) do + click_link(link) + end end -When /^(?:|I )fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value| - fill_in(field, :with => value) +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 "([^\"]*)" 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: @@ -50,214 +59,161 @@ # 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}"} +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 -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) +When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector| + with_scope(selector) do + select(value, :from => field) + end end -When /^(?:|I )check "([^\"]*)"$/ do |field| - check(field) +When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + check(field) + end end -When /^(?:|I )uncheck "([^\"]*)"$/ do |field| - uncheck(field) +When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + uncheck(field) + end end -When /^(?:|I )choose "([^\"]*)"$/ do |field| - choose(field) +When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + choose(field) + end 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" +When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector| + with_scope(selector) do + attach_file(field, path) end - - attach_file(field, path, type) end -Then /^(?:|I )should see "([^\"]*)"$/ do |text| - if defined?(Spec::Rails::Matchers) - response.should contain(text) - else - assert_contain text - 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| - within(selector) do |content| - if defined?(Spec::Rails::Matchers) - content.should contain(text) +Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_content(text) else - hc = Webrat::Matchers::HasContent.new(text) - assert hc.matches?(content), hc.failure_message + assert page.has_content?(text) end end end -Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp| +Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector| regexp = Regexp.new(regexp) - if defined?(Spec::Rails::Matchers) - 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 defined?(Spec::Rails::Matchers) - 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 defined?(Spec::Rails::Matchers) - 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 defined?(Spec::Rails::Matchers) - 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 defined?(Spec::Rails::Matchers) - response.should_not contain(regexp) - else - assert_not_contain(regexp) + with_scope(selector) do + if page.respond_to? :should + page.should have_no_xpath('//*', :text => regexp) + else + assert page.has_no_xpath?('//*', :text => regexp) + end end end -Then /^(?:|I )should not see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector| - within(selector) do |content| - regexp = Regexp.new(regexp) - if defined?(Spec::Rails::Matchers) - content.should_not contain(regexp) +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_no_match(regexp, content) + assert_match(/#{value}/, field_value) end end end -Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value| - if defined?(Spec::Rails::Matchers) - field_labeled(field).value.should =~ /#{value}/ - else - assert_match(/#{value}/, field_labeled(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 "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value| - if defined?(Spec::Rails::Matchers) - field_labeled(field).value.should_not =~ /#{value}/ - else - assert_no_match(/#{value}/, field_labeled(field).value) +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 be checked$/ do |label| - if defined?(Spec::Rails::Matchers) - field_labeled(label).should be_checked - else - assert field_labeled(label).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 /^the "([^\"]*)" checkbox should not be checked$/ do |label| - if defined?(Spec::Rails::Matchers) - field_labeled(label).should_not be_checked + +Then /^(?:|I )should be on (.+)$/ do |page_name| + current_path = URI.parse(current_url).path + if current_path.respond_to? :should + current_path.should == path_to(page_name) else - assert !field_labeled(label).checked? + assert_equal path_to(page_name), current_path end end -Then /^(?:|I )should be on (.+)$/ do |page_name| - current_path = URI.parse(current_url).select(:path, :query).compact.join('?') - if defined?(Spec::Rails::Matchers) - current_path.should == path_to(page_name) +Then /^(?:|I )should have the following query string:$/ do |expected_pairs| + query = URI.parse(current_url).query + 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 - assert_equal path_to(page_name), current_path + assert_equal expected_params, actual_params end end Then /^show me the page$/ do save_and_open_page -end \ No newline at end of file +end diff --git a/support/env.rb b/support/env.rb index 417a434..bf06218 100644 --- a/support/env.rb +++ b/support/env.rb @@ -4,7 +4,7 @@ # instead of editing this one. Cucumber will automatically load all features/**/*.rb # files. -ENV["RAILS_ENV"] ||= "cucumber" +ENV["RAILS_ENV"] ||= "test" require File.expand_path(File.dirname(__FILE__) + '/../../config/environment') require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support @@ -13,14 +13,15 @@ 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 @@ -46,9 +47,13 @@ # subsequent scenarios. If you do this, we recommend you create a Before # block that will explicitly put your database in a known state. Cucumber::Rails::World.use_transactional_fixtures = true - # How to clean your database when transactions are turned off. See # http://github.com/bmabey/database_cleaner for more info. -require 'database_cleaner' -DatabaseCleaner.strategy = :truncation - +if defined?(ActiveRecord::Base) + begin + require 'database_cleaner' + DatabaseCleaner.strategy = :truncation + rescue LoadError => ignore_if_database_cleaner_not_present + end +end +$VERBOSE = nil diff --git a/support/paths.rb b/support/paths.rb index 981e3b2..06b3efb 100644 --- a/support/paths.rb +++ b/support/paths.rb @@ -7,10 +7,10 @@ module NavigationHelpers # def path_to(page_name) case page_name - + when /the home\s?page/ '/' - + # Add more mappings here. # Here is an example that pulls values out of the Regexp: # @@ -18,9 +18,14 @@ def path_to(page_name) # user_profile_path(User.find_by_login($1)) else - "/#{page_name}" - #raise "Can't find mapping from \"#{page_name}\" to a path.\n" + - # "Now, go and add a mapping in #{__FILE__}" + begin + page_name =~ /the (.*) page/ + path_components = $1.split(/\s+/) + self.send(path_components.push('path').join('_').to_sym) + rescue Object => e + raise "Can't find mapping from \"#{page_name}\" to a path.\n" + + "Now, go and add a mapping in #{__FILE__}" + end end end end