cucumber 2.0.0 → 2.0.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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +7 -9
  3. data/History.md +295 -265
  4. data/README.md +9 -7
  5. data/cucumber.gemspec +2 -2
  6. data/features/docs/cli/dry_run.feature +0 -3
  7. data/features/docs/cli/finding_steps.feature +28 -0
  8. data/features/docs/cli/run_specific_scenarios.feature +3 -1
  9. data/features/docs/cli/specifying_multiple_formatters.feature +22 -1
  10. data/features/docs/defining_steps/nested_steps.feature +0 -1
  11. data/features/docs/defining_steps/printing_messages.feature +4 -4
  12. data/features/docs/defining_steps/skip_scenario.feature +0 -2
  13. data/features/docs/exception_in_around_hook.feature +1 -3
  14. data/features/docs/formatters/html_formatter.feature +1 -0
  15. data/features/docs/formatters/json_formatter.feature +73 -62
  16. data/features/docs/formatters/junit_formatter.feature +130 -38
  17. data/features/docs/formatters/rerun_formatter.feature +60 -8
  18. data/features/docs/formatters/usage_formatter.feature +3 -7
  19. data/features/docs/getting_started.feature +1 -1
  20. data/features/docs/gherkin/background.feature +0 -11
  21. data/features/docs/gherkin/language_help.feature +5 -0
  22. data/features/docs/gherkin/outlines.feature +1 -3
  23. data/features/docs/gherkin/using_descriptions.feature +0 -1
  24. data/features/docs/raketask.feature +1 -1
  25. data/features/docs/writing_support_code/after_hooks.feature +22 -0
  26. data/features/lib/step_definitions/aruba_steps.rb +4 -0
  27. data/features/lib/step_definitions/junit_steps.rb +1 -1
  28. data/features/lib/support/normalise_output.rb +21 -4
  29. data/lib/cucumber/cli/configuration.rb +16 -13
  30. data/lib/cucumber/cli/main.rb +35 -10
  31. data/lib/cucumber/cli/options.rb +33 -9
  32. data/lib/cucumber/cli/rerun_file.rb +29 -0
  33. data/lib/cucumber/filters/prepare_world.rb +2 -3
  34. data/lib/cucumber/formatter/backtrace_filter.rb +40 -0
  35. data/lib/cucumber/formatter/console.rb +2 -3
  36. data/lib/cucumber/formatter/cucumber.css +1 -0
  37. data/lib/cucumber/formatter/duration_extractor.rb +28 -0
  38. data/lib/cucumber/formatter/hook_query_visitor.rb +40 -0
  39. data/lib/cucumber/formatter/html.rb +16 -1
  40. data/lib/cucumber/formatter/json.rb +287 -8
  41. data/lib/cucumber/formatter/junit.rb +92 -143
  42. data/lib/cucumber/formatter/legacy_api/adapter.rb +18 -54
  43. data/lib/cucumber/formatter/legacy_api/ast.rb +13 -0
  44. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -0
  45. data/lib/cucumber/formatter/pretty.rb +2 -1
  46. data/lib/cucumber/formatter/progress.rb +20 -53
  47. data/lib/cucumber/formatter/rerun.rb +2 -1
  48. data/lib/cucumber/formatter/usage.rb +16 -22
  49. data/lib/cucumber/hooks.rb +18 -9
  50. data/lib/cucumber/multiline_argument/data_table.rb +40 -28
  51. data/lib/cucumber/platform.rb +1 -1
  52. data/lib/cucumber/rb_support/rb_hook.rb +4 -0
  53. data/lib/cucumber/running_test_case.rb +13 -4
  54. data/lib/cucumber/runtime/after_hooks.rb +7 -6
  55. data/lib/cucumber/runtime/before_hooks.rb +8 -4
  56. data/lib/cucumber/runtime/step_hooks.rb +5 -4
  57. data/lib/cucumber/runtime/support_code.rb +6 -15
  58. data/lib/cucumber/step_match.rb +1 -1
  59. data/spec/cucumber/cli/configuration_spec.rb +32 -5
  60. data/spec/cucumber/cli/main_spec.rb +3 -3
  61. data/spec/cucumber/cli/options_spec.rb +60 -1
  62. data/spec/cucumber/cli/rerun_spec.rb +89 -0
  63. data/spec/cucumber/formatter/html_spec.rb +84 -5
  64. data/spec/cucumber/formatter/json_spec.rb +757 -0
  65. data/spec/cucumber/formatter/junit_spec.rb +5 -5
  66. data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +69 -8
  67. data/spec/cucumber/formatter/pretty_spec.rb +96 -0
  68. data/spec/cucumber/formatter/progress_spec.rb +85 -1
  69. data/spec/cucumber/formatter/rerun_spec.rb +3 -3
  70. data/spec/cucumber/multiline_argument/data_table_spec.rb +89 -0
  71. data/spec/cucumber/running_test_case_spec.rb +57 -1
  72. metadata +70 -60
  73. data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +0 -204
  74. data/lib/cucumber/formatter/gpretty.rb +0 -24
@@ -2,7 +2,7 @@ Feature: Rerun formatter
2
2
 
3
3
  The rerun formatter writes an output that's perfect for
4
4
  passing to Cucumber when you want to rerun only the
5
- scenarios that have failed.
5
+ scenarios that prevented the exit code to be zero.
6
6
 
7
7
  You can save off the rerun output to a file by using it like this:
8
8
 
@@ -18,7 +18,28 @@ Feature: Rerun formatter
18
18
  Background:
19
19
  Given the standard step definitions
20
20
 
21
- Scenario: Regular scenarios
21
+ Scenario: Exit code is zero
22
+ Given a file named "features/mixed.feature" with:
23
+ """
24
+ Feature: Mixed
25
+
26
+ Scenario:
27
+ Given this step is undefined
28
+
29
+ Scenario:
30
+ Given this step is pending
31
+
32
+ Scenario:
33
+ Given this step passes
34
+
35
+ """
36
+
37
+ When I run `cucumber -f rerun`
38
+ Then it should pass with exactly:
39
+ """
40
+ """
41
+
42
+ Scenario: Exit code is zero in the dry-run mode
22
43
  Given a file named "features/mixed.feature" with:
23
44
  """
24
45
  Feature: Mixed
@@ -44,13 +65,44 @@ Feature: Rerun formatter
44
65
  Given this step passes
45
66
  """
46
67
 
47
- When I run `cucumber -f rerun`
48
- Then it should fail with:
68
+ When I run `cucumber -f rerun --dry-run`
69
+ Then it should pass with exactly:
70
+ """
71
+ """
72
+
73
+ Scenario: Exit code is not zero, regular scenario
74
+ Given a file named "features/mixed.feature" with:
75
+ """
76
+ Feature: Mixed
77
+
78
+ Scenario:
79
+ Given this step fails
80
+
81
+ Scenario:
82
+ Given this step is undefined
83
+
84
+ Scenario:
85
+ Given this step is pending
86
+
87
+ Scenario:
88
+ Given this step passes
89
+
90
+ """
91
+ And a file named "features/all_good.feature" with:
92
+ """
93
+ Feature: All good
94
+
95
+ Scenario:
96
+ Given this step passes
97
+ """
98
+
99
+ When I run `cucumber -f rerun --strict`
100
+ Then it should fail with exactly:
49
101
  """
50
102
  features/mixed.feature:3:6:9
51
103
  """
52
104
 
53
- Scenario: Scenario outlines
105
+ Scenario: Exit code is not zero, scenario outlines
54
106
  For details see https://github.com/cucumber/cucumber/issues/57
55
107
  Given a file named "features/one_passing_one_failing.feature" with:
56
108
  """
@@ -71,7 +123,7 @@ Feature: Rerun formatter
71
123
  features/one_passing_one_failing.feature:9
72
124
  """
73
125
 
74
- Scenario: Failing background
126
+ Scenario: Exit code is not zero, failing background
75
127
  Given a file named "features/failing_background.feature" with:
76
128
  """
77
129
  Feature: Failing background sample
@@ -91,7 +143,7 @@ Feature: Rerun formatter
91
143
  features/failing_background.feature:6:9
92
144
  """
93
145
 
94
- Scenario: Failing background with scenario outline
146
+ Scenario: Exit code is not zero, failing background with scenario outline
95
147
  Given a file named "features/failing_background_outline.feature" with:
96
148
  """
97
149
  Feature: Failing background sample with scenario outline
@@ -113,7 +165,7 @@ Feature: Rerun formatter
113
165
  features/failing_background_outline.feature:11:12
114
166
  """
115
167
 
116
- Scenario: Scenario outlines with expand
168
+ Scenario: Exit code is not zero, scenario outlines with expand
117
169
  For details see https://github.com/cucumber/cucumber/issues/503
118
170
 
119
171
  Given a file named "features/one_passing_one_failing.feature" with:
@@ -30,12 +30,11 @@ Feature: Usage formatter
30
30
  Given(/D/) { }
31
31
  """
32
32
 
33
- @wip-new-core
34
33
  Scenario: Run with --format usage
35
34
  When I run `cucumber -f usage --dry-run`
36
35
  Then it should pass with exactly:
37
36
  """
38
- --------
37
+ -----------
39
38
 
40
39
  /A/ # features/step_definitions/steps.rb:1
41
40
  Given A # features/f.feature:3
@@ -53,7 +52,6 @@ Feature: Usage formatter
53
52
 
54
53
  4 scenarios (4 skipped)
55
54
  11 steps (11 skipped)
56
- 0m0.012s
57
55
 
58
56
  """
59
57
 
@@ -61,7 +59,7 @@ Feature: Usage formatter
61
59
  When I run `cucumber -x -f usage --dry-run`
62
60
  Then it should pass with exactly:
63
61
  """
64
- ----------
62
+ -----------
65
63
 
66
64
  /A/ # features/step_definitions/steps.rb:1
67
65
  Given A # features/f.feature:3
@@ -79,7 +77,6 @@ Feature: Usage formatter
79
77
 
80
78
  4 scenarios (4 skipped)
81
79
  11 steps (11 skipped)
82
- 0m0.012s
83
80
 
84
81
  """
85
82
 
@@ -87,7 +84,7 @@ Feature: Usage formatter
87
84
  When I run `cucumber -f stepdefs --dry-run`
88
85
  Then it should pass with exactly:
89
86
  """
90
- --------
87
+ -----------
91
88
 
92
89
  /A/ # features/step_definitions/steps.rb:1
93
90
  /B/ # features/step_definitions/steps.rb:2
@@ -97,6 +94,5 @@ Feature: Usage formatter
97
94
 
98
95
  4 scenarios (4 skipped)
99
96
  11 steps (11 skipped)
100
- 0m0.012s
101
97
 
102
98
  """
@@ -19,7 +19,7 @@ Feature: Getting started
19
19
  puts 'this will not be shown'
20
20
  """
21
21
  When I run `cucumber`
22
- Then the exit status should be 1
22
+ Then the exit status should be 2
23
23
  And the output should not contain:
24
24
  """
25
25
  this will not be shown
@@ -222,7 +222,6 @@ Feature: Background
222
222
 
223
223
  1 scenario (1 passed)
224
224
  2 steps (2 passed)
225
- 0m0.012s
226
225
 
227
226
  """
228
227
 
@@ -243,7 +242,6 @@ Feature: Background
243
242
 
244
243
  2 scenarios (2 passed)
245
244
  4 steps (4 passed)
246
- 0m0.012s
247
245
 
248
246
  """
249
247
 
@@ -272,7 +270,6 @@ Feature: Background
272
270
 
273
271
  2 scenarios (2 passed)
274
272
  4 steps (4 passed)
275
- 0m0.012s
276
273
 
277
274
  """
278
275
 
@@ -295,7 +292,6 @@ Feature: Background
295
292
 
296
293
  1 scenario (1 passed)
297
294
  2 steps (2 passed)
298
- 0m0.012s
299
295
 
300
296
  """
301
297
 
@@ -325,7 +321,6 @@ Feature: Background
325
321
 
326
322
  2 scenarios (2 failed)
327
323
  6 steps (2 failed, 4 skipped)
328
- 0m0.012s
329
324
 
330
325
  """
331
326
 
@@ -362,7 +357,6 @@ Feature: Background
362
357
 
363
358
  2 scenarios (2 failed)
364
359
  4 steps (2 failed, 2 skipped)
365
- 0m0.012s
366
360
 
367
361
  """
368
362
 
@@ -386,7 +380,6 @@ Feature: Background
386
380
 
387
381
  2 scenarios (2 pending)
388
382
  4 steps (2 skipped, 2 pending)
389
- 0m0.012s
390
383
 
391
384
  """
392
385
 
@@ -416,7 +409,6 @@ Feature: Background
416
409
 
417
410
  2 scenarios (1 failed, 1 passed)
418
411
  6 steps (1 failed, 1 skipped, 4 passed)
419
- 0m0.012s
420
412
 
421
413
  """
422
414
 
@@ -453,7 +445,6 @@ Feature: Background
453
445
 
454
446
  2 scenarios (1 failed, 1 passed)
455
447
  6 steps (1 failed, 1 skipped, 4 passed)
456
- 0m0.012s
457
448
 
458
449
  """
459
450
 
@@ -493,7 +484,6 @@ Feature: Background
493
484
 
494
485
  2 scenarios (1 failed, 1 passed)
495
486
  6 steps (1 failed, 1 skipped, 4 passed)
496
- 0m0.012s
497
487
 
498
488
  """
499
489
 
@@ -553,7 +543,6 @@ Feature: Background
553
543
 
554
544
  2 scenarios (2 passed)
555
545
  8 steps (8 passed)
556
- 0m0.012s
557
546
 
558
547
  """
559
548
 
@@ -35,3 +35,8 @@ Feature: Language help
35
35
  Scenario: List languages
36
36
  When I run `cucumber --i18n help`
37
37
  Then cucumber lists all the supported languages
38
+
39
+ Scenario: Seek help for invalid language
40
+ When I run `cucumber --i18n foo`
41
+ Then the output includes the message "Invalid language 'foo'"
42
+ And cucumber lists all the supported languages
@@ -138,7 +138,7 @@ Feature: Scenario outlines
138
138
  When I run `cucumber -q --format progress features/outline_sample.feature`
139
139
  Then it should fail with exactly:
140
140
  """
141
- --UU..FF..
141
+ U-..F-..
142
142
 
143
143
  (::) failed steps (::)
144
144
 
@@ -152,7 +152,5 @@ Feature: Scenario outlines
152
152
 
153
153
  5 scenarios (1 failed, 1 undefined, 3 passed)
154
154
  8 steps (1 failed, 2 skipped, 1 undefined, 4 passed)
155
- 0m0.012s
156
155
 
157
156
  """
158
-
@@ -83,6 +83,5 @@ Feature: Using descriptions to give features context
83
83
 
84
84
  2 scenarios (2 passed)
85
85
  4 steps (4 passed)
86
- 0m0.012s
87
86
 
88
87
  """
@@ -40,5 +40,5 @@ Feature: Raketask
40
40
 
41
41
  Scenario: Failing feature
42
42
  When I run `bundle exec rake fail`
43
- Then the exit status should not be 0
43
+ Then the exit status should be 1
44
44
  But the output should not contain "rake aborted!"
@@ -11,6 +11,28 @@ Feature: After Hooks
11
11
  Background:
12
12
  Given the standard step definitions
13
13
 
14
+ Scenario Outline: Retrieve the status of a scenario as a symbol
15
+ Given a file named "features/support/debug_hook.rb" with:
16
+ """
17
+ After do |scenario|
18
+ puts scenario.status.inspect
19
+ end
20
+ """
21
+ And a file named "features/result.feature" with:
22
+ """
23
+ Feature:
24
+ Scenario:
25
+ Given this step <result>
26
+ """
27
+ When I run `cucumber -f progress`
28
+ Then the output should contain "<status symbol>"
29
+
30
+ Examples:
31
+ | result | status symbol |
32
+ | passes | :passed |
33
+ | fails | :failed |
34
+ | is pending | :pending |
35
+
14
36
  Scenario: Check the failed status of a scenario in a hook
15
37
  Given a file named "features/support/debug_hook.rb" with:
16
38
  """
@@ -20,3 +20,7 @@ Then /^it fails before running features with:$/ do |expected|
20
20
  assert_matching_output("\\A#{expected}", all_output)
21
21
  assert_success(false)
22
22
  end
23
+
24
+ Then(/^the output includes the message "(.*)"$/) do |message|
25
+ expect(all_output).to include(message)
26
+ end
@@ -1,7 +1,7 @@
1
1
  Then(/^the junit output file "(.*?)" should contain:$/) do |actual_file, text|
2
2
  actual = IO.read(current_dir + '/' + actual_file)
3
3
  actual = replace_junit_time(actual)
4
- expect(actual).to eq text.to_s
4
+ expect(actual).to eq text
5
5
  end
6
6
 
7
7
  module JUnitHelper
@@ -19,15 +19,32 @@ module NormaliseArubaOutput
19
19
  elements = feature.fetch('elements') { [] }
20
20
  elements.each do |scenario|
21
21
  scenario['steps'].each do |step|
22
- if step['result']
23
- expect(step['result']['duration']).to be >= 0
24
- step['result']['duration'] = 1
22
+ ['steps', 'before', 'after'].each do |type|
23
+ if scenario[type]
24
+ scenario[type].each do |step_or_hook|
25
+ normalise_json_step_or_hook(step_or_hook)
26
+ if step_or_hook['after']
27
+ step_or_hook['after'].each do |hook|
28
+ normalise_json_step_or_hook(hook)
29
+ end
30
+ end
31
+ end
32
+ end
25
33
  end
26
34
  end
27
35
  end
28
36
  end
29
37
  end
38
+
39
+ def normalise_json_step_or_hook(step_or_hook)
40
+ if step_or_hook['result']
41
+ if step_or_hook['result']['duration']
42
+ expect(step_or_hook['result']['duration']).to be >= 0
43
+ step_or_hook['result']['duration'] = 1
44
+ end
45
+ end
46
+ end
47
+
30
48
  end
31
49
 
32
50
  World(NormaliseArubaOutput)
33
-
@@ -1,5 +1,6 @@
1
1
  require 'logger'
2
2
  require 'cucumber/cli/options'
3
+ require 'cucumber/cli/rerun_file'
3
4
  require 'cucumber/constantize'
4
5
  require 'gherkin/tag_expression'
5
6
 
@@ -75,8 +76,7 @@ module Cucumber
75
76
  end
76
77
 
77
78
  def all_files_to_load
78
- requires = @options[:require].empty? ? require_dirs : @options[:require]
79
- files = requires.map do |path|
79
+ files = require_dirs.map do |path|
80
80
  path = path.gsub(/\\/, '/') # In case we're on windows. Globs don't work with backslashes.
81
81
  path = path.gsub(/\/$/, '') # Strip trailing slash.
82
82
  File.directory?(path) ? Dir["#{path}/**/*"] : path
@@ -105,9 +105,8 @@ module Cucumber
105
105
  path = path.chomp('/')
106
106
  if File.directory?(path)
107
107
  Dir["#{path}/**/*.feature"].sort
108
- elsif path[0..0] == '@' and # @listfile.txt
109
- File.file?(path[1..-1]) # listfile.txt is a file
110
- IO.read(path[1..-1]).split(/(.*?\.feature.*?) /).collect(&:strip).reject(&:empty?)
108
+ elsif RerunFile.can_read?(path)
109
+ RerunFile.new(path).features
111
110
  else
112
111
  path
113
112
  end
@@ -116,6 +115,7 @@ module Cucumber
116
115
  potential_feature_files
117
116
  end
118
117
 
118
+
119
119
  def feature_dirs
120
120
  dirs = paths.map { |f| File.directory?(f) ? f : File.dirname(f) }.uniq
121
121
  dirs.delete('.') unless paths.include?('.')
@@ -180,8 +180,12 @@ module Cucumber
180
180
 
181
181
  private
182
182
 
183
+ def default_features_paths
184
+ ["features"]
185
+ end
186
+
183
187
  def with_default_features_path(paths)
184
- return ['features'] if paths.empty?
188
+ return default_features_paths if paths.empty?
185
189
  paths
186
190
  end
187
191
 
@@ -201,10 +205,7 @@ module Cucumber
201
205
  @options[:formats] << ['pretty', @out_stream] if @options[:formats].empty?
202
206
  @options[:formats] = @options[:formats].sort_by{|f| f[1] == @out_stream ? -1 : 1}
203
207
  @options[:formats].uniq!
204
- streams = @options[:formats].map { |(_, stream)| stream }
205
- if streams != streams.uniq
206
- raise "All but one formatter must use --out, only one can print to each stream (or STDOUT)"
207
- end
208
+ @options.check_formatter_stream_conflicts()
208
209
  end
209
210
 
210
211
  def remove_excluded_files_from(files)
@@ -212,10 +213,12 @@ module Cucumber
212
213
  end
213
214
 
214
215
  def require_dirs
215
- feature_dirs + Dir['vendor/{gems,plugins}/*/cucumber']
216
+ if @options[:require].empty?
217
+ default_features_paths + Dir['vendor/{gems,plugins}/*/cucumber']
218
+ else
219
+ @options[:require]
220
+ end
216
221
  end
217
-
218
222
  end
219
-
220
223
  end
221
224
  end