Skip to content

Commit e35e342

Browse files
committed
Cucumber features work correctly now.
1 parent 2986092 commit e35e342

File tree

6 files changed

+169
-134
lines changed

6 files changed

+169
-134
lines changed

config/cucumber.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<%
22
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
33
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
4-
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
4+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
55
%>
66
default: <%= std_opts %> features
77
wip: --tags @wip:3 --wip features

features/step_definitions/web_steps.rb

Lines changed: 82 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
1-
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
2-
# It is recommended to regenerate this file in the future when you upgrade to a
3-
# newer version of cucumber-rails. Consider adding your own code to a new file
4-
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
5-
# files.
1+
# TL;DR: YOU SHOULD DELETE THIS FILE
2+
#
3+
# This file was generated by Cucumber-Rails and is only here to get you a head start
4+
# These step definitions are thin wrappers around the Capybara/Webrat API that lets you
5+
# visit pages, interact with widgets and make assertions about page content.
6+
#
7+
# If you use these step definitions as basis for your features you will quickly end up
8+
# with features that are:
9+
#
10+
# * Hard to maintain
11+
# * Verbose to read
12+
#
13+
# A much better approach is to write your own higher level step definitions, following
14+
# the advice in the following blog posts:
15+
#
16+
# * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
17+
# * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
18+
# * http://elabs.se/blog/15-you-re-cuking-it-wrong
19+
#
620

721

822
require 'uri'
923
require 'cgi'
1024
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
25+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
1126

1227
module WithinHelpers
1328
def with_scope(locator)
14-
locator ? within(locator) { yield } : yield
29+
locator ? within(*selector_for(locator)) { yield } : yield
1530
end
1631
end
1732
World(WithinHelpers)
1833

34+
# Single-line step scoper
35+
When /^(.*) within (.*[^:])$/ do |step, parent|
36+
with_scope(parent) { When step }
37+
end
38+
39+
# Multi-line step scoper
40+
When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
41+
with_scope(parent) { When "#{step}:", table_or_string }
42+
end
43+
1944
Given /^(?:|I )am on (.+)$/ do |page_name|
2045
visit path_to(page_name)
2146
end
@@ -24,28 +49,20 @@ def with_scope(locator)
2449
visit path_to(page_name)
2550
end
2651

27-
When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
28-
with_scope(selector) do
29-
click_button(button)
30-
end
52+
When /^(?:|I )press "([^"]*)"$/ do |button|
53+
click_button(button)
3154
end
3255

33-
When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
34-
with_scope(selector) do
35-
click_link(link)
36-
end
56+
When /^(?:|I )follow "([^"]*)"$/ do |link|
57+
click_link(link)
3758
end
3859

39-
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
40-
with_scope(selector) do
41-
fill_in(field, :with => value)
42-
end
60+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
61+
fill_in(field, :with => value)
4362
end
4463

45-
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
46-
with_scope(selector) do
47-
fill_in(field, :with => value)
48-
end
64+
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
65+
fill_in(field, :with => value)
4966
end
5067

5168
# Use this to fill in an entire form with data from a table. Example:
@@ -59,95 +76,70 @@ def with_scope(locator)
5976
# TODO: Add support for checkbox, select og option
6077
# based on naming conventions.
6178
#
62-
When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields|
63-
with_scope(selector) do
64-
fields.rows_hash.each do |name, value|
65-
When %{I fill in "#{name}" with "#{value}"}
66-
end
67-
end
68-
end
69-
70-
When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
71-
with_scope(selector) do
72-
select(value, :from => field)
79+
When /^(?:|I )fill in the following:$/ do |fields|
80+
fields.rows_hash.each do |name, value|
81+
When %{I fill in "#{name}" with "#{value}"}
7382
end
7483
end
7584

76-
When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
77-
with_scope(selector) do
78-
check(field)
79-
end
85+
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
86+
select(value, :from => field)
8087
end
8188

82-
When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
83-
with_scope(selector) do
84-
uncheck(field)
85-
end
89+
When /^(?:|I )check "([^"]*)"$/ do |field|
90+
check(field)
8691
end
8792

88-
When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
89-
with_scope(selector) do
90-
choose(field)
91-
end
93+
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
94+
uncheck(field)
9295
end
9396

94-
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
95-
with_scope(selector) do
96-
attach_file(field, path)
97-
end
97+
When /^(?:|I )choose "([^"]*)"$/ do |field|
98+
choose(field)
9899
end
99100

100-
Then /^(?:|I )should see JSON:$/ do |expected_json|
101-
require 'json'
102-
expected = JSON.pretty_generate(JSON.parse(expected_json))
103-
actual = JSON.pretty_generate(JSON.parse(response.body))
104-
expected.should == actual
101+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
102+
attach_file(field, File.expand_path(path))
105103
end
106104

107-
Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
108-
with_scope(selector) do
109-
if page.respond_to? :should
110-
page.should have_content(text)
111-
else
112-
assert page.has_content?(text)
113-
end
105+
Then /^(?:|I )should see "([^"]*)"$/ do |text|
106+
if page.respond_to? :should
107+
page.should have_content(text)
108+
else
109+
assert page.has_content?(text)
114110
end
115111
end
116112

117-
Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
113+
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
118114
regexp = Regexp.new(regexp)
119-
with_scope(selector) do
120-
if page.respond_to? :should
121-
page.should have_xpath('//*', :text => regexp)
122-
else
123-
assert page.has_xpath?('//*', :text => regexp)
124-
end
115+
116+
if page.respond_to? :should
117+
page.should have_xpath('//*', :text => regexp)
118+
else
119+
assert page.has_xpath?('//*', :text => regexp)
125120
end
126121
end
127122

128-
Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
129-
with_scope(selector) do
130-
if page.respond_to? :should
131-
page.should have_no_content(text)
132-
else
133-
assert page.has_no_content?(text)
134-
end
123+
Then /^(?:|I )should not see "([^"]*)"$/ do |text|
124+
if page.respond_to? :should
125+
page.should have_no_content(text)
126+
else
127+
assert page.has_no_content?(text)
135128
end
136129
end
137130

138-
Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
131+
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
139132
regexp = Regexp.new(regexp)
140-
with_scope(selector) do
141-
if page.respond_to? :should
142-
page.should have_no_xpath('//*', :text => regexp)
143-
else
144-
assert page.has_no_xpath?('//*', :text => regexp)
145-
end
133+
134+
if page.respond_to? :should
135+
page.should have_no_xpath('//*', :text => regexp)
136+
else
137+
assert page.has_no_xpath?('//*', :text => regexp)
146138
end
147139
end
148140

149-
Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
150-
with_scope(selector) do
141+
Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
142+
with_scope(parent) do
151143
field = find_field(field)
152144
field_value = (field.tag_name == 'textarea') ? field.text : field.value
153145
if field_value.respond_to? :should
@@ -158,8 +150,8 @@ def with_scope(locator)
158150
end
159151
end
160152

161-
Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value|
162-
with_scope(selector) do
153+
Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
154+
with_scope(parent) do
163155
field = find_field(field)
164156
field_value = (field.tag_name == 'textarea') ? field.text : field.value
165157
if field_value.respond_to? :should_not
@@ -170,8 +162,8 @@ def with_scope(locator)
170162
end
171163
end
172164

173-
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
174-
with_scope(selector) do
165+
Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
166+
with_scope(parent) do
175167
field_checked = find_field(label)['checked']
176168
if field_checked.respond_to? :should
177169
field_checked.should be_true
@@ -181,8 +173,8 @@ def with_scope(locator)
181173
end
182174
end
183175

184-
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
185-
with_scope(selector) do
176+
Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
177+
with_scope(parent) do
186178
field_checked = find_field(label)['checked']
187179
if field_checked.respond_to? :should
188180
field_checked.should be_false

features/support/env.rb

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,47 @@
44
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
55
# files.
66

7-
ENV["RAILS_ENV"] ||= "test"
8-
require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
7+
require 'cucumber/rails'
98

10-
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
11-
require 'cucumber/rails/rspec'
12-
require 'cucumber/rails/world'
13-
require 'cucumber/rails/active_record'
14-
require 'cucumber/web/tableish'
15-
16-
require 'capybara/rails'
17-
require 'capybara/cucumber'
18-
require 'capybara/session'
19-
require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
209
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
2110
# order to ease the transition to Capybara we set the default here. If you'd
2211
# prefer to use XPath just remove this line and adjust any selectors in your
2312
# steps to use the XPath syntax.
2413
Capybara.default_selector = :css
2514

26-
# If you set this to false, any error raised from within your app will bubble
27-
# up to your step definition and out to cucumber unless you catch it somewhere
28-
# on the way. You can make Rails rescue errors and render error pages on a
29-
# per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
15+
# By default, any exception happening in your Rails application will bubble up
16+
# to Cucumber so that your scenario will fail. This is a different from how
17+
# your application behaves in the production environment, where an error page will
18+
# be rendered instead.
19+
#
20+
# Sometimes we want to override this default behaviour and allow Rails to rescue
21+
# exceptions and display an error page (just like when the app is running in production).
22+
# Typical scenarios where you want to do this is when you test your error pages.
23+
# There are two ways to allow Rails to rescue exceptions:
24+
#
25+
# 1) Tag your scenario (or feature) with @allow-rescue
26+
#
27+
# 2) Set the value below to true. Beware that doing this globally is not
28+
# recommended as it will mask a lot of errors for you!
3029
#
31-
# If you set this to true, Rails will rescue all errors and render error
32-
# pages, more or less in the same way your application would behave in the
33-
# default production environment. It's not recommended to do this for all
34-
# of your scenarios, as this makes it hard to discover errors in your application.
3530
ActionController::Base.allow_rescue = false
3631

37-
# If you set this to true, each scenario will run in a database transaction.
38-
# You can still turn off transactions on a per-scenario basis, simply tagging
39-
# a feature or scenario with the @no-txn tag. If you are using Capybara,
40-
# tagging with @culerity or @javascript will also turn transactions off.
32+
# Remove/comment out the lines below if your app doesn't have a database.
33+
# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
34+
begin
35+
DatabaseCleaner.strategy = :transaction
36+
rescue NameError
37+
raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
38+
end
39+
40+
# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
41+
# See the DatabaseCleaner documentation for details. Example:
4142
#
42-
# If you set this to false, transactions will be off for all scenarios,
43-
# regardless of whether you use @no-txn or not.
43+
# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
44+
# DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
45+
# end
46+
#
47+
# Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
48+
# DatabaseCleaner.strategy = :transaction
49+
# end
4450
#
45-
# Beware that turning transactions off will leave data in your database
46-
# after each scenario, which can lead to hard-to-debug failures in
47-
# subsequent scenarios. If you do this, we recommend you create a Before
48-
# block that will explicitly put your database in a known state.
49-
Cucumber::Rails::World.use_transactional_fixtures = true
50-
# How to clean your database when transactions are turned off. See
51-
# http://github.com/bmabey/database_cleaner for more info.
52-
if defined?(ActiveRecord::Base)
53-
begin
54-
require 'database_cleaner'
55-
DatabaseCleaner.strategy = :truncation
56-
rescue LoadError => ignore_if_database_cleaner_not_present
57-
end
58-
end

features/support/paths.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module NavigationHelpers
88
def path_to(page_name)
99
case page_name
1010

11-
when /the home\s?page/
11+
when /^the home\s?page$/
1212
'/'
1313

1414
# Add more mappings here.
@@ -19,10 +19,10 @@ def path_to(page_name)
1919

2020
else
2121
begin
22-
page_name =~ /the (.*) page/
22+
page_name =~ /^the (.*) page$/
2323
path_components = $1.split(/\s+/)
2424
self.send(path_components.push('path').join('_').to_sym)
25-
rescue Object => e
25+
rescue NoMethodError, ArgumentError
2626
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
2727
"Now, go and add a mapping in #{__FILE__}"
2828
end

0 commit comments

Comments
 (0)