cucumber-rails 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/HACKING.rdoc +7 -17
  2. data/History.txt +30 -0
  3. data/README.rdoc +16 -10
  4. data/Rakefile +2 -2
  5. data/VERSION +1 -1
  6. data/cucumber-rails.gemspec +12 -10
  7. data/features/rails2.feature +51 -8
  8. data/features/rails3.feature +55 -14
  9. data/features/rerun_profile.feature +38 -0
  10. data/features/step_definitions/cucumber_rails_steps.rb +23 -0
  11. data/lib/cucumber/rails/capybara_javascript_emulation.rb +2 -2
  12. data/lib/cucumber/rails/rspec.rb +3 -5
  13. data/lib/cucumber/rails/test_unit.rb +4 -6
  14. data/lib/cucumber/rails/world.rb +1 -1
  15. data/lib/cucumber/web/tableish.rb +50 -9
  16. data/lib/generators/cucumber/skeleton/skeleton_base.rb +4 -4
  17. data/rvm.yml +2 -2
  18. data/spec/cucumber/web/tableish_spec.rb +36 -6
  19. data/templates/feature/feature.erb +10 -12
  20. data/templates/feature/steps.erb +1 -1
  21. data/templates/skeleton/config/cucumber.yml.erb +4 -3
  22. data/templates/skeleton/environments/cucumber.rb.erb +1 -1
  23. data/templates/skeleton/step_definitions/capybara_steps.rb.erb +40 -23
  24. data/templates/skeleton/step_definitions/web_steps_de.rb.erb +33 -33
  25. data/templates/skeleton/step_definitions/web_steps_ja.rb.erb +139 -0
  26. data/templates/skeleton/step_definitions/web_steps_ko.rb.erb +141 -0
  27. data/templates/skeleton/step_definitions/webrat_steps.rb.erb +36 -28
  28. data/templates/skeleton/support/{_rails_each_run.rb → _rails_each_run.rb.erb} +2 -1
  29. data/templates/skeleton/support/_rails_prefork.rb.erb +2 -0
  30. data/templates/skeleton/support/paths.rb +10 -4
  31. data/templates/skeleton/support/rails.rb.erb +1 -1
  32. data/templates/skeleton/support/rails_spork.rb.erb +1 -1
  33. data/templates/skeleton/tasks/cucumber.rake.erb +6 -0
  34. metadata +11 -9
  35. data/generators/cucumber/templates/step_definitions/web_steps_ja.rb.erb +0 -136
@@ -57,14 +57,14 @@ class Capybara::Driver::RackTest::Node
57
57
  include Cucumber::Rails::CapybaraJavascriptEmulation
58
58
  end
59
59
 
60
- Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
60
+ Before('~@no-js-emulation') do
61
61
  # Enable javascript emulation
62
62
  Capybara::Driver::RackTest::Node.class_eval do
63
63
  alias_method :click, :click_with_javascript_emulation
64
64
  end
65
65
  end
66
66
 
67
- Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
67
+ Before('@no-js-emulation') do
68
68
  # Disable javascript emulation
69
69
  Capybara::Driver::RackTest::Node.class_eval do
70
70
  alias_method :click, :click_without_javascript_emulation
@@ -1,13 +1,11 @@
1
1
  require 'cucumber/rails/world'
2
2
 
3
3
  begin
4
- require 'rspec/expectations'
5
- require 'rspec/rails'
4
+ require 'rspec/rails/matchers'
6
5
 
7
6
  [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
8
7
  klass.class_eval do
9
8
  include Rspec::Matchers
10
- include Rspec::Rails::Matchers
11
9
  end
12
10
  end
13
11
  rescue LoadError => try_rspec_1
@@ -17,7 +15,7 @@ rescue LoadError => try_rspec_1
17
15
  [Cucumber::Rails::World, ActionController::Integration::Session].each do |klass|
18
16
  klass.class_eval do
19
17
  include Spec::Matchers
20
- include Spec::Rails::Matchers
18
+ include Spec::Rails::Matchers if defined?(Spec::Rails::Matchers)
21
19
  end
22
20
  end
23
- end
21
+ end
@@ -1,9 +1,7 @@
1
+ # This is fishy. Try to get rid of it....
1
2
  begin
2
3
  require 'test/unit/testresult'
3
- rescue LoadError => e
4
- e.message << "\nYou must gem install test-unit. For more info see https://rspec.lighthouseapp.com/projects/16211/tickets/292"
5
- e.message << "\nAlso make sure you have rack 1.0.0 or higher."
6
- raise e
4
+ # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
5
+ Test::Unit.run = true if Test::Unit.respond_to?(:run=)
6
+ rescue LoadError => ignore
7
7
  end
8
- # So that Test::Unit doesn't launch at the end - makes it think it has already been run.
9
- Test::Unit.run = true if Test::Unit.respond_to?(:run=)
@@ -37,7 +37,7 @@ module Cucumber #:nodoc:
37
37
  class World < ActionController::IntegrationTest
38
38
  include ActiveSupport::Testing::SetupAndTeardown if ActiveSupport::Testing.const_defined?("SetupAndTeardown")
39
39
  def initialize #:nodoc:
40
- @_result = Test::Unit::TestResult.new
40
+ @_result = Test::Unit::TestResult.new if defined?(Test::Unit::TestResult)
41
41
  end
42
42
  end
43
43
  end
@@ -3,7 +3,7 @@ require 'nokogiri'
3
3
  module Cucumber
4
4
  module Web
5
5
  module Tableish
6
- # This method returns an Array of Array of String, using CSS3 selectors.
6
+ # This method returns an Array of Array of String, using CSS3 selectors.
7
7
  # This is particularly handy when using Cucumber's Table#diff! method.
8
8
  #
9
9
  # The +row_selector+ argument must be a String, and picks out all the rows
@@ -51,27 +51,68 @@ module Cucumber
51
51
 
52
52
  def _tableish(html, row_selector, column_selectors) #:nodoc
53
53
  doc = Nokogiri::HTML(html)
54
- column_count = nil
55
- doc.search(row_selector).map do |row|
54
+ spans = nil
55
+ max_cols = 0
56
+
57
+ # Parse the table.
58
+ rows = doc.search(row_selector).map do |row|
56
59
  cells = case(column_selectors)
57
60
  when String
58
61
  row.search(column_selectors)
59
62
  when Proc
60
63
  column_selectors.call(row)
61
64
  end
62
- column_count ||= cells.length
63
- (0...column_count).map do |n|
64
- cell = cells[n]
65
- case(cell)
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
66
97
  when String then cell.strip
67
98
  when nil then ''
68
99
  else cell.text.strip
69
100
  end
101
+
102
+ array
70
103
  end
104
+
105
+ cells
71
106
  end
72
107
  end
73
- 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
74
115
  end
75
116
  end
76
117
 
77
- World(Cucumber::Web::Tableish)
118
+ World(Cucumber::Web::Tableish)
@@ -32,9 +32,9 @@ module Cucumber
32
32
  unless rails2
33
33
  puts "Update Rails 3 Gemfile for cucumber"
34
34
  gsub_file 'Gemfile', /('|")gem/, "\1\ngem"
35
- add_gem('database_cleaner', '>=0.5.0') unless has_plugin? 'database_cleaner'
35
+ add_gem('database_cleaner', '>=0.5.2') unless has_plugin? 'database_cleaner'
36
36
  if driver == :capybara
37
- add_gem('capybara', '>=0.3.0')
37
+ add_gem('capybara', '>=0.3.7')
38
38
  else
39
39
  add_gem('webrat', '>=0.7.0') unless has_plugin? 'webrat'
40
40
  end
@@ -107,8 +107,8 @@ module Cucumber
107
107
 
108
108
  def create_database(m = self, rails2 = false)
109
109
  unless File.read('config/database.yml').include? 'cucumber:'
110
- m.gsub_file 'config/database.yml', /^test:.*\n/, "test: &TEST\n"
111
- m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *TEST"
110
+ m.gsub_file 'config/database.yml', /^test:.*\n/, "test: &test\n"
111
+ m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *test"
112
112
 
113
113
  # Since gsub_file doesn't ask the user, just inform user that the file was overwritten.
114
114
  puts " force config/database.yml"
data/rvm.yml CHANGED
@@ -7,7 +7,7 @@ rails_gems:
7
7
  2.3.5:
8
8
  - rails -v 2.3.5
9
9
  3.0.0.beta:
10
- - i18n -v 0.3.0
10
+ - i18n -v 0.3.5
11
11
  - tzinfo -v 0.3.16
12
12
  - memcache-client -v 1.7.5
13
13
  - rack-mount -v 0.4.0
@@ -15,7 +15,7 @@ rails_gems:
15
15
  - text-format -v 1.0.0
16
16
  - erubis -v 2.6.5
17
17
  - mail -v 2.1.2
18
- - thor -v 0.13
18
+ - thor -v 0.13.4
19
19
  - bundler -v 0.9.7
20
20
  - builder -v 2.1.2
21
21
  - rails --pre
@@ -9,7 +9,7 @@ module Cucumber
9
9
  module Web
10
10
  describe Tableish do
11
11
  include Tableish
12
-
12
+
13
13
  unless RUBY_PLATFORM =~ /java/
14
14
  it "should convert a table" do
15
15
  html = <<-HTML
@@ -58,9 +58,9 @@ module Cucumber
58
58
  HTML
59
59
 
60
60
  _tableish(html, 'table#tools tr', 'td,th').should == [
61
- %w{tool dude},
62
- %w{webrat bryan},
63
- %w{cucumber aslak}
61
+ ['tool', 'dude',],
62
+ ['webrat', 'bryan'],
63
+ ['cucumber', 'aslak']
64
64
  ]
65
65
  end
66
66
 
@@ -88,6 +88,36 @@ module Cucumber
88
88
  ]
89
89
  end
90
90
 
91
+ it "should handle colspan and rowspan" do
92
+ html = <<-HTML
93
+ <table id="tools">
94
+ <tr>
95
+ <td rowspan="4">a</td>
96
+ <td>b</td>
97
+ <td>c</td>
98
+ <td>d</td>
99
+ </tr>
100
+ <tr>
101
+ <td colspan="3">e</td>
102
+ </tr>
103
+ <tr>
104
+ <td rowspan="2" colspan="2">f</td>
105
+ <td>g</td>
106
+ </tr>
107
+ <tr>
108
+ <td>h</td>
109
+ </tr>
110
+ </table>
111
+ HTML
112
+
113
+ _tableish(html, 'table#tools tr', 'td,th').should == [
114
+ ['a', 'b', 'c', 'd'],
115
+ ['', 'e', '', '' ],
116
+ ['', 'f', '', 'g' ],
117
+ ['', '', '', 'h' ],
118
+ ]
119
+ end
120
+
91
121
  it "should convert a dl" do
92
122
  html = <<-HTML
93
123
  <dl id="tools">
@@ -144,7 +174,7 @@ module Cucumber
144
174
  </form>
145
175
  HTML
146
176
 
147
- selectors = lambda do |form|
177
+ selectors = lambda do |form|
148
178
  [
149
179
  form.css('div input:nth-child(1)').first.attributes['value'],
150
180
  form.css('span').first.text.gsub(/\302\240/, ' ')
@@ -159,4 +189,4 @@ module Cucumber
159
189
  end
160
190
  end
161
191
  end
162
- end
192
+ end
@@ -25,28 +25,26 @@ Feature: Manage <%= plural_name %>
25
25
  # Rails generates Delete links that use Javascript to pop up a confirmation
26
26
  # dialog and then do a HTTP POST request (emulated DELETE request).
27
27
  #
28
- # Capybara must use Culerity or Selenium2 (webdriver) when pages rely on
29
- # Javascript events. Only Culerity supports confirmation dialogs.
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.
30
31
  #
31
- # Since Culerity and Selenium2 has some overhead, Cucumber-Rails will detect
32
- # the presence of Javascript behind Delete links and issue a DELETE request
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
33
34
  # instead of a GET request.
34
35
  #
35
- # You can turn off this emulation by tagging your scenario with @selenium,
36
- # @culerity, @celerity or @javascript. (See the Capybara documentation for
37
- # details about those tags). If any of these tags are present, Cucumber-Rails
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
38
40
  # will also turn off transactions and clean the database with DatabaseCleaner
39
41
  # after the scenario has finished. This is to prevent data from leaking into
40
42
  # the next scenario.
41
43
  #
42
- # Another way to avoid Cucumber-Rails'' javascript emulation without using any
44
+ # Another way to avoid Cucumber-Rails' javascript emulation without using any
43
45
  # of the tags above is to modify your views to use <button> instead. You can
44
46
  # see how in http://github.com/jnicklas/capybara/issues#issue/12
45
47
  #
46
- # TODO: Verify with Rob what this means: The rack driver will detect the
47
- # onclick javascript and emulate its behaviour without a real Javascript
48
- # interpreter.
49
- #
50
48
  <% if options[:capybara] -%>
51
49
  @<%= options[:capybara] %>
52
50
  <% end -%>
@@ -3,7 +3,7 @@ Given /^the following <%= plural_name %>:$/ do |<%= plural_name %>|
3
3
  end
4
4
 
5
5
  When /^I delete the (\d+)(?:st|nd|rd|th) <%= singular_name %>$/ do |pos|
6
- visit <%= plural_name %>_url
6
+ visit <%= plural_name %>_path
7
7
  within("table tr:nth-child(#{pos.to_i+1})") do
8
8
  click_link "Destroy"
9
9
  end
@@ -1,7 +1,8 @@
1
1
  <%%
2
2
  rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
3
- rerun_opts = rerun.to_s.strip.empty? ? "--format progress features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
4
- std_opts = "#{rerun_opts} --format rerun --out rerun.txt --strict --tags ~@wip"
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'] || 'progress'} --strict --tags ~@wip"
5
5
  %>
6
- default: <%= spork? ? '--drb ' : '' %><%%= std_opts %>
6
+ default: <%= spork? ? '--drb ' : '' %><%%= std_opts %> features
7
7
  wip: <%= spork? ? '--drb ' : '' %>--tags @wip:3 --wip features
8
+ rerun: <%= spork? ? '--drb ' : '' %><%%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
@@ -24,7 +24,7 @@ config.action_mailer.delivery_method = :test
24
24
  config.gem 'cucumber-rails', :lib => false, :version => '>=<%= version %>' unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber-rails'))
25
25
  config.gem 'database_cleaner', :lib => false, :version => '>=0.5.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/database_cleaner'))
26
26
  <% if driver == :capybara -%>
27
- config.gem 'capybara', :lib => false, :version => '>=0.3.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/capybara'))
27
+ config.gem 'capybara', :lib => false, :version => '>=0.3.5' unless File.directory?(File.join(Rails.root, 'vendor/plugins/capybara'))
28
28
  <% else -%>
29
29
  config.gem 'webrat', :lib => false, :version => '>=0.7.0' unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat'))
30
30
  <% end -%>
@@ -1,6 +1,7 @@
1
1
  <%= embed_file('support/edit_warning.txt') %>
2
2
 
3
3
  require 'uri'
4
+ require 'cgi'
4
5
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
5
6
 
6
7
  module WithinHelpers
@@ -91,9 +92,16 @@ When /^(?:|I )attach the file "([^\"]*)" to "([^\"]*)"(?: within "([^\"]*)")?$/
91
92
  end
92
93
  end
93
94
 
95
+ Then /^(?:|I )should see JSON:$/ do |expected_json|
96
+ require 'json'
97
+ expected = JSON.pretty_generate(JSON.parse(expected_json))
98
+ actual = JSON.pretty_generate(JSON.parse(response.body))
99
+ expected.should == actual
100
+ end
101
+
94
102
  Then /^(?:|I )should see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, selector|
95
103
  with_scope(selector) do
96
- if defined?(Spec::Rails::Matchers)
104
+ if page.respond_to? :should
97
105
  page.should have_content(text)
98
106
  else
99
107
  assert page.has_content?(text)
@@ -104,7 +112,7 @@ end
104
112
  Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^\"]*)")?$/ do |regexp, selector|
105
113
  regexp = Regexp.new(regexp)
106
114
  with_scope(selector) do
107
- if defined?(Spec::Rails::Matchers)
115
+ if page.respond_to? :should
108
116
  page.should have_xpath('//*', :text => regexp)
109
117
  else
110
118
  assert page.has_xpath?('//*', :text => regexp)
@@ -114,7 +122,7 @@ end
114
122
 
115
123
  Then /^(?:|I )should not see "([^\"]*)"(?: within "([^\"]*)")?$/ do |text, selector|
116
124
  with_scope(selector) do
117
- if defined?(Spec::Rails::Matchers)
125
+ if page.respond_to? :should
118
126
  page.should have_no_content(text)
119
127
  else
120
128
  assert page.has_no_content?(text)
@@ -125,7 +133,7 @@ end
125
133
  Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^\"]*)")?$/ do |regexp, selector|
126
134
  regexp = Regexp.new(regexp)
127
135
  with_scope(selector) do
128
- if defined?(Spec::Rails::Matchers)
136
+ if page.respond_to? :should
129
137
  page.should have_no_xpath('//*', :text => regexp)
130
138
  else
131
139
  assert page.has_no_xpath?('//*', :text => regexp)
@@ -135,57 +143,66 @@ end
135
143
 
136
144
  Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should contain "([^\"]*)"$/ do |field, selector, value|
137
145
  with_scope(selector) do
138
- if defined?(Spec::Rails::Matchers)
139
- find_field(field).value.should =~ /#{value}/
146
+ field = find_field(field)
147
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
148
+ if field_value.respond_to? :should
149
+ field_value.should =~ /#{value}/
140
150
  else
141
- assert_match(/#{value}/, field_labeled(field).value)
151
+ assert_match(/#{value}/, field_value)
142
152
  end
143
153
  end
144
154
  end
145
155
 
146
156
  Then /^the "([^\"]*)" field(?: within "([^\"]*)")? should not contain "([^\"]*)"$/ do |field, selector, value|
147
157
  with_scope(selector) do
148
- if defined?(Spec::Rails::Matchers)
149
- find_field(field).value.should_not =~ /#{value}/
158
+ field = find_field(field)
159
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
160
+ if field_value.respond_to? :should_not
161
+ field_value.should_not =~ /#{value}/
150
162
  else
151
- assert_no_match(/#{value}/, find_field(field).value)
163
+ assert_no_match(/#{value}/, field_value)
152
164
  end
153
165
  end
154
166
  end
155
167
 
156
168
  Then /^the "([^\"]*)" checkbox(?: within "([^\"]*)")? should be checked$/ do |label, selector|
157
169
  with_scope(selector) do
158
- if defined?(Spec::Rails::Matchers)
159
- find_field(label)['checked'].should == 'checked'
170
+ field_checked = find_field(label)['checked']
171
+ if field_checked.respond_to? :should
172
+ field_checked.should == 'checked'
160
173
  else
161
- assert_equal 'checked', field_labeled(label)['checked']
174
+ assert_equal 'checked', field_checked
162
175
  end
163
176
  end
164
177
  end
165
178
 
166
179
  Then /^the "([^\"]*)" checkbox(?: within "([^\"]*)")? should not be checked$/ do |label, selector|
167
180
  with_scope(selector) do
168
- if defined?(Spec::Rails::Matchers)
169
- find_field(label)['checked'].should_not == 'checked'
181
+ field_checked = find_field(label)['checked']
182
+ if field_checked.respond_to? :should_not
183
+ field_checked.should_not == 'checked'
170
184
  else
171
- assert_not_equal 'checked', field_labeled(label)['checked']
185
+ assert_not_equal 'checked', field_checked
172
186
  end
173
187
  end
174
188
  end
175
189
 
176
190
  Then /^(?:|I )should be on (.+)$/ do |page_name|
177
- if defined?(Spec::Rails::Matchers)
178
- URI.parse(current_url).path.should == path_to(page_name)
191
+ current_path = URI.parse(current_url).path
192
+ if current_path.respond_to? :should
193
+ current_path.should == path_to(page_name)
179
194
  else
180
- assert_equal path_to(page_name), URI.parse(current_url).path
195
+ assert_equal path_to(page_name), current_path
181
196
  end
182
197
  end
183
198
 
184
199
  Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
185
- actual_params = CGI.parse(URI.parse(current_url).query)
186
- expected_params = Hash[expected_pairs.rows_hash.map{|k,v| [k,[v]]}]
187
-
188
- if defined?(Spec::Rails::Matchers)
200
+ query = URI.parse(current_url).query
201
+ actual_params = query ? CGI.parse(query) : {}
202
+ expected_params = {}
203
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
204
+
205
+ if actual_params.respond_to? :should
189
206
  actual_params.should == expected_params
190
207
  else
191
208
  assert_equal expected_params, actual_params