cucumber 0.4.3 → 0.4.4

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.
Files changed (69) hide show
  1. data/History.txt +27 -0
  2. data/VERSION.yml +3 -2
  3. data/cucumber.gemspec +11 -5
  4. data/examples/watir/features/support/screenshots.rb +1 -2
  5. data/features/call_many_steps.feature +124 -0
  6. data/features/default_snippets.feature +2 -2
  7. data/features/expand.feature +13 -2
  8. data/features/language_help.feature +1 -1
  9. data/features/report_called_undefined_steps.feature +1 -1
  10. data/features/snippet.feature +2 -2
  11. data/features/support/env.rb +3 -5
  12. data/features/tag_logic.feature +32 -0
  13. data/features/wire_protocol.feature +7 -7
  14. data/lib/cucumber.rb +6 -0
  15. data/lib/cucumber/ast/background.rb +1 -1
  16. data/lib/cucumber/ast/comment.rb +1 -1
  17. data/lib/cucumber/ast/examples.rb +1 -1
  18. data/lib/cucumber/ast/feature.rb +1 -1
  19. data/lib/cucumber/ast/feature_element.rb +2 -3
  20. data/lib/cucumber/ast/features.rb +1 -1
  21. data/lib/cucumber/ast/outline_table.rb +17 -4
  22. data/lib/cucumber/ast/py_string.rb +3 -1
  23. data/lib/cucumber/ast/scenario.rb +3 -1
  24. data/lib/cucumber/ast/scenario_outline.rb +2 -2
  25. data/lib/cucumber/ast/step.rb +1 -1
  26. data/lib/cucumber/ast/step_collection.rb +1 -1
  27. data/lib/cucumber/ast/step_invocation.rb +2 -1
  28. data/lib/cucumber/ast/table.rb +3 -3
  29. data/lib/cucumber/ast/tags.rb +18 -11
  30. data/lib/cucumber/ast/tree_walker.rb +16 -0
  31. data/lib/cucumber/cli/main.rb +3 -2
  32. data/lib/cucumber/cli/options.rb +4 -6
  33. data/lib/cucumber/cli/profile_loader.rb +4 -0
  34. data/lib/cucumber/filter.rb +2 -2
  35. data/lib/cucumber/formatter/ansicolor.rb +8 -0
  36. data/lib/cucumber/formatter/pretty.rb +3 -4
  37. data/lib/cucumber/language_support/language_methods.rb +4 -3
  38. data/lib/cucumber/languages.yml +1 -1
  39. data/lib/cucumber/parser.rb +2 -0
  40. data/lib/cucumber/parser/common.rb +170 -0
  41. data/lib/cucumber/parser/common.tt +21 -0
  42. data/lib/cucumber/parser/feature.rb +7 -291
  43. data/lib/cucumber/parser/feature.tt +7 -43
  44. data/lib/cucumber/parser/i18n.tt +2 -0
  45. data/lib/cucumber/parser/natural_language.rb +9 -0
  46. data/lib/cucumber/parser/py_string.rb +276 -0
  47. data/lib/cucumber/parser/py_string.tt +45 -0
  48. data/lib/cucumber/parser/table.rb +5 -120
  49. data/lib/cucumber/parser/table.tt +2 -13
  50. data/lib/cucumber/platform.rb +3 -2
  51. data/lib/cucumber/rails/active_record.rb +2 -21
  52. data/lib/cucumber/rails/world.rb +2 -1
  53. data/lib/cucumber/rb_support/rb_hook.rb +2 -1
  54. data/lib/cucumber/rb_support/rb_language.rb +8 -6
  55. data/lib/cucumber/rb_support/rb_step_definition.rb +4 -0
  56. data/lib/cucumber/rb_support/rb_world.rb +16 -37
  57. data/lib/cucumber/step_mother.rb +86 -2
  58. data/lib/cucumber/wire_support/wire_language.rb +2 -2
  59. data/lib/cucumber/wire_support/wire_protocol.rb +1 -1
  60. data/rails_generators/cucumber/cucumber_generator.rb +3 -1
  61. data/rails_generators/cucumber/templates/cucumber.rake +4 -2
  62. data/rails_generators/cucumber/templates/webrat_steps.rb +28 -28
  63. data/spec/cucumber/ast/background_spec.rb +2 -1
  64. data/spec/cucumber/ast/scenario_spec.rb +3 -1
  65. data/spec/cucumber/formatter/console_spec.rb +1 -1
  66. data/spec/cucumber/rb_support/rb_step_definition_spec.rb +14 -5
  67. data/spec/cucumber/step_mother_spec.rb +1 -1
  68. data/spec/cucumber/world/pending_spec.rb +1 -1
  69. metadata +8 -3
@@ -1,12 +1,13 @@
1
1
  module Cucumber
2
2
  module Parser
3
- # TIP: When you hack on the grammar, just delete feature.rb in this directory.
3
+ # TIP: When you hack on the grammar, just delete table.rb in this directory.
4
4
  # Also make sure you have uninstalled all cucumber gems (don't forget xxx-cucumber
5
5
  # github gems).
6
6
  #
7
7
  # Treetop will then generate the parser in-memory. When you're happy, just generate
8
8
  # the rb file with tt feature.tt
9
9
  grammar Table
10
+ include Common
10
11
 
11
12
  rule table
12
13
  table_row+ {
@@ -54,18 +55,6 @@ module Cucumber
54
55
  (!('|' / eol) .)*
55
56
  end
56
57
 
57
- rule space
58
- [ \t]
59
- end
60
-
61
- rule eol
62
- "\n" / ("\r" "\n"?)
63
- end
64
-
65
- rule eof
66
- !.
67
- end
68
-
69
58
  end
70
59
  end
71
60
  end
@@ -11,8 +11,9 @@ module Cucumber
11
11
  BINARY = File.expand_path(File.dirname(__FILE__) + '/../../bin/cucumber')
12
12
  LIBDIR = File.expand_path(File.dirname(__FILE__) + '/../../lib')
13
13
  JRUBY = defined?(JRUBY_VERSION)
14
- IRONRUBY = Config::CONFIG['sitedir'] =~ /IronRuby/i
14
+ IRONRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == "ironruby"
15
15
  WINDOWS = Config::CONFIG['host_os'] =~ /mswin|mingw/
16
+ OS_X = Config::CONFIG['host_os'] =~ /darwin/
16
17
  WINDOWS_MRI = WINDOWS && !JRUBY && !IRONRUBY
17
18
  RAILS = defined?(Rails)
18
19
  RUBY_BINARY = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
@@ -27,4 +28,4 @@ module Cucumber
27
28
  end
28
29
  end
29
30
  self.use_full_backtrace = false
30
- end
31
+ end
@@ -13,33 +13,14 @@ if defined?(ActiveRecord::Base)
13
13
 
14
14
  Before do
15
15
  if Cucumber::Rails::World.use_transactional_fixtures
16
- @__cucumber_ar_connections = if ActiveRecord::Base.respond_to?(:connection_handler)
17
- ActiveRecord::Base.connection_handler.connection_pools.values.map {|pool| pool.connection}
18
- else
19
- [ActiveRecord::Base.connection] # Rails <= 2.1.2
20
- end
21
- @__cucumber_ar_connections.each do |__cucumber_ar_connection|
22
- if __cucumber_ar_connection.respond_to?(:increment_open_transactions)
23
- __cucumber_ar_connection.increment_open_transactions
24
- else
25
- ActiveRecord::Base.__send__(:increment_open_transactions)
26
- end
27
- __cucumber_ar_connection.begin_db_transaction
28
- end
16
+ run_callbacks :setup if respond_to?(:run_callbacks)
29
17
  end
30
18
  ActionMailer::Base.deliveries = [] if defined?(ActionMailer::Base)
31
19
  end
32
20
 
33
21
  After do
34
22
  if Cucumber::Rails::World.use_transactional_fixtures
35
- @__cucumber_ar_connections.each do |__cucumber_ar_connection|
36
- __cucumber_ar_connection.rollback_db_transaction
37
- if __cucumber_ar_connection.respond_to?(:decrement_open_transactions)
38
- __cucumber_ar_connection.decrement_open_transactions
39
- else
40
- ActiveRecord::Base.__send__(:decrement_open_transactions)
41
- end
42
- end
23
+ run_callbacks :teardown if respond_to?(:run_callbacks)
43
24
  end
44
25
  end
45
26
  else
@@ -8,13 +8,14 @@ end
8
8
  require 'cucumber/rails/test_unit'
9
9
  require 'cucumber/rails/action_controller'
10
10
 
11
- unless ::Rails.configuration.cache_classes
11
+ if ::Rails.respond_to?(:configuration) && !(::Rails.configuration.cache_classes)
12
12
  warn "WARNING: You have set Rails' config.cache_classes to false (most likely in config/environments/cucumber.rb). This setting is known to break Cucumber's use_transactional_fixtures method. Set config.cache_classes to true if you want to use transactional fixtures. For more information see https://rspec.lighthouseapp.com/projects/16211/tickets/165."
13
13
  end
14
14
 
15
15
  module Cucumber #:nodoc:
16
16
  module Rails
17
17
  class World < ActionController::IntegrationTest
18
+ include ActiveSupport::Testing::SetupAndTeardown
18
19
  def initialize #:nodoc:
19
20
  @_result = Test::Unit::TestResult.new
20
21
  end
@@ -2,6 +2,7 @@ module Cucumber
2
2
  module RbSupport
3
3
  # Wrapper for Before, After and AfterStep hooks
4
4
  class RbHook
5
+ attr_accessor :tag_name_lists
5
6
  attr_reader :tag_names
6
7
 
7
8
  def initialize(rb_language, tag_names, proc)
@@ -15,4 +16,4 @@ module Cucumber
15
16
  end
16
17
  end
17
18
  end
18
- end
19
+ end
@@ -35,6 +35,7 @@ module Cucumber
35
35
  @step_mother = step_mother
36
36
  @step_definitions = []
37
37
  RbDsl.rb_language = self
38
+ @world_proc = @world_modules = nil
38
39
  end
39
40
 
40
41
  # Tell the language about other i18n translations so that
@@ -87,13 +88,13 @@ module Cucumber
87
88
  multiline_class_comment = "# #{multiline_arg_class.default_arg_name} is a #{multiline_arg_class.to_s}\n "
88
89
  end
89
90
 
90
- "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending\nend"
91
+ "#{step_keyword} /^#{escaped}$/ do#{block_arg_string}\n #{multiline_class_comment}pending # express the regexp above with the code you wish you had\nend"
91
92
  end
92
93
 
93
- def begin_rb_scenario
94
+ def begin_rb_scenario(scenario)
94
95
  create_world
95
96
  extend_world
96
- connect_world
97
+ connect_world(scenario)
97
98
  end
98
99
 
99
100
  def register_rb_hook(phase, tag_names, proc)
@@ -125,8 +126,8 @@ module Cucumber
125
126
 
126
127
  protected
127
128
 
128
- def begin_scenario
129
- begin_rb_scenario
129
+ def begin_scenario(scenario)
130
+ begin_rb_scenario(scenario)
130
131
  end
131
132
 
132
133
  def end_scenario
@@ -155,8 +156,9 @@ module Cucumber
155
156
  end
156
157
  end
157
158
 
158
- def connect_world
159
+ def connect_world(scenario)
159
160
  @current_world.__cucumber_step_mother = @step_mother
161
+ @current_world.__natural_language = scenario.language
160
162
  end
161
163
 
162
164
  def check_nil(o, proc)
@@ -59,6 +59,10 @@ module Cucumber
59
59
  end
60
60
  end
61
61
 
62
+ def backtrace_line
63
+ @proc.backtrace_line(regexp_source)
64
+ end
65
+
62
66
  def file_colon_line
63
67
  @proc.file_colon_line
64
68
  end
@@ -14,56 +14,35 @@ module Cucumber
14
14
  rb.execute_transforms([arg]).first
15
15
  end
16
16
 
17
- attr_writer :__cucumber_step_mother
17
+ attr_writer :__cucumber_step_mother, :__natural_language
18
18
 
19
19
  # Call a step from within a step definition. This method is aliased to
20
20
  # the same i18n as RbDsl.
21
21
  def __cucumber_invoke(name, multiline_argument=nil) #:nodoc:
22
- begin
23
- @__cucumber_step_mother.invoke(name, multiline_argument)
24
- rescue Exception => e
25
- e.nested! if Undefined === e
26
- raise e
27
- end
22
+ @__cucumber_step_mother.invoke(name, multiline_argument)
28
23
  end
29
24
 
30
- # Returns a Cucumber::Ast::Table for +text_or_table+, which can either
31
- # be a String:
32
- #
33
- # table(%{
34
- # | account | description | amount |
35
- # | INT-100 | Taxi | 114 |
36
- # | CUC-101 | Peeler | 22 |
37
- # })
38
- #
39
- # or a 2D Array:
40
- #
41
- # table([
42
- # %w{ account description amount },
43
- # %w{ INT-100 Taxi 114 },
44
- # %w{ CUC-101 Peeler 22 }
45
- # ])
46
- #
25
+ # See StepMother#invoke_steps
26
+ def steps(steps_text)
27
+ @__cucumber_step_mother.invoke_steps(steps_text, @__natural_language)
28
+ end
29
+
30
+ # See StepMother#table
47
31
  def table(text_or_table, file=nil, line_offset=0)
48
- if Array === text_or_table
49
- Ast::Table.new(text_or_table)
50
- else
51
- @table_parser ||= Parser::TableParser.new
52
- @table_parser.parse_or_fail(text_or_table.strip, file, line_offset)
53
- end
32
+ @__cucumber_step_mother.table(text_or_table, file, line_offset)
54
33
  end
55
34
 
56
- # Output +announcement+ alongside the formatted output.
57
- # This is an alternative to using Kernel#puts - it will display
58
- # nicer, and in all outputs (in case you use several formatters)
59
- #
60
- # Beware that the output will be printed *before* the corresponding
61
- # step. This is because the step itself will not be printed until
62
- # after it has run, so it can be coloured according to its status.
35
+ # See StepMother#py_string
36
+ def py_string(string_with_triple_quotes, file=nil, line_offset=0)
37
+ @__cucumber_step_mother.py_string(text_or_table, file, line_offset)
38
+ end
39
+
40
+ # See StepMother#announce
63
41
  def announce(announcement)
64
42
  @__cucumber_step_mother.announce(announcement)
65
43
  end
66
44
 
45
+ # See StepMother#embed
67
46
  def embed(file, mime_type)
68
47
  @__cucumber_step_mother.embed(file, mime_type)
69
48
  end
@@ -49,6 +49,7 @@ module Cucumber
49
49
  @programming_languages = []
50
50
  @language_map = {}
51
51
  load_natural_language('en')
52
+ @current_scenario = nil
52
53
  end
53
54
 
54
55
  def load_plain_text_features(feature_files)
@@ -126,10 +127,21 @@ module Cucumber
126
127
  end
127
128
  end
128
129
 
129
- def announce(msg) #:nodoc:
130
+ # Output +announcement+ alongside the formatted output.
131
+ # This is an alternative to using Kernel#puts - it will display
132
+ # nicer, and in all outputs (in case you use several formatters)
133
+ #
134
+ # Beware that the output will be printed *before* the corresponding
135
+ # step. This is because the step itself will not be printed until
136
+ # after it has run, so it can be coloured according to its status.
137
+ #
138
+ def announce(msg)
130
139
  @visitor.announce(msg)
131
140
  end
132
141
 
142
+ # Embed +file+ of MIME type +mime_type+ into the output. This may or may
143
+ # not be ignored, depending on what kind of formatter(s) are active.
144
+ #
133
145
  def embed(file, mime_type)
134
146
  @visitor.embed(file, mime_type)
135
147
  end
@@ -144,7 +156,79 @@ module Cucumber
144
156
  end
145
157
 
146
158
  def invoke(step_name, multiline_argument=nil)
147
- step_match(step_name).invoke(multiline_argument)
159
+ begin
160
+ step_match(step_name).invoke(multiline_argument)
161
+ rescue Exception => e
162
+ e.nested! if Undefined === e
163
+ raise e
164
+ end
165
+ end
166
+
167
+ # Invokes a series of steps +steps_text+. Example:
168
+ #
169
+ # invoke(%Q{
170
+ # Given I have 8 cukes in my belly
171
+ # Then I should not be thirsty
172
+ # })
173
+ def invoke_steps(steps_text, natural_language)
174
+ ored_keywords = natural_language.step_keywords.join("|")
175
+ after_keyword = natural_language.space_after_keyword ? ' ' : ''
176
+ # TODO Gherkin:
177
+ # This a bit hacky and fragile. When we move to Gherkin we should replace this entire method body
178
+ # with a call to the parser - parsing the body of a scenario. We may need to put the parser/policy in the
179
+ # appropriate state (the same state it's in after parsing a Scenario: line).
180
+ steps_text.strip.split(/(?=^\s*(?:#{ored_keywords}))/).map { |step| step.strip }.each do |step|
181
+ output = step.match(/^\s*(#{ored_keywords})#{after_keyword}([^\n]+)(\n.*)?$/m)
182
+
183
+ action, step_name, table_or_string = output[1], output[2], output[3]
184
+ if table_or_string.to_s.strip =~ /^\|/
185
+ table_or_string = table(table_or_string)
186
+ elsif table_or_string.to_s.strip =~ /^"""/
187
+ table_or_string = py_string(table_or_string.gsub(/^\n/, ""))
188
+ end
189
+ args = [step_name, table_or_string].compact
190
+ invoke(*args)
191
+ end
192
+ end
193
+
194
+ # Returns a Cucumber::Ast::Table for +text_or_table+, which can either
195
+ # be a String:
196
+ #
197
+ # table(%{
198
+ # | account | description | amount |
199
+ # | INT-100 | Taxi | 114 |
200
+ # | CUC-101 | Peeler | 22 |
201
+ # })
202
+ #
203
+ # or a 2D Array:
204
+ #
205
+ # table([
206
+ # %w{ account description amount },
207
+ # %w{ INT-100 Taxi 114 },
208
+ # %w{ CUC-101 Peeler 22 }
209
+ # ])
210
+ #
211
+ def table(text_or_table, file=nil, line_offset=0)
212
+ if Array === text_or_table
213
+ Ast::Table.new(text_or_table)
214
+ else
215
+ @table_parser ||= Parser::TableParser.new
216
+ @table_parser.parse_or_fail(text_or_table.strip, file, line_offset)
217
+ end
218
+ end
219
+
220
+ # Returns a regular String for +string_with_triple_quotes+. Example:
221
+ #
222
+ # """
223
+ # hello
224
+ # world
225
+ # """
226
+ #
227
+ # Is retured as: " hello\nworld"
228
+ #
229
+ def py_string(string_with_triple_quotes, file=nil, line_offset=0)
230
+ @py_string_parser ||= Parser::PyStringParser.new
231
+ @py_string_parser.parse_or_fail(string_with_triple_quotes, file, line_offset).to_s
148
232
  end
149
233
 
150
234
  def step_match(step_name, name_to_report=nil) #:nodoc:
@@ -34,8 +34,8 @@ module Cucumber
34
34
 
35
35
  protected
36
36
 
37
- def begin_scenario
38
- @connections.each { |remote| remote.begin_scenario }
37
+ def begin_scenario(scenario)
38
+ @connections.each { |remote| remote.begin_scenario(scenario) }
39
39
  end
40
40
 
41
41
  def end_scenario
@@ -36,7 +36,7 @@ module Cucumber
36
36
  end
37
37
  end
38
38
 
39
- def begin_scenario
39
+ def begin_scenario(scenario)
40
40
  make_request(:begin_scenario) do
41
41
  def handle_success(params)
42
42
  end
@@ -16,7 +16,9 @@ class CucumberGenerator < Rails::Generator::Base
16
16
  :assigns => { :cucumber_version => ::Cucumber::VERSION }
17
17
 
18
18
  m.gsub_file 'config/database.yml', /test:.*\n/, "test: &TEST\n"
19
- m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *TEST"
19
+ unless File.read('config/database.yml').include? 'cucumber:'
20
+ m.gsub_file 'config/database.yml', /\z/, "\ncucumber:\n <<: *TEST"
21
+ end
20
22
 
21
23
  m.directory 'features/support'
22
24
  if spork?
@@ -1,5 +1,7 @@
1
1
  # This file was generated by
2
- $LOAD_PATH.unshift(RAILS_ROOT + '/vendor/plugins/cucumber/lib') if File.directory?(RAILS_ROOT + '/vendor/plugins/cucumber/lib')
2
+ # Find vendored gem or plugin of cucumber
3
+ vendored_cucumber_dir = Dir["#{RAILS_ROOT}/vendor/{gems,plugins}/cucumber*"].first
4
+ $LOAD_PATH.unshift("#{vendored_cucumber_dir}/lib") unless vendored_cucumber_dir.nil?
3
5
 
4
6
  unless ARGV.any? {|a| a =~ /^gems/}
5
7
 
@@ -8,7 +10,7 @@ begin
8
10
 
9
11
  # Use vendored cucumber binary if possible. If it's not vendored,
10
12
  # Cucumber::Rake::Task will automatically use installed gem's cucumber binary
11
- vendored_cucumber_binary = Dir["#{RAILS_ROOT}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
13
+ vendored_cucumber_binary = "#{vendored_cucumber_dir}/bin/cucumber" unless vendored_cucumber_dir.nil?
12
14
 
13
15
  namespace :cucumber do
14
16
  Cucumber::Rake::Task.new({:ok => 'db:test:prepare'}, 'Run features that should pass') do |t|
@@ -8,31 +8,31 @@ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "pat
8
8
  # Commonly used webrat steps
9
9
  # http://github.com/brynary/webrat
10
10
 
11
- Given /^I am on (.+)$/ do |page_name|
11
+ Given /^(?:|I )am on (.+)$/ do |page_name|
12
12
  visit path_to(page_name)
13
13
  end
14
14
 
15
- When /^I go to (.+)$/ do |page_name|
15
+ When /^(?:|I )go to (.+)$/ do |page_name|
16
16
  visit path_to(page_name)
17
17
  end
18
18
 
19
- When /^I press "([^\"]*)"$/ do |button|
19
+ When /^(?:|I )press "([^\"]*)"$/ do |button|
20
20
  click_button(button)
21
21
  end
22
22
 
23
- When /^I follow "([^\"]*)"$/ do |link|
23
+ When /^(?:|I )follow "([^\"]*)"$/ do |link|
24
24
  click_link(link)
25
25
  end
26
26
 
27
- When /^I follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
27
+ When /^(?:|I )follow "([^\"]*)" within "([^\"]*)"$/ do |link, parent|
28
28
  click_link_within(parent, link)
29
29
  end
30
30
 
31
- When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
31
+ When /^(?:|I )fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
32
32
  fill_in(field, :with => value)
33
33
  end
34
34
 
35
- When /^I fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
35
+ When /^(?:|I )fill in "([^\"]*)" for "([^\"]*)"$/ do |value, field|
36
36
  fill_in(field, :with => value)
37
37
  end
38
38
 
@@ -47,19 +47,19 @@ end
47
47
  # TODO: Add support for checkbox, select og option
48
48
  # based on naming conventions.
49
49
  #
50
- When /^I fill in the following:$/ do |fields|
50
+ When /^(?:|I )fill in the following:$/ do |fields|
51
51
  fields.rows_hash.each do |name, value|
52
52
  When %{I fill in "#{name}" with "#{value}"}
53
53
  end
54
54
  end
55
55
 
56
- When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
56
+ When /^(?:|I )select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
57
57
  select(value, :from => field)
58
58
  end
59
59
 
60
60
  # Use this step in conjunction with Rail's datetime_select helper. For example:
61
61
  # When I select "December 25, 2008 10:00" as the date and time
62
- When /^I select "([^\"]*)" as the date and time$/ do |time|
62
+ When /^(?:|I )select "([^\"]*)" as the date and time$/ do |time|
63
63
  select_datetime(time)
64
64
  end
65
65
 
@@ -72,7 +72,7 @@ end
72
72
  # The following steps would fill out the form:
73
73
  # When I select "November 23, 2004 11:20" as the "Preferred" date and time
74
74
  # And I select "November 25, 2004 10:30" as the "Alternative" date and time
75
- When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
75
+ When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
76
76
  select_datetime(datetime, :from => datetime_label)
77
77
  end
78
78
 
@@ -80,47 +80,47 @@ end
80
80
  # When I select "2:20PM" as the time
81
81
  # Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
82
82
  # will convert the 2:20PM to 14:20 and then select it.
83
- When /^I select "([^\"]*)" as the time$/ do |time|
83
+ When /^(?:|I )select "([^\"]*)" as the time$/ do |time|
84
84
  select_time(time)
85
85
  end
86
86
 
87
87
  # Use this step when using multiple time_select helpers on a page or you want to
88
88
  # specify the name of the time on the form. For example:
89
89
  # When I select "7:30AM" as the "Gym" time
90
- When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
90
+ When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
91
91
  select_time(time, :from => time_label)
92
92
  end
93
93
 
94
94
  # Use this step in conjunction with Rail's date_select helper. For example:
95
95
  # When I select "February 20, 1981" as the date
96
- When /^I select "([^\"]*)" as the date$/ do |date|
96
+ When /^(?:|I )select "([^\"]*)" as the date$/ do |date|
97
97
  select_date(date)
98
98
  end
99
99
 
100
100
  # Use this step when using multiple date_select helpers on one page or
101
101
  # you want to specify the name of the date on the form. For example:
102
102
  # When I select "April 26, 1982" as the "Date of Birth" date
103
- When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
103
+ When /^(?:|I )select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
104
104
  select_date(date, :from => date_label)
105
105
  end
106
106
 
107
- When /^I check "([^\"]*)"$/ do |field|
107
+ When /^(?:|I )check "([^\"]*)"$/ do |field|
108
108
  check(field)
109
109
  end
110
110
 
111
- When /^I uncheck "([^\"]*)"$/ do |field|
111
+ When /^(?:|I )uncheck "([^\"]*)"$/ do |field|
112
112
  uncheck(field)
113
113
  end
114
114
 
115
- When /^I choose "([^\"]*)"$/ do |field|
115
+ When /^(?:|I )choose "([^\"]*)"$/ do |field|
116
116
  choose(field)
117
117
  end
118
118
 
119
- When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
119
+ When /^(?:|I )attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
120
120
  attach_file(field, path)
121
121
  end
122
122
 
123
- Then /^I should see "([^\"]*)"$/ do |text|
123
+ Then /^(?:|I )should see "([^\"]*)"$/ do |text|
124
124
  <% if framework == :rspec -%>
125
125
  response.should contain(text)
126
126
  <% else -%>
@@ -128,7 +128,7 @@ Then /^I should see "([^\"]*)"$/ do |text|
128
128
  <% end -%>
129
129
  end
130
130
 
131
- Then /^I should see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
131
+ Then /^(?:|I )should see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
132
132
  within(selector) do |content|
133
133
  <% if framework == :rspec -%>
134
134
  content.should contain(text)
@@ -138,7 +138,7 @@ Then /^I should see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
138
138
  end
139
139
  end
140
140
 
141
- Then /^I should see \/([^\/]*)\/$/ do |regexp|
141
+ Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
142
142
  regexp = Regexp.new(regexp)
143
143
  <% if framework == :rspec -%>
144
144
  response.should contain(regexp)
@@ -147,7 +147,7 @@ Then /^I should see \/([^\/]*)\/$/ do |regexp|
147
147
  <% end -%>
148
148
  end
149
149
 
150
- Then /^I should see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
150
+ Then /^(?:|I )should see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
151
151
  within(selector) do |content|
152
152
  regexp = Regexp.new(regexp)
153
153
  <% if framework == :rspec -%>
@@ -158,7 +158,7 @@ Then /^I should see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
158
158
  end
159
159
  end
160
160
 
161
- Then /^I should not see "([^\"]*)"$/ do |text|
161
+ Then /^(?:|I )should not see "([^\"]*)"$/ do |text|
162
162
  <% if framework == :rspec -%>
163
163
  response.should_not contain(text)
164
164
  <% else -%>
@@ -166,7 +166,7 @@ Then /^I should not see "([^\"]*)"$/ do |text|
166
166
  <% end -%>
167
167
  end
168
168
 
169
- Then /^I should not see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
169
+ Then /^(?:|I )should not see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
170
170
  within(selector) do |content|
171
171
  <% if framework == :rspec -%>
172
172
  content.should_not contain(text)
@@ -176,7 +176,7 @@ Then /^I should not see "([^\"]*)" within "([^\"]*)"$/ do |text, selector|
176
176
  end
177
177
  end
178
178
 
179
- Then /^I should not see \/([^\/]*)\/$/ do |regexp|
179
+ Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
180
180
  regexp = Regexp.new(regexp)
181
181
  <% if framework == :rspec -%>
182
182
  response.should_not contain(regexp)
@@ -185,7 +185,7 @@ Then /^I should not see \/([^\/]*)\/$/ do |regexp|
185
185
  <% end -%>
186
186
  end
187
187
 
188
- Then /^I should not see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
188
+ Then /^(?:|I )should not see \/([^\/]*)\/ within "([^\"]*)"$/ do |regexp, selector|
189
189
  within(selector) do |content|
190
190
  regexp = Regexp.new(regexp)
191
191
  <% if framework == :rspec -%>
@@ -228,7 +228,7 @@ Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
228
228
  <% end -%>
229
229
  end
230
230
 
231
- Then /^I should be on (.+)$/ do |page_name|
231
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
232
232
  <% if framework == :rspec -%>
233
233
  URI.parse(current_url).path.should == path_to(page_name)
234
234
  <% else -%>