cucumber 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +7 -9
- data/History.md +295 -265
- data/README.md +9 -7
- data/cucumber.gemspec +2 -2
- data/features/docs/cli/dry_run.feature +0 -3
- data/features/docs/cli/finding_steps.feature +28 -0
- data/features/docs/cli/run_specific_scenarios.feature +3 -1
- data/features/docs/cli/specifying_multiple_formatters.feature +22 -1
- data/features/docs/defining_steps/nested_steps.feature +0 -1
- data/features/docs/defining_steps/printing_messages.feature +4 -4
- data/features/docs/defining_steps/skip_scenario.feature +0 -2
- data/features/docs/exception_in_around_hook.feature +1 -3
- data/features/docs/formatters/html_formatter.feature +1 -0
- data/features/docs/formatters/json_formatter.feature +73 -62
- data/features/docs/formatters/junit_formatter.feature +130 -38
- data/features/docs/formatters/rerun_formatter.feature +60 -8
- data/features/docs/formatters/usage_formatter.feature +3 -7
- data/features/docs/getting_started.feature +1 -1
- data/features/docs/gherkin/background.feature +0 -11
- data/features/docs/gherkin/language_help.feature +5 -0
- data/features/docs/gherkin/outlines.feature +1 -3
- data/features/docs/gherkin/using_descriptions.feature +0 -1
- data/features/docs/raketask.feature +1 -1
- data/features/docs/writing_support_code/after_hooks.feature +22 -0
- data/features/lib/step_definitions/aruba_steps.rb +4 -0
- data/features/lib/step_definitions/junit_steps.rb +1 -1
- data/features/lib/support/normalise_output.rb +21 -4
- data/lib/cucumber/cli/configuration.rb +16 -13
- data/lib/cucumber/cli/main.rb +35 -10
- data/lib/cucumber/cli/options.rb +33 -9
- data/lib/cucumber/cli/rerun_file.rb +29 -0
- data/lib/cucumber/filters/prepare_world.rb +2 -3
- data/lib/cucumber/formatter/backtrace_filter.rb +40 -0
- data/lib/cucumber/formatter/console.rb +2 -3
- data/lib/cucumber/formatter/cucumber.css +1 -0
- data/lib/cucumber/formatter/duration_extractor.rb +28 -0
- data/lib/cucumber/formatter/hook_query_visitor.rb +40 -0
- data/lib/cucumber/formatter/html.rb +16 -1
- data/lib/cucumber/formatter/json.rb +287 -8
- data/lib/cucumber/formatter/junit.rb +92 -143
- data/lib/cucumber/formatter/legacy_api/adapter.rb +18 -54
- data/lib/cucumber/formatter/legacy_api/ast.rb +13 -0
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +4 -0
- data/lib/cucumber/formatter/pretty.rb +2 -1
- data/lib/cucumber/formatter/progress.rb +20 -53
- data/lib/cucumber/formatter/rerun.rb +2 -1
- data/lib/cucumber/formatter/usage.rb +16 -22
- data/lib/cucumber/hooks.rb +18 -9
- data/lib/cucumber/multiline_argument/data_table.rb +40 -28
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/rb_support/rb_hook.rb +4 -0
- data/lib/cucumber/running_test_case.rb +13 -4
- data/lib/cucumber/runtime/after_hooks.rb +7 -6
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/step_hooks.rb +5 -4
- data/lib/cucumber/runtime/support_code.rb +6 -15
- data/lib/cucumber/step_match.rb +1 -1
- data/spec/cucumber/cli/configuration_spec.rb +32 -5
- data/spec/cucumber/cli/main_spec.rb +3 -3
- data/spec/cucumber/cli/options_spec.rb +60 -1
- data/spec/cucumber/cli/rerun_spec.rb +89 -0
- data/spec/cucumber/formatter/html_spec.rb +84 -5
- data/spec/cucumber/formatter/json_spec.rb +757 -0
- data/spec/cucumber/formatter/junit_spec.rb +5 -5
- data/spec/cucumber/formatter/legacy_api/adapter_spec.rb +69 -8
- data/spec/cucumber/formatter/pretty_spec.rb +96 -0
- data/spec/cucumber/formatter/progress_spec.rb +85 -1
- data/spec/cucumber/formatter/rerun_spec.rb +3 -3
- data/spec/cucumber/multiline_argument/data_table_spec.rb +89 -0
- data/spec/cucumber/running_test_case_spec.rb +57 -1
- metadata +70 -60
- data/lib/cucumber/formatter/gherkin_formatter_adapter.rb +0 -204
- data/lib/cucumber/formatter/gpretty.rb +0 -24
@@ -1,8 +1,9 @@
|
|
1
1
|
module Cucumber
|
2
2
|
class Runtime
|
3
3
|
class AfterHooks
|
4
|
-
def initialize(
|
5
|
-
@
|
4
|
+
def initialize(hooks, scenario)
|
5
|
+
@hooks = hooks
|
6
|
+
@scenario = scenario
|
6
7
|
end
|
7
8
|
|
8
9
|
def apply_to(test_case)
|
@@ -14,11 +15,11 @@ module Cucumber
|
|
14
15
|
private
|
15
16
|
|
16
17
|
def after_hooks(source)
|
17
|
-
@
|
18
|
-
|
19
|
-
|
18
|
+
@hooks.map do |hook|
|
19
|
+
action = ->(result) { hook.invoke('After', @scenario.with_result(result)) }
|
20
|
+
Hooks.after_hook(source, Hooks.location(hook), &action)
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
24
|
-
|
@@ -1,8 +1,11 @@
|
|
1
|
+
require 'cucumber/hooks'
|
2
|
+
|
1
3
|
module Cucumber
|
2
4
|
class Runtime
|
3
5
|
class BeforeHooks
|
4
|
-
def initialize(
|
5
|
-
@
|
6
|
+
def initialize(hooks, scenario)
|
7
|
+
@hooks = hooks
|
8
|
+
@scenario = scenario
|
6
9
|
end
|
7
10
|
|
8
11
|
def apply_to(test_case)
|
@@ -14,8 +17,9 @@ module Cucumber
|
|
14
17
|
private
|
15
18
|
|
16
19
|
def before_hooks(source)
|
17
|
-
@
|
18
|
-
|
20
|
+
@hooks.map do |hook|
|
21
|
+
action_block = ->(result) { hook.invoke('Before', @scenario.with_result(result)) }
|
22
|
+
Hooks.before_hook(source, Hooks.location(hook), &action_block)
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Cucumber
|
2
2
|
class Runtime
|
3
3
|
class StepHooks
|
4
|
-
def initialize(
|
5
|
-
@
|
4
|
+
def initialize(hooks)
|
5
|
+
@hooks = hooks
|
6
6
|
end
|
7
7
|
|
8
8
|
def apply(test_steps)
|
@@ -13,8 +13,9 @@ module Cucumber
|
|
13
13
|
|
14
14
|
private
|
15
15
|
def after_step_hooks(test_step)
|
16
|
-
@
|
17
|
-
|
16
|
+
@hooks.map do |hook|
|
17
|
+
action = ->(*args) { hook.invoke('AfterStep', args) }
|
18
|
+
Hooks.after_step_hook(test_step.source, Hooks.location(hook), &action)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -148,31 +148,22 @@ module Cucumber
|
|
148
148
|
def find_after_step_hooks(test_case)
|
149
149
|
ruby = load_programming_language('rb')
|
150
150
|
scenario = RunningTestCase.new(test_case)
|
151
|
-
|
152
|
-
|
153
|
-
->(*args) { hook.invoke('AfterStep', args) }
|
154
|
-
end
|
155
|
-
StepHooks.new action_blocks
|
151
|
+
hooks = ruby.hooks_for(:after_step, scenario)
|
152
|
+
StepHooks.new hooks
|
156
153
|
end
|
157
154
|
|
158
155
|
def apply_before_hooks(test_case)
|
159
156
|
ruby = load_programming_language('rb')
|
160
157
|
scenario = RunningTestCase.new(test_case)
|
161
|
-
|
162
|
-
|
163
|
-
->(result) { hook.invoke('Before', scenario.with_result(result)) }
|
164
|
-
end
|
165
|
-
BeforeHooks.new(action_blocks).apply_to(test_case)
|
158
|
+
hooks = ruby.hooks_for(:before, scenario)
|
159
|
+
BeforeHooks.new(hooks, scenario).apply_to(test_case)
|
166
160
|
end
|
167
161
|
|
168
162
|
def apply_after_hooks(test_case)
|
169
163
|
ruby = load_programming_language('rb')
|
170
164
|
scenario = RunningTestCase.new(test_case)
|
171
|
-
|
172
|
-
|
173
|
-
->(result) { hook.invoke('After', scenario.with_result(result)) }
|
174
|
-
end
|
175
|
-
AfterHooks.new(action_blocks).apply_to(test_case)
|
165
|
+
hooks = ruby.hooks_for(:after, scenario)
|
166
|
+
AfterHooks.new(hooks, scenario).apply_to(test_case)
|
176
167
|
end
|
177
168
|
|
178
169
|
def find_around_hooks(test_case)
|
data/lib/cucumber/step_match.rb
CHANGED
@@ -252,6 +252,12 @@ END_OF_MESSAGE
|
|
252
252
|
|
253
253
|
expect(config.options[:dry_run]).to be true
|
254
254
|
end
|
255
|
+
|
256
|
+
it "implies --no-duration with --dry-run option" do
|
257
|
+
config.parse!(%w{--dry-run})
|
258
|
+
|
259
|
+
expect(config.options[:duration]).to be false
|
260
|
+
end
|
255
261
|
|
256
262
|
it "accepts --no-source option" do
|
257
263
|
config.parse!(%w{--no-source})
|
@@ -265,11 +271,18 @@ END_OF_MESSAGE
|
|
265
271
|
expect(config.options[:snippets]).to be false
|
266
272
|
end
|
267
273
|
|
268
|
-
it "sets snippets and source to false with --quiet option" do
|
274
|
+
it "sets snippets and source and duration to false with --quiet option" do
|
269
275
|
config.parse!(%w{--quiet})
|
270
276
|
|
271
277
|
expect(config.options[:snippets]).to be false
|
272
278
|
expect(config.options[:source]).to be false
|
279
|
+
expect(config.options[:duration]).to be false
|
280
|
+
end
|
281
|
+
|
282
|
+
it "sets duration to false with --no-duration" do
|
283
|
+
config.parse!(%w{--no-duration})
|
284
|
+
|
285
|
+
expect(config.options[:duration]).to be false
|
273
286
|
end
|
274
287
|
|
275
288
|
it "accepts --verbose option" do
|
@@ -300,6 +313,11 @@ END_OF_MESSAGE
|
|
300
313
|
expect(-> { config.parse!(%w{--format pretty --format progress}) }).to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
301
314
|
end
|
302
315
|
|
316
|
+
it "does not accept multiple --format options when both use implicit STDOUT (using profile with no formatters)" do
|
317
|
+
given_cucumber_yml_defined_as({'default' => ['-q']})
|
318
|
+
expect(-> { config.parse!(%w{--format pretty --format progress}) }).to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
319
|
+
end
|
320
|
+
|
303
321
|
it "accepts same --format options with implicit STDOUT, and keep only one" do
|
304
322
|
config.parse!(%w{--format pretty --format pretty})
|
305
323
|
|
@@ -310,6 +328,11 @@ END_OF_MESSAGE
|
|
310
328
|
expect(-> { config.parse!(%w{--format pretty --out file1 --format progress --out file1}) }).to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
311
329
|
end
|
312
330
|
|
331
|
+
it "does not accept multiple --out streams pointing to the same place (one from profile, one from command line)" do
|
332
|
+
given_cucumber_yml_defined_as({'default' => ['-f','progress', '--out', 'file1']})
|
333
|
+
expect(-> { config.parse!(%w{--format pretty --out file1}) }).to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
334
|
+
end
|
335
|
+
|
313
336
|
it "associates --out to previous --format" do
|
314
337
|
config.parse!(%w{--format progress --out file1 --format profile --out file2})
|
315
338
|
|
@@ -402,15 +425,19 @@ END_OF_MESSAGE
|
|
402
425
|
allow(File).to receive(:directory?).and_return(false)
|
403
426
|
allow(File).to receive(:file?).and_return(true)
|
404
427
|
allow(IO).to receive(:read).and_return(
|
405
|
-
"cucumber.feature:1:3
|
406
|
-
|
428
|
+
"cucumber.feature:1:3\ncucumber.feature:5 cucumber.feature:10\n"\
|
429
|
+
"domain folder/different cuke.feature:134 domain folder/cuke.feature:1\n"\
|
430
|
+
"domain folder/different cuke.feature:4:5 bar.feature")
|
407
431
|
config.parse!(%w{@rerun.txt})
|
408
432
|
|
409
433
|
expect(config.feature_files).to eq [
|
410
434
|
"cucumber.feature:1:3",
|
411
|
-
"cucumber
|
435
|
+
"cucumber.feature:5",
|
436
|
+
"cucumber.feature:10",
|
437
|
+
"domain folder/different cuke.feature:134",
|
412
438
|
"domain folder/cuke.feature:1",
|
413
|
-
"domain folder/different cuke:4:5"
|
439
|
+
"domain folder/different cuke.feature:4:5",
|
440
|
+
"bar.feature"]
|
414
441
|
end
|
415
442
|
|
416
443
|
it "should allow specifying environment variables on the command line" do
|
@@ -51,7 +51,7 @@ module Cucumber
|
|
51
51
|
Cucumber.wants_to_quit = false
|
52
52
|
end
|
53
53
|
|
54
|
-
it "
|
54
|
+
it "exits with error code" do
|
55
55
|
results = double('results', :failure? => false)
|
56
56
|
|
57
57
|
allow_any_instance_of(Runtime).to receive(:run!)
|
@@ -59,7 +59,7 @@ module Cucumber
|
|
59
59
|
|
60
60
|
Cucumber.wants_to_quit = true
|
61
61
|
|
62
|
-
expect(kernel).to receive(:exit).with(
|
62
|
+
expect(kernel).to receive(:exit).with(2)
|
63
63
|
|
64
64
|
subject.execute!
|
65
65
|
end
|
@@ -93,7 +93,7 @@ module Cucumber
|
|
93
93
|
|
94
94
|
allow(Configuration).to receive(:new) { configuration }
|
95
95
|
allow(configuration).to receive(:parse!).and_raise(exception_klass.new("error message"))
|
96
|
-
allow(kernel).to receive(:exit).with(
|
96
|
+
allow(kernel).to receive(:exit).with(2)
|
97
97
|
|
98
98
|
subject.execute!
|
99
99
|
|
@@ -59,7 +59,7 @@ module Cucumber
|
|
59
59
|
context "with LANG specified as 'help'" do
|
60
60
|
include RSpec::WorkInProgress
|
61
61
|
|
62
|
-
it "lists all known
|
62
|
+
it "lists all known languages" do
|
63
63
|
when_parsing '--i18n help' do
|
64
64
|
expect(Kernel).to receive(:exit)
|
65
65
|
end
|
@@ -69,6 +69,28 @@ module Cucumber
|
|
69
69
|
when_parsing('--i18n help') { expect(Kernel).to receive(:exit) }
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
context "with invalid LANG" do
|
74
|
+
include RSpec::WorkInProgress
|
75
|
+
|
76
|
+
it "exits" do
|
77
|
+
when_parsing '--i18n foo' do
|
78
|
+
expect(Kernel).to receive(:exit)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "says the language was invalid" do
|
83
|
+
after_parsing '--i18n foo' do
|
84
|
+
expect(@output_stream.string).to include("Invalid language 'foo'. Available languages are:")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it "displays the language table" do
|
89
|
+
after_parsing '--i18n foo' do
|
90
|
+
expect(@output_stream.string).to include(Gherkin::I18n.language_table);
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
72
94
|
end
|
73
95
|
|
74
96
|
context '-f FORMAT or --format FORMAT' do
|
@@ -88,6 +110,35 @@ module Cucumber
|
|
88
110
|
end
|
89
111
|
end
|
90
112
|
|
113
|
+
context 'handling multiple formatters' do
|
114
|
+
it "catches multiple command line formatters using the same stream" do
|
115
|
+
expect{ options.parse!(prepare_args('-f pretty -f progress')) }.to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "catches multiple profile formatters using the same stream" do
|
119
|
+
given_cucumber_yml_defined_as({'default' => '-f progress -f pretty'})
|
120
|
+
options = Options.new(output_stream, error_stream, :default_profile => 'default')
|
121
|
+
|
122
|
+
expect{ options.parse!(%w{}) }.to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
123
|
+
end
|
124
|
+
|
125
|
+
it "profiles does not affect the catching of multiple command line formatters using the same stream" do
|
126
|
+
given_cucumber_yml_defined_as({'default' => '-q'})
|
127
|
+
options = Options.new(output_stream, error_stream, :default_profile => 'default')
|
128
|
+
|
129
|
+
expect{ options.parse!(%w{-f progress -f pretty}) }.to raise_error("All but one formatter must use --out, only one can print to each stream (or STDOUT)")
|
130
|
+
end
|
131
|
+
|
132
|
+
it "merges profile formatters and command line formatters" do
|
133
|
+
given_cucumber_yml_defined_as({'default' => '-f junit -o result.xml'})
|
134
|
+
options = Options.new(output_stream, error_stream, :default_profile => 'default')
|
135
|
+
|
136
|
+
options.parse!(%w{-f pretty})
|
137
|
+
|
138
|
+
expect(options[:formats]).to eq [['pretty', output_stream], ["junit", "result.xml"]]
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
91
142
|
context '-t TAGS --tags TAGS' do
|
92
143
|
it "designates tags prefixed with ~ as tags to be excluded" do
|
93
144
|
after_parsing('--tags ~@foo,@bar') { expect(options[:tag_expressions]).to eq ['~@foo,@bar'] }
|
@@ -238,6 +289,14 @@ module Cucumber
|
|
238
289
|
|
239
290
|
expect(options[:snippets]).to be false
|
240
291
|
expect(options[:source]).to be false
|
292
|
+
expect(options[:duration]).to be false
|
293
|
+
end
|
294
|
+
|
295
|
+
it "uses --no-duration when defined in the profile" do
|
296
|
+
given_cucumber_yml_defined_as('foo' => '--no-duration')
|
297
|
+
options.parse!(%w[-p foo])
|
298
|
+
|
299
|
+
expect(options[:duration]).to be false
|
241
300
|
end
|
242
301
|
end
|
243
302
|
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Cli
|
5
|
+
describe RerunFile do
|
6
|
+
|
7
|
+
let(:rerun_file) { RerunFile.new('@rerun.txt') }
|
8
|
+
|
9
|
+
it "expects rerun files to have a leading @" do
|
10
|
+
allow(File).to receive(:file?) { true }
|
11
|
+
expect(RerunFile.can_read?('rerun.txt')).to eq false
|
12
|
+
expect(RerunFile.can_read?('@rerun.txt')).to eq true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "does not treat directories as rerun files" do
|
16
|
+
allow(File).to receive(:file?) { false }
|
17
|
+
expect(RerunFile.can_read?('@rerun.txt')).to eq false
|
18
|
+
end
|
19
|
+
|
20
|
+
it "removes leading @ character from filename" do
|
21
|
+
expect(rerun_file.path).to eq 'rerun.txt'
|
22
|
+
end
|
23
|
+
|
24
|
+
context "rerun file containing single feature" do
|
25
|
+
before(:each) do
|
26
|
+
allow(IO).to receive(:read).and_return("cucumber.feature")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "produces an array containing a single feature file path" do
|
30
|
+
expect(rerun_file.features).to eq %w(cucumber.feature)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "contains multiple features on multiple lines" do
|
35
|
+
before(:each) do
|
36
|
+
allow(IO).to receive(:read).and_return("cucumber.feature\nfoo.feature")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "produces an array containing multiple feature file paths" do
|
40
|
+
expect(rerun_file.features).to eq %w(cucumber.feature foo.feature)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "contains multiple features on same line" do
|
45
|
+
before(:each) do
|
46
|
+
allow(IO).to receive(:read).and_return("cucumber.feature foo.feature")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "produces an array containing multiple feature file paths" do
|
50
|
+
expect(rerun_file.features).to eq %w(cucumber.feature foo.feature)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "contains multiple scenarios on same line" do
|
55
|
+
before(:each) do
|
56
|
+
allow(IO).to receive(:read).and_return("cucumber.feature:8 foo.feature:8:16")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "produces an array containing multiple feature file paths with scenario lines" do
|
60
|
+
expect(rerun_file.features).to eq %w(cucumber.feature:8 foo.feature:8:16)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "contains features with spaces in file names" do
|
65
|
+
before(:each) do
|
66
|
+
allow(IO).to receive(:read).and_return("cucumber test.feature:8 foo.feature:8:16")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "produces an array containing multiple feature file paths with scenario lines" do
|
70
|
+
expect(rerun_file.features).to eq ['cucumber test.feature:8', 'foo.feature:8:16']
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "contains features and scenarios with and without spaces same line and across lines" do
|
75
|
+
before(:each) do
|
76
|
+
allow(IO).to receive(:read).and_return(
|
77
|
+
"cucumber.feature:1:3\ncucumber.feature:5 cucumber.feature:10\n"\
|
78
|
+
"cucumber space.feature:134 domain folder/cuke.feature\n")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "produces an array containing multiple feature file paths with scenario lines" do
|
82
|
+
feature_files = ['cucumber.feature:1:3', 'cucumber.feature:5', 'cucumber.feature:10',
|
83
|
+
'cucumber space.feature:134', 'domain folder/cuke.feature']
|
84
|
+
expect(rerun_file.features).to eq feature_files
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -40,7 +40,7 @@ module Cucumber
|
|
40
40
|
|
41
41
|
describe "with a step that embeds a snapshot" do
|
42
42
|
define_steps do
|
43
|
-
Given(/snap/) {
|
43
|
+
Given(/snap/) {
|
44
44
|
RSpec::Mocks.allow_message(File, :file?) { true }
|
45
45
|
embed('out/snapshot.jpeg', 'image/jpeg')
|
46
46
|
}
|
@@ -87,7 +87,25 @@ module Cucumber
|
|
87
87
|
|
88
88
|
it { expect(@out.string).to match(/^\<!DOCTYPE/) }
|
89
89
|
it { expect(@out.string).to match(/\<\/html\>$/) }
|
90
|
-
|
90
|
+
|
91
|
+
it "nests the comment within the feature" do
|
92
|
+
expect(@doc).to have_css_node('.feature .comment', /Healthy/)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "properly closes the comment" do
|
96
|
+
expect(@out.string).to match(%r{<pre class="comment"># Healthy<br/></pre>})
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "with a comment at scenario level" do
|
101
|
+
define_feature <<-FEATURE
|
102
|
+
Feature: Foo
|
103
|
+
# Healthy Scenario
|
104
|
+
Scenario:
|
105
|
+
Given passing
|
106
|
+
FEATURE
|
107
|
+
|
108
|
+
it { expect(@doc).to have_css_node('.scenario .comment', /Healthy Scenario/) }
|
91
109
|
end
|
92
110
|
|
93
111
|
describe "with a tag" do
|
@@ -273,9 +291,49 @@ module Cucumber
|
|
273
291
|
it { expect(@doc).not_to have_css_node('.feature .scenario .backtrace', //) }
|
274
292
|
end
|
275
293
|
|
294
|
+
context "with a before hook that fails" do
|
295
|
+
describe "in a scenario" do
|
296
|
+
define_steps do
|
297
|
+
Before { raise 'eek' }
|
298
|
+
Given(/yay/) {}
|
299
|
+
end
|
300
|
+
|
301
|
+
define_feature(<<-FEATURE)
|
302
|
+
Feature: shouting
|
303
|
+
Scenario:
|
304
|
+
Given yay
|
305
|
+
FEATURE
|
306
|
+
|
307
|
+
it { expect(@out.string).to include('makeRed(\'scenario_1\')') }
|
308
|
+
it { expect(@doc).not_to have_css_node('.feature .scenario .step.failed', //) }
|
309
|
+
it { expect(@doc).to have_css_node('.feature .scenario .step.skipped', /yay/) }
|
310
|
+
end
|
311
|
+
|
312
|
+
describe "in a scenario outline" do
|
313
|
+
define_steps do
|
314
|
+
Before { raise 'eek' }
|
315
|
+
Given(/yay/) {}
|
316
|
+
end
|
317
|
+
|
318
|
+
define_feature(<<-FEATURE)
|
319
|
+
Feature: shouting
|
320
|
+
Scenario Outline:
|
321
|
+
Given <step>
|
322
|
+
Examples:
|
323
|
+
| step |
|
324
|
+
| yay |
|
325
|
+
FEATURE
|
326
|
+
|
327
|
+
it { expect(@out.string).to include('makeRed(\'scenario_1\')') }
|
328
|
+
it { expect(@doc).not_to have_css_node('.feature .scenario .step.failed', //) }
|
329
|
+
it { expect(@doc).to have_css_node('.feature .scenario .step.skipped', /yay/) }
|
330
|
+
end
|
331
|
+
|
332
|
+
end
|
333
|
+
|
276
334
|
describe "with a step that embeds a snapshot" do
|
277
335
|
define_steps do
|
278
|
-
Given(/snap/) {
|
336
|
+
Given(/snap/) {
|
279
337
|
RSpec::Mocks.allow_message(File, :file?) { true }
|
280
338
|
embed('snapshot.jpeg', 'image/jpeg')
|
281
339
|
}
|
@@ -289,7 +347,7 @@ module Cucumber
|
|
289
347
|
|
290
348
|
it { expect(@doc.css('.embed img').first.attributes['src'].to_s).to eq "snapshot.jpeg" }
|
291
349
|
end
|
292
|
-
|
350
|
+
|
293
351
|
describe "with a step that embeds a text" do
|
294
352
|
define_steps do
|
295
353
|
Given(/log/) { embed('log.txt', 'text/plain') }
|
@@ -431,7 +489,7 @@ module Cucumber
|
|
431
489
|
let(:runtime) { Runtime.new({:expand => true})}
|
432
490
|
before(:each) do
|
433
491
|
@out = StringIO.new
|
434
|
-
@formatter = Html.new(runtime, @out, {})
|
492
|
+
@formatter = Html.new(runtime, @out, {:expand => true})
|
435
493
|
run_defined_feature
|
436
494
|
@doc = Nokogiri.HTML(@out.string)
|
437
495
|
end
|
@@ -453,6 +511,27 @@ module Cucumber
|
|
453
511
|
|
454
512
|
it { expect(@doc.css('pre').map { |pre| /^(Given|Then|When)/.match(pre.text)[1] }).to eq ["Given", "Given"] }
|
455
513
|
end
|
514
|
+
|
515
|
+
describe "with a scenario outline and a before hook that fails" do
|
516
|
+
define_steps do
|
517
|
+
Before { raise 'eek' }
|
518
|
+
Given(/yay/) {}
|
519
|
+
end
|
520
|
+
|
521
|
+
define_feature(<<-FEATURE)
|
522
|
+
Feature: shouting
|
523
|
+
Scenario Outline:
|
524
|
+
Given <step>
|
525
|
+
Examples:
|
526
|
+
| step |
|
527
|
+
| yay |
|
528
|
+
FEATURE
|
529
|
+
|
530
|
+
it { expect(@out.string).to include('makeRed(\'scenario_1\')') }
|
531
|
+
it { expect(@out.string).to include('makeRed(\'scenario_1_1\')') }
|
532
|
+
it { expect(@doc).not_to have_css_node('.feature .scenario .step.failed', //) }
|
533
|
+
it { expect(@doc).to have_css_node('.feature .scenario .step.skipped', /yay/) }
|
534
|
+
end
|
456
535
|
end
|
457
536
|
end
|
458
537
|
end
|