casecumber-rails 1.0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +205 -0
- data/History.md +219 -0
- data/LICENSE +22 -0
- data/README.md +77 -0
- data/Rakefile +9 -0
- data/config/.gitignore +1 -0
- data/config/cucumber.yml +1 -0
- data/cucumber-rails.gemspec +46 -0
- data/dev_tasks/cucumber.rake +5 -0
- data/dev_tasks/rspec.rake +8 -0
- data/dev_tasks/yard.rake +0 -0
- data/dev_tasks/yard/default/layout/html/bubble_32x32.png +0 -0
- data/dev_tasks/yard/default/layout/html/footer.erb +5 -0
- data/dev_tasks/yard/default/layout/html/index.erb +1 -0
- data/dev_tasks/yard/default/layout/html/layout.erb +25 -0
- data/dev_tasks/yard/default/layout/html/logo.erb +1 -0
- data/dev_tasks/yard/default/layout/html/setup.rb +4 -0
- data/features/allow_rescue.feature +63 -0
- data/features/capybara_javascript_drivers.feature +87 -0
- data/features/database_cleaner.feature +44 -0
- data/features/emulate_javascript.feature +34 -0
- data/features/inspect_query_string.feature +37 -0
- data/features/install_cucumber_rails.feature +16 -0
- data/features/mongoid.feature +53 -0
- data/features/multiple_databases.feature +74 -0
- data/features/named_selectors.feature +33 -0
- data/features/no_database.feature +70 -0
- data/features/pseduo_class_selectors.feature +24 -0
- data/features/rerun_profile.feature +38 -0
- data/features/rest_api.feature +47 -0
- data/features/routing.feature +18 -0
- data/features/select_dates.feature +99 -0
- data/features/step_definitions/cucumber_rails_steps.rb +89 -0
- data/features/support/env.rb +37 -0
- data/features/test_unit.feature +43 -0
- data/lib/cucumber/rails.rb +23 -0
- data/lib/cucumber/rails/action_controller.rb +12 -0
- data/lib/cucumber/rails/application.rb +17 -0
- data/lib/cucumber/rails/capybara.rb +6 -0
- data/lib/cucumber/rails/capybara/javascript_emulation.rb +83 -0
- data/lib/cucumber/rails/capybara/select_dates_and_times.rb +50 -0
- data/lib/cucumber/rails/hooks.rb +4 -0
- data/lib/cucumber/rails/hooks/active_record.rb +21 -0
- data/lib/cucumber/rails/hooks/allow_rescue.rb +8 -0
- data/lib/cucumber/rails/hooks/database_cleaner.rb +13 -0
- data/lib/cucumber/rails/hooks/mail.rb +5 -0
- data/lib/cucumber/rails/rspec.rb +21 -0
- data/lib/cucumber/rails/world.rb +26 -0
- data/lib/cucumber/web/tableish.rb +118 -0
- data/lib/generators/cucumber/feature/USAGE +16 -0
- data/lib/generators/cucumber/feature/feature_generator.rb +28 -0
- data/lib/generators/cucumber/feature/named_arg.rb +19 -0
- data/lib/generators/cucumber/feature/templates/feature.erb +63 -0
- data/lib/generators/cucumber/feature/templates/steps.erb +14 -0
- data/lib/generators/cucumber/install/USAGE +15 -0
- data/lib/generators/cucumber/install/install_generator.rb +88 -0
- data/lib/generators/cucumber/install/templates/config/cucumber.yml.erb +8 -0
- data/lib/generators/cucumber/install/templates/script/cucumber +10 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps.rb.erb +192 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_cs.rb.erb +127 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_da.rb.erb +105 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_de.rb.erb +127 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_es.rb.erb +127 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_ja.rb.erb +140 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_ko.rb.erb +142 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_no.rb.erb +105 -0
- data/lib/generators/cucumber/install/templates/step_definitions/web_steps_pt-BR.rb.erb +132 -0
- data/lib/generators/cucumber/install/templates/support/_rails_each_run.rb.erb +36 -0
- data/lib/generators/cucumber/install/templates/support/_rails_prefork.rb.erb +1 -0
- data/lib/generators/cucumber/install/templates/support/capybara.rb +5 -0
- data/lib/generators/cucumber/install/templates/support/edit_warning.txt +5 -0
- data/lib/generators/cucumber/install/templates/support/paths.rb +33 -0
- data/lib/generators/cucumber/install/templates/support/rails.rb.erb +4 -0
- data/lib/generators/cucumber/install/templates/support/rails_spork.rb.erb +13 -0
- data/lib/generators/cucumber/install/templates/support/selectors.rb +39 -0
- data/lib/generators/cucumber/install/templates/support/web_steps_warning.txt +19 -0
- data/lib/generators/cucumber/install/templates/tasks/cucumber.rake.erb +60 -0
- data/spec/cucumber/web/tableish_spec.rb +239 -0
- data/spec/spec_helper.rb +3 -0
- metadata +514 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
begin
|
2
|
+
# Try to load it so we can assign @_result below if needed.
|
3
|
+
require 'test/unit/testresult'
|
4
|
+
rescue LoadError => ignore
|
5
|
+
end
|
6
|
+
|
7
|
+
module Cucumber #:nodoc:
|
8
|
+
module Rails #:nodoc:
|
9
|
+
class World < ActionController::IntegrationTest #:nodoc:
|
10
|
+
include Rack::Test::Methods
|
11
|
+
include ActiveSupport::Testing::SetupAndTeardown if ActiveSupport::Testing.const_defined?("SetupAndTeardown")
|
12
|
+
|
13
|
+
def initialize #:nodoc:
|
14
|
+
@_result = Test::Unit::TestResult.new if defined?(Test::Unit::TestResult)
|
15
|
+
end
|
16
|
+
|
17
|
+
if !defined?(ActiveRecord::Base)
|
18
|
+
def self.fixture_table_names; []; end # Workaround for projects that don't use ActiveRecord
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
World do
|
25
|
+
Cucumber::Rails::World.new
|
26
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Web
|
5
|
+
module Tableish
|
6
|
+
# This method returns an Array of Array of String, using CSS3 selectors.
|
7
|
+
# This is particularly handy when using Cucumber's Table#diff! method.
|
8
|
+
#
|
9
|
+
# The +row_selector+ argument must be a String, and picks out all the rows
|
10
|
+
# from the web page's DOM. If the number of cells in each row differs, it
|
11
|
+
# will be constrained by (or padded with) the number of cells in the first row
|
12
|
+
#
|
13
|
+
# The +column_selectors+ argument must be a String or a Proc, picking out
|
14
|
+
# cells from each row. If you pass a Proc, it will be yielded an instance
|
15
|
+
# of Nokogiri::HTML::Element.
|
16
|
+
#
|
17
|
+
# == Example with a table
|
18
|
+
#
|
19
|
+
# <table id="tools">
|
20
|
+
# <tr>
|
21
|
+
# <th>tool</th>
|
22
|
+
# <th>dude</th>
|
23
|
+
# </tr>
|
24
|
+
# <tr>
|
25
|
+
# <td>webrat</td>
|
26
|
+
# <td>bryan</td>
|
27
|
+
# </tr>
|
28
|
+
# <tr>
|
29
|
+
# <td>cucumber</td>
|
30
|
+
# <td>aslak</td>
|
31
|
+
# </tr>
|
32
|
+
# </table>
|
33
|
+
#
|
34
|
+
# t = tableish('table#tools tr', 'td,th')
|
35
|
+
#
|
36
|
+
# == Example with a dl
|
37
|
+
#
|
38
|
+
# <dl id="tools">
|
39
|
+
# <dt>webrat</dt>
|
40
|
+
# <dd>bryan</dd>
|
41
|
+
# <dt>cucumber</dt>
|
42
|
+
# <dd>aslak</dd>
|
43
|
+
# </dl>
|
44
|
+
#
|
45
|
+
# t = tableish('dl#tools dt', lambda{|dt| [dt, dt.next.next]})
|
46
|
+
#
|
47
|
+
def tableish(row_selector, column_selectors)
|
48
|
+
html = defined?(Capybara) ? body : response_body
|
49
|
+
_tableish(html, row_selector, column_selectors)
|
50
|
+
end
|
51
|
+
|
52
|
+
def _tableish(html, row_selector, column_selectors) #:nodoc
|
53
|
+
doc = Nokogiri::HTML(html)
|
54
|
+
spans = nil
|
55
|
+
max_cols = 0
|
56
|
+
|
57
|
+
# Parse the table.
|
58
|
+
rows = doc.search(row_selector).map do |row|
|
59
|
+
cells = case(column_selectors)
|
60
|
+
when String
|
61
|
+
row.search(column_selectors)
|
62
|
+
when Proc
|
63
|
+
column_selectors.call(row)
|
64
|
+
end
|
65
|
+
|
66
|
+
# TODO: max_cols should be sum of colspans
|
67
|
+
max_cols = [max_cols, cells.length].max
|
68
|
+
|
69
|
+
spans ||= Array.new(max_cols, 1)
|
70
|
+
|
71
|
+
cell_index = 0
|
72
|
+
|
73
|
+
cells = (0...spans.length).inject([]) do |array, n|
|
74
|
+
span = spans[n]
|
75
|
+
|
76
|
+
cell = if span > 1
|
77
|
+
row_span, col_span = 1, 1
|
78
|
+
nil
|
79
|
+
else
|
80
|
+
cell = cells[cell_index]
|
81
|
+
|
82
|
+
row_span, col_span = _parse_spans(cell)
|
83
|
+
|
84
|
+
if col_span > 1
|
85
|
+
((n + 1)...(n + col_span)).each do |m|
|
86
|
+
spans[m] = row_span + 1
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
cell_index +=1
|
91
|
+
cell
|
92
|
+
end
|
93
|
+
|
94
|
+
spans[n] = row_span > 1 ? row_span : ([span - 1, 1].max)
|
95
|
+
|
96
|
+
array << case cell
|
97
|
+
when String then cell.strip
|
98
|
+
when nil then ''
|
99
|
+
else cell.text.strip
|
100
|
+
end
|
101
|
+
|
102
|
+
array
|
103
|
+
end
|
104
|
+
|
105
|
+
cells
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def _parse_spans(cell)
|
110
|
+
cell.is_a?(Nokogiri::XML::Node) ?
|
111
|
+
[cell.attributes['rowspan'].to_s.to_i || 1, cell.attributes['colspan'].to_s.to_i || 1] :
|
112
|
+
[1, 1]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
World(Cucumber::Web::Tableish)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Description:
|
2
|
+
Generates a skeleton for a new feature. Both a simple .feature file and
|
3
|
+
a steps.rb file is generated. This generator should be used with moderation.
|
4
|
+
See http://github.com/aslakhellesoy/cucumber/wikis/feature-coupled-steps-antipattern
|
5
|
+
for details about the dangers involved.
|
6
|
+
|
7
|
+
This generator can take an optional list of attribute pairs similar to Rails'
|
8
|
+
built-in resource generator.
|
9
|
+
|
10
|
+
Examples (Rails 3):
|
11
|
+
`script/rails generate cucumber:feature post` # no attributes
|
12
|
+
`script/rails generate cucumber:feature post title:string body:text published:boolean`
|
13
|
+
|
14
|
+
Examples (Rails 2):
|
15
|
+
`script/generate feature post` # no attributes
|
16
|
+
`script/generate feature post title:string body:text published:boolean`
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'named_arg')
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
class FeatureGenerator < ::Rails::Generators::NamedBase
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
argument :fields, :optional => true, :type => :array, :banner => "[field:type, field:type]"
|
8
|
+
|
9
|
+
attr_reader :named_args
|
10
|
+
|
11
|
+
def parse_fields
|
12
|
+
@named_args = @fields.nil? ? [] : @fields.map { |arg| NamedArg.new(arg) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate
|
16
|
+
empty_directory 'features/step_definitions'
|
17
|
+
template 'feature.erb', "features/manage_#{plural_name}.feature"
|
18
|
+
template 'steps.erb', "features/step_definitions/#{singular_name}_steps.rb"
|
19
|
+
gsub_file 'features/support/paths.rb', /'\/'/mi do |match|
|
20
|
+
"#{match}\n when /the new #{singular_name} page/\n new_#{singular_name}_path\n"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.banner
|
25
|
+
"#{$0} cucumber:feature ModelName [field:type, field:type]"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class NamedArg
|
2
|
+
attr_reader :name
|
3
|
+
attr_reader :type
|
4
|
+
|
5
|
+
def initialize(s)
|
6
|
+
@name, @type = *s.split(':')
|
7
|
+
end
|
8
|
+
|
9
|
+
def value(n)
|
10
|
+
if @type == 'boolean'
|
11
|
+
(n % 2) == 0
|
12
|
+
elsif @type == 'integer'
|
13
|
+
n
|
14
|
+
else
|
15
|
+
"#{@name} #{n}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
Feature: Manage <%= plural_name %>
|
2
|
+
In order to [goal]
|
3
|
+
[stakeholder]
|
4
|
+
wants [behaviour]
|
5
|
+
|
6
|
+
Scenario: Register new <%= singular_name %>
|
7
|
+
Given I am on the new <%= singular_name %> page
|
8
|
+
<% keyword = 'When' -%>
|
9
|
+
<% named_args.each do |arg| -%>
|
10
|
+
<% if arg.type == 'boolean' -%>
|
11
|
+
<%= keyword %> I uncheck "<%= arg.name.humanize %>"
|
12
|
+
<% else -%>
|
13
|
+
<%= keyword %> I fill in "<%= arg.name.humanize %>" with "<%= arg.value(1) %>"
|
14
|
+
<% end -%>
|
15
|
+
<% keyword = 'And' -%>
|
16
|
+
<% end -%>
|
17
|
+
And I press "Create"
|
18
|
+
<% keyword = 'Then' -%>
|
19
|
+
<% named_args.each do |arg| -%>
|
20
|
+
<%= keyword %> I should see "<%= arg.value(1) %>"
|
21
|
+
<% keyword = 'And' -%>
|
22
|
+
<% end -%>
|
23
|
+
|
24
|
+
<% if IO.read('features/support/env.rb') =~ /capybara/n -%>
|
25
|
+
# Rails generates Delete links that use Javascript to pop up a confirmation
|
26
|
+
# dialog and then do a HTTP POST request (emulated DELETE request).
|
27
|
+
#
|
28
|
+
# Capybara must use Culerity/Celerity or Selenium2 (webdriver) when pages rely
|
29
|
+
# on Javascript events. Only Culerity/Celerity supports clicking on confirmation
|
30
|
+
# dialogs.
|
31
|
+
#
|
32
|
+
# Since Culerity/Celerity and Selenium2 has some overhead, Cucumber-Rails will
|
33
|
+
# detect the presence of Javascript behind Delete links and issue a DELETE request
|
34
|
+
# instead of a GET request.
|
35
|
+
#
|
36
|
+
# You can turn this emulation off by tagging your scenario with @no-js-emulation.
|
37
|
+
# Turning on browser testing with @selenium, @culerity, @celerity or @javascript
|
38
|
+
# will also turn off the emulation. (See the Capybara documentation for
|
39
|
+
# details about those tags). If any of the browser tags are present, Cucumber-Rails
|
40
|
+
# will also turn off transactions and clean the database with DatabaseCleaner
|
41
|
+
# after the scenario has finished. This is to prevent data from leaking into
|
42
|
+
# the next scenario.
|
43
|
+
#
|
44
|
+
# Another way to avoid Cucumber-Rails' javascript emulation without using any
|
45
|
+
# of the tags above is to modify your views to use <button> instead. You can
|
46
|
+
# see how in http://github.com/jnicklas/capybara/issues#issue/12
|
47
|
+
#
|
48
|
+
<% if options[:capybara] -%>
|
49
|
+
@<%= options[:capybara] %>
|
50
|
+
<% end -%>
|
51
|
+
<% end -%>
|
52
|
+
Scenario: Delete <%= singular_name %>
|
53
|
+
Given the following <%= plural_name %>:
|
54
|
+
|<%= named_args.map(&:name).join('|') %>|
|
55
|
+
<% (1..4).each do |n| -%>
|
56
|
+
|<%= named_args.map{|arg| arg.value(n)}.join('|') %>|
|
57
|
+
<% end -%>
|
58
|
+
When I delete the 3rd <%= singular_name %>
|
59
|
+
Then I should see the following <%= plural_name %>:
|
60
|
+
|<%= named_args.map{|arg| arg.name.humanize}.join('|') %>|
|
61
|
+
<% [1,2,4].each do |n| -%>
|
62
|
+
|<%= named_args.map{|arg| arg.value(n)}.join('|') %>|
|
63
|
+
<% end -%>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Given /^the following <%= plural_name %>:$/ do |<%= plural_name %>|
|
2
|
+
<%= class_name %>.create!(<%= plural_name %>.hashes)
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I delete the (\d+)(?:st|nd|rd|th) <%= singular_name %>$/ do |pos|
|
6
|
+
visit <%= plural_name %>_path
|
7
|
+
within("table tr:nth-child(#{pos.to_i+1})") do
|
8
|
+
click_link "Destroy"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Then /^I should see the following <%= plural_name %>:$/ do |expected_<%= plural_name %>_table|
|
13
|
+
expected_<%= plural_name %>_table.diff!(tableish('table tr', 'td,th'))
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Description:
|
2
|
+
Sets up Cucumber in your Rails project. After running this generator you will
|
3
|
+
get a new rake task called features.
|
4
|
+
|
5
|
+
This also generates the necessary files in the features directory.
|
6
|
+
|
7
|
+
Also see the cucumber:feature generator.
|
8
|
+
|
9
|
+
Examples:
|
10
|
+
`rails generate cucumber:install`
|
11
|
+
|
12
|
+
`rails generate cucumber:install --help`
|
13
|
+
|
14
|
+
You can also provide a language argument for localized web_steps:
|
15
|
+
`rails generate cucumber:install de`
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
class InstallGenerator < ::Rails::Generators::Base
|
5
|
+
source_root File.expand_path("../templates", __FILE__)
|
6
|
+
|
7
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
8
|
+
|
9
|
+
argument :language, :type => :string, :banner => "LANG", :optional => true
|
10
|
+
|
11
|
+
class_option :rspec, :type => :boolean, :desc => "Use RSpec"
|
12
|
+
class_option :testunit, :type => :boolean, :desc => "Use Test::Unit"
|
13
|
+
class_option :spork, :type => :boolean, :desc => "Use Spork"
|
14
|
+
class_option :skip_database, :type => :boolean, :desc => "Skip modification of database.yml", :aliases => '-D', :default => false
|
15
|
+
|
16
|
+
attr_reader :framework
|
17
|
+
|
18
|
+
def create_templates
|
19
|
+
template 'config/cucumber.yml.erb', 'config/cucumber.yml'
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_scripts
|
23
|
+
copy_file 'script/cucumber', 'script/cucumber'
|
24
|
+
chmod 'script/cucumber', 0755
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_step_definitions
|
28
|
+
empty_directory 'features/step_definitions'
|
29
|
+
|
30
|
+
template "step_definitions/web_steps.rb.erb", 'features/step_definitions/web_steps.rb'
|
31
|
+
if language
|
32
|
+
template "step_definitions/web_steps_#{language}.rb.erb", "features/step_definitions/web_steps_#{language}.rb"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_feature_support
|
37
|
+
empty_directory 'features/support'
|
38
|
+
copy_file 'support/paths.rb', 'features/support/paths.rb'
|
39
|
+
copy_file 'support/selectors.rb', 'features/support/selectors.rb'
|
40
|
+
|
41
|
+
if spork?
|
42
|
+
template 'support/rails_spork.rb.erb', 'features/support/env.rb'
|
43
|
+
else
|
44
|
+
template 'support/rails.rb.erb', 'features/support/env.rb'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_tasks
|
49
|
+
empty_directory 'lib/tasks'
|
50
|
+
template 'tasks/cucumber.rake.erb', 'lib/tasks/cucumber.rake'
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_database
|
54
|
+
return unless File.exist?('config/database.yml')
|
55
|
+
unless File.read('config/database.yml').include? 'cucumber:'
|
56
|
+
gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n"
|
57
|
+
gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test"
|
58
|
+
|
59
|
+
# Since gsub_file doesn't ask the user, just inform user that the file was overwritten.
|
60
|
+
puts " force config/database.yml"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def spork?
|
67
|
+
options[:spork]
|
68
|
+
end
|
69
|
+
|
70
|
+
def embed_file(source, indent='')
|
71
|
+
IO.read(File.join(self.class.source_root, source)).gsub(/^/, indent)
|
72
|
+
end
|
73
|
+
|
74
|
+
def embed_template(source, indent='')
|
75
|
+
template = File.join(self.class.source_root, source)
|
76
|
+
ERB.new(IO.read(template), nil, '-').result(binding).gsub(/^/, indent)
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def framework_from_options
|
82
|
+
return 'rspec-rails' if options[:rspec]
|
83
|
+
return 'testunit' if options[:testunit]
|
84
|
+
return 'rspec-rails'
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
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'] || 'pretty'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= spork? ? '--drb ' : '' %><%%= std_opts %> features
|
7
|
+
wip: <%= spork? ? '--drb ' : '' %>--tags @wip:3 --wip features
|
8
|
+
rerun: <%= spork? ? '--drb ' : '' %><%%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
|
4
|
+
if vendored_cucumber_bin
|
5
|
+
load File.expand_path(vendored_cucumber_bin)
|
6
|
+
else
|
7
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
8
|
+
require 'cucumber'
|
9
|
+
load Cucumber::BINARY
|
10
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
<%= embed_file('support/web_steps_warning.txt') %>
|
2
|
+
|
3
|
+
require 'uri'
|
4
|
+
require 'cgi'
|
5
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
|
7
|
+
|
8
|
+
module WithinHelpers
|
9
|
+
def with_scope(locator)
|
10
|
+
locator ? within(*selector_for(locator)) { yield } : yield
|
11
|
+
end
|
12
|
+
end
|
13
|
+
World(WithinHelpers)
|
14
|
+
|
15
|
+
# Single-line step scoper
|
16
|
+
When /^(.*) within (.*[^:])$/ do |step, parent|
|
17
|
+
with_scope(parent) { When step }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Multi-line step scoper
|
21
|
+
When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
|
22
|
+
with_scope(parent) { When "#{step}:", table_or_string }
|
23
|
+
end
|
24
|
+
|
25
|
+
Given /^(?:|I )am on (.+)$/ do |page_name|
|
26
|
+
visit path_to(page_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
When /^(?:|I )go to (.+)$/ do |page_name|
|
30
|
+
visit path_to(page_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
When /^(?:|I )press "([^"]*)"$/ do |button|
|
34
|
+
click_button(button)
|
35
|
+
end
|
36
|
+
|
37
|
+
When /^(?:|I )follow "([^"]*)"$/ do |link|
|
38
|
+
click_link(link)
|
39
|
+
end
|
40
|
+
|
41
|
+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
42
|
+
fill_in(field, :with => value)
|
43
|
+
end
|
44
|
+
|
45
|
+
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
|
46
|
+
fill_in(field, :with => value)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Use this to fill in an entire form with data from a table. Example:
|
50
|
+
#
|
51
|
+
# When I fill in the following:
|
52
|
+
# | Account Number | 5002 |
|
53
|
+
# | Expiry date | 2009-11-01 |
|
54
|
+
# | Note | Nice guy |
|
55
|
+
# | Wants Email? | |
|
56
|
+
#
|
57
|
+
# TODO: Add support for checkbox, select og option
|
58
|
+
# based on naming conventions.
|
59
|
+
#
|
60
|
+
When /^(?:|I )fill in the following:$/ do |fields|
|
61
|
+
fields.rows_hash.each do |name, value|
|
62
|
+
When %{I fill in "#{name}" with "#{value}"}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
|
67
|
+
select(value, :from => field)
|
68
|
+
end
|
69
|
+
|
70
|
+
When /^(?:|I )check "([^"]*)"$/ do |field|
|
71
|
+
check(field)
|
72
|
+
end
|
73
|
+
|
74
|
+
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
|
75
|
+
uncheck(field)
|
76
|
+
end
|
77
|
+
|
78
|
+
When /^(?:|I )choose "([^"]*)"$/ do |field|
|
79
|
+
choose(field)
|
80
|
+
end
|
81
|
+
|
82
|
+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
|
83
|
+
attach_file(field, File.expand_path(path))
|
84
|
+
end
|
85
|
+
|
86
|
+
Then /^(?:|I )should see "([^"]*)"$/ do |text|
|
87
|
+
if page.respond_to? :should
|
88
|
+
page.should have_content(text)
|
89
|
+
else
|
90
|
+
assert page.has_content?(text)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
|
95
|
+
regexp = Regexp.new(regexp)
|
96
|
+
|
97
|
+
if page.respond_to? :should
|
98
|
+
page.should have_xpath('//*', :text => regexp)
|
99
|
+
else
|
100
|
+
assert page.has_xpath?('//*', :text => regexp)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
Then /^(?:|I )should not see "([^"]*)"$/ do |text|
|
105
|
+
if page.respond_to? :should
|
106
|
+
page.should have_no_content(text)
|
107
|
+
else
|
108
|
+
assert page.has_no_content?(text)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
|
113
|
+
regexp = Regexp.new(regexp)
|
114
|
+
|
115
|
+
if page.respond_to? :should
|
116
|
+
page.should have_no_xpath('//*', :text => regexp)
|
117
|
+
else
|
118
|
+
assert page.has_no_xpath?('//*', :text => regexp)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
|
123
|
+
with_scope(parent) do
|
124
|
+
field = find_field(field)
|
125
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
126
|
+
if field_value.respond_to? :should
|
127
|
+
field_value.should =~ /#{value}/
|
128
|
+
else
|
129
|
+
assert_match(/#{value}/, field_value)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
|
135
|
+
with_scope(parent) do
|
136
|
+
field = find_field(field)
|
137
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
138
|
+
if field_value.respond_to? :should_not
|
139
|
+
field_value.should_not =~ /#{value}/
|
140
|
+
else
|
141
|
+
assert_no_match(/#{value}/, field_value)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
|
147
|
+
with_scope(parent) do
|
148
|
+
field_checked = find_field(label)['checked']
|
149
|
+
if field_checked.respond_to? :should
|
150
|
+
field_checked.should be_true
|
151
|
+
else
|
152
|
+
assert field_checked
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
|
158
|
+
with_scope(parent) do
|
159
|
+
field_checked = find_field(label)['checked']
|
160
|
+
if field_checked.respond_to? :should
|
161
|
+
field_checked.should be_false
|
162
|
+
else
|
163
|
+
assert !field_checked
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
Then /^(?:|I )should be on (.+)$/ do |page_name|
|
169
|
+
current_path = URI.parse(current_url).path
|
170
|
+
if current_path.respond_to? :should
|
171
|
+
current_path.should == path_to(page_name)
|
172
|
+
else
|
173
|
+
assert_equal path_to(page_name), current_path
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
|
178
|
+
query = URI.parse(current_url).query
|
179
|
+
actual_params = query ? CGI.parse(query) : {}
|
180
|
+
expected_params = {}
|
181
|
+
expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
|
182
|
+
|
183
|
+
if actual_params.respond_to? :should
|
184
|
+
actual_params.should == expected_params
|
185
|
+
else
|
186
|
+
assert_equal expected_params, actual_params
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
Then /^show me the page$/ do
|
191
|
+
save_and_open_page
|
192
|
+
end
|