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.
- 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
@@ -0,0 +1,757 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cucumber/formatter/spec_helper'
|
3
|
+
require 'cucumber/formatter/json'
|
4
|
+
require 'cucumber/cli/options'
|
5
|
+
require 'multi_json'
|
6
|
+
|
7
|
+
module Cucumber
|
8
|
+
module Formatter
|
9
|
+
describe Json do
|
10
|
+
extend SpecHelperDsl
|
11
|
+
include SpecHelper
|
12
|
+
|
13
|
+
context "Given a single feature" do
|
14
|
+
before(:each) do
|
15
|
+
@out = StringIO.new
|
16
|
+
@formatter = Json.new(runtime, @out, {})
|
17
|
+
run_defined_feature
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "with a scenario with no steps" do
|
21
|
+
define_feature <<-FEATURE
|
22
|
+
Feature: Banana party
|
23
|
+
|
24
|
+
Scenario: Monkey eats bananas
|
25
|
+
FEATURE
|
26
|
+
|
27
|
+
it "outputs the json data" do
|
28
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
29
|
+
[{"id": "banana-party",
|
30
|
+
"uri": "spec.feature",
|
31
|
+
"keyword": "Feature",
|
32
|
+
"name": "Banana party",
|
33
|
+
"line": 1,
|
34
|
+
"description": "",
|
35
|
+
"elements":
|
36
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
37
|
+
"keyword": "Scenario",
|
38
|
+
"name": "Monkey eats bananas",
|
39
|
+
"line": 3,
|
40
|
+
"description": "",
|
41
|
+
"type": "scenario"}]}]})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "with a scenario with an undefined step" do
|
46
|
+
define_feature <<-FEATURE
|
47
|
+
Feature: Banana party
|
48
|
+
|
49
|
+
Scenario: Monkey eats bananas
|
50
|
+
Given there are bananas
|
51
|
+
FEATURE
|
52
|
+
|
53
|
+
it "outputs the json data" do
|
54
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
55
|
+
[{"id": "banana-party",
|
56
|
+
"uri": "spec.feature",
|
57
|
+
"keyword": "Feature",
|
58
|
+
"name": "Banana party",
|
59
|
+
"line": 1,
|
60
|
+
"description": "",
|
61
|
+
"elements":
|
62
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
63
|
+
"keyword": "Scenario",
|
64
|
+
"name": "Monkey eats bananas",
|
65
|
+
"line": 3,
|
66
|
+
"description": "",
|
67
|
+
"type": "scenario",
|
68
|
+
"steps":
|
69
|
+
[{"keyword": "Given ",
|
70
|
+
"name": "there are bananas",
|
71
|
+
"line": 4,
|
72
|
+
"match": {"location": "spec.feature:4"},
|
73
|
+
"result": {"status": "undefined"}}]}]}]})
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "with a scenario with a passed step" do
|
78
|
+
define_feature <<-FEATURE
|
79
|
+
Feature: Banana party
|
80
|
+
|
81
|
+
Scenario: Monkey eats bananas
|
82
|
+
Given there are bananas
|
83
|
+
FEATURE
|
84
|
+
|
85
|
+
define_steps do
|
86
|
+
Given(/^there are bananas$/) {}
|
87
|
+
end
|
88
|
+
|
89
|
+
it "outputs the json data" do
|
90
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
91
|
+
[{"id": "banana-party",
|
92
|
+
"uri": "spec.feature",
|
93
|
+
"keyword": "Feature",
|
94
|
+
"name": "Banana party",
|
95
|
+
"line": 1,
|
96
|
+
"description": "",
|
97
|
+
"elements":
|
98
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
99
|
+
"keyword": "Scenario",
|
100
|
+
"name": "Monkey eats bananas",
|
101
|
+
"line": 3,
|
102
|
+
"description": "",
|
103
|
+
"type": "scenario",
|
104
|
+
"steps":
|
105
|
+
[{"keyword": "Given ",
|
106
|
+
"name": "there are bananas",
|
107
|
+
"line": 4,
|
108
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:86"},
|
109
|
+
"result": {"status": "passed",
|
110
|
+
"duration": 1}}]}]}]})
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "with a scenario with a failed step" do
|
115
|
+
define_feature <<-FEATURE
|
116
|
+
Feature: Banana party
|
117
|
+
|
118
|
+
Scenario: Monkey eats bananas
|
119
|
+
Given there are bananas
|
120
|
+
FEATURE
|
121
|
+
|
122
|
+
define_steps do
|
123
|
+
Given(/^there are bananas$/) { raise "no bananas" }
|
124
|
+
end
|
125
|
+
|
126
|
+
it "outputs the json data" do
|
127
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
128
|
+
[{"id": "banana-party",
|
129
|
+
"uri": "spec.feature",
|
130
|
+
"keyword": "Feature",
|
131
|
+
"name": "Banana party",
|
132
|
+
"line": 1,
|
133
|
+
"description": "",
|
134
|
+
"elements":
|
135
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
136
|
+
"keyword": "Scenario",
|
137
|
+
"name": "Monkey eats bananas",
|
138
|
+
"line": 3,
|
139
|
+
"description": "",
|
140
|
+
"type": "scenario",
|
141
|
+
"steps":
|
142
|
+
[{"keyword": "Given ",
|
143
|
+
"name": "there are bananas",
|
144
|
+
"line": 4,
|
145
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:123"},
|
146
|
+
"result": {"status": "failed",
|
147
|
+
"error_message": "no bananas (RuntimeError)\\n./spec/cucumber/formatter/json_spec.rb:123:in `/^there are bananas$/'\\nspec.feature:4:in `Given there are bananas'",
|
148
|
+
"duration": 1}}]}]}]})
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "with a scenario with a pending step" do
|
153
|
+
define_feature <<-FEATURE
|
154
|
+
Feature: Banana party
|
155
|
+
|
156
|
+
Scenario: Monkey eats bananas
|
157
|
+
Given there are bananas
|
158
|
+
FEATURE
|
159
|
+
|
160
|
+
define_steps do
|
161
|
+
Given(/^there are bananas$/) { pending }
|
162
|
+
end
|
163
|
+
|
164
|
+
it "outputs the json data" do
|
165
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
166
|
+
[{"id": "banana-party",
|
167
|
+
"uri": "spec.feature",
|
168
|
+
"keyword": "Feature",
|
169
|
+
"name": "Banana party",
|
170
|
+
"line": 1,
|
171
|
+
"description": "",
|
172
|
+
"elements":
|
173
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
174
|
+
"keyword": "Scenario",
|
175
|
+
"name": "Monkey eats bananas",
|
176
|
+
"line": 3,
|
177
|
+
"description": "",
|
178
|
+
"type": "scenario",
|
179
|
+
"steps":
|
180
|
+
[{"keyword": "Given ",
|
181
|
+
"name": "there are bananas",
|
182
|
+
"line": 4,
|
183
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:161"},
|
184
|
+
"result": {"status": "pending",
|
185
|
+
"error_message": "TODO (Cucumber::Pending)\\n./spec/cucumber/formatter/json_spec.rb:161:in `/^there are bananas$/'\\nspec.feature:4:in `Given there are bananas'",
|
186
|
+
"duration": 1}}]}]}]})
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "with a scenario outline with one example" do
|
191
|
+
define_feature <<-FEATURE
|
192
|
+
Feature: Banana party
|
193
|
+
|
194
|
+
Scenario Outline: Monkey eats bananas
|
195
|
+
Given there are <fruit>
|
196
|
+
|
197
|
+
Examples: Fruit Table
|
198
|
+
| fruit |
|
199
|
+
| bananas |
|
200
|
+
FEATURE
|
201
|
+
|
202
|
+
define_steps do
|
203
|
+
Given(/^there are bananas$/) {}
|
204
|
+
end
|
205
|
+
|
206
|
+
it "outputs the json data" do
|
207
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
208
|
+
[{"id": "banana-party",
|
209
|
+
"uri": "spec.feature",
|
210
|
+
"keyword": "Feature",
|
211
|
+
"name": "Banana party",
|
212
|
+
"line": 1,
|
213
|
+
"description": "",
|
214
|
+
"elements":
|
215
|
+
[{"id": "banana-party;monkey-eats-bananas;fruit-table;2",
|
216
|
+
"keyword": "Scenario Outline",
|
217
|
+
"name": "Monkey eats bananas",
|
218
|
+
"line": 8,
|
219
|
+
"description": "",
|
220
|
+
"type": "scenario",
|
221
|
+
"steps":
|
222
|
+
[{"keyword": "Given ",
|
223
|
+
"name": "there are bananas",
|
224
|
+
"line": 8,
|
225
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:203"},
|
226
|
+
"result": {"status": "passed",
|
227
|
+
"duration": 1}}]}]}]})
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe "with tags in the feature file" do
|
232
|
+
define_feature <<-FEATURE
|
233
|
+
@f
|
234
|
+
Feature: Banana party
|
235
|
+
|
236
|
+
@s
|
237
|
+
Scenario: Monkey eats bananas
|
238
|
+
Given there are bananas
|
239
|
+
|
240
|
+
@so
|
241
|
+
Scenario Outline: Monkey eats bananas
|
242
|
+
Given there are <fruit>
|
243
|
+
|
244
|
+
@ex
|
245
|
+
Examples: Fruit Table
|
246
|
+
| fruit |
|
247
|
+
| bananas |
|
248
|
+
FEATURE
|
249
|
+
|
250
|
+
define_steps do
|
251
|
+
Given(/^there are bananas$/) {}
|
252
|
+
end
|
253
|
+
|
254
|
+
it "the tags are included in the json data" do
|
255
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
256
|
+
[{"id": "banana-party",
|
257
|
+
"uri": "spec.feature",
|
258
|
+
"keyword": "Feature",
|
259
|
+
"name": "Banana party",
|
260
|
+
"line": 2,
|
261
|
+
"description": "",
|
262
|
+
"tags": [{"name": "@f",
|
263
|
+
"line": 1}],
|
264
|
+
"elements":
|
265
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
266
|
+
"keyword": "Scenario",
|
267
|
+
"name": "Monkey eats bananas",
|
268
|
+
"line": 5,
|
269
|
+
"description": "",
|
270
|
+
"tags": [{"name": "@f",
|
271
|
+
"line": 1},
|
272
|
+
{"name": "@s",
|
273
|
+
"line": 4}],
|
274
|
+
"type": "scenario",
|
275
|
+
"steps":
|
276
|
+
[{"keyword": "Given ",
|
277
|
+
"name": "there are bananas",
|
278
|
+
"line": 6,
|
279
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:251"},
|
280
|
+
"result": {"status": "passed",
|
281
|
+
"duration": 1}}]},
|
282
|
+
{"id": "banana-party;monkey-eats-bananas;fruit-table;2",
|
283
|
+
"keyword": "Scenario Outline",
|
284
|
+
"name": "Monkey eats bananas",
|
285
|
+
"line": 15,
|
286
|
+
"description": "",
|
287
|
+
"tags": [{"name": "@f",
|
288
|
+
"line": 1},
|
289
|
+
{"name": "@so",
|
290
|
+
"line": 8},
|
291
|
+
{"name": "@ex",
|
292
|
+
"line": 12}],
|
293
|
+
"type": "scenario",
|
294
|
+
"steps":
|
295
|
+
[{"keyword": "Given ",
|
296
|
+
"name": "there are bananas",
|
297
|
+
"line": 15,
|
298
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:251"},
|
299
|
+
"result": {"status": "passed",
|
300
|
+
"duration": 1}}]}]}]})
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe "with comments in the feature file" do
|
305
|
+
define_feature <<-FEATURE
|
306
|
+
#feature comment
|
307
|
+
Feature: Banana party
|
308
|
+
|
309
|
+
#background comment
|
310
|
+
Background: There are bananas
|
311
|
+
Given there are bananas
|
312
|
+
|
313
|
+
#scenario comment
|
314
|
+
Scenario: Monkey eats bananas
|
315
|
+
#step comment1
|
316
|
+
Then the monkey eats bananas
|
317
|
+
|
318
|
+
#scenario outline comment
|
319
|
+
Scenario Outline: Monkey eats bananas
|
320
|
+
#step comment2
|
321
|
+
Then the monkey eats <fruit>
|
322
|
+
|
323
|
+
#examples table comment
|
324
|
+
Examples: Fruit Table
|
325
|
+
| fruit |
|
326
|
+
#examples table row comment
|
327
|
+
| bananas |
|
328
|
+
FEATURE
|
329
|
+
|
330
|
+
define_steps do
|
331
|
+
Given(/^there are bananas$/) {}
|
332
|
+
Then(/^the monkey eats bananas$/) {}
|
333
|
+
end
|
334
|
+
|
335
|
+
it "the comments are included in the json data" do
|
336
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
337
|
+
[{"id": "banana-party",
|
338
|
+
"uri": "spec.feature",
|
339
|
+
"keyword": "Feature",
|
340
|
+
"name": "Banana party",
|
341
|
+
"line": 2,
|
342
|
+
"description": "",
|
343
|
+
"comments": [{"value": "#feature comment",
|
344
|
+
"line": 1}],
|
345
|
+
"elements":
|
346
|
+
[{"keyword": "Background",
|
347
|
+
"name": "There are bananas",
|
348
|
+
"line": 5,
|
349
|
+
"description": "",
|
350
|
+
"comments": [{"value": "#background comment",
|
351
|
+
"line": 4}],
|
352
|
+
"type": "background",
|
353
|
+
"steps":
|
354
|
+
[{"keyword": "Given ",
|
355
|
+
"name": "there are bananas",
|
356
|
+
"line": 6,
|
357
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:331"},
|
358
|
+
"result": {"status": "passed",
|
359
|
+
"duration": 1}}]},
|
360
|
+
{"id": "banana-party;monkey-eats-bananas",
|
361
|
+
"keyword": "Scenario",
|
362
|
+
"name": "Monkey eats bananas",
|
363
|
+
"line": 9,
|
364
|
+
"description": "",
|
365
|
+
"comments": [{"value": "#scenario comment",
|
366
|
+
"line": 8}],
|
367
|
+
"type": "scenario",
|
368
|
+
"steps":
|
369
|
+
[{"keyword": "Then ",
|
370
|
+
"name": "the monkey eats bananas",
|
371
|
+
"line": 11,
|
372
|
+
"comments": [{"value": "#step comment1",
|
373
|
+
"line": 10}],
|
374
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:332"},
|
375
|
+
"result": {"status": "passed",
|
376
|
+
"duration": 1}}]},
|
377
|
+
{"keyword": "Background",
|
378
|
+
"name": "There are bananas",
|
379
|
+
"line": 5,
|
380
|
+
"description": "",
|
381
|
+
"comments": [{"value": "#background comment",
|
382
|
+
"line": 4}],
|
383
|
+
"type": "background",
|
384
|
+
"steps":
|
385
|
+
[{"keyword": "Given ",
|
386
|
+
"name": "there are bananas",
|
387
|
+
"line": 6,
|
388
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:331"},
|
389
|
+
"result": {"status": "passed",
|
390
|
+
"duration": 1}}]},
|
391
|
+
{"id": "banana-party;monkey-eats-bananas;fruit-table;2",
|
392
|
+
"keyword": "Scenario Outline",
|
393
|
+
"name": "Monkey eats bananas",
|
394
|
+
"line": 22,
|
395
|
+
"description": "",
|
396
|
+
"comments": [{"value": "#scenario outline comment",
|
397
|
+
"line": 13},
|
398
|
+
{"value": "#examples table comment",
|
399
|
+
"line": 18},
|
400
|
+
{"value": "#examples table row comment",
|
401
|
+
"line": 21}],
|
402
|
+
"type": "scenario",
|
403
|
+
"steps":
|
404
|
+
[{"keyword": "Then ",
|
405
|
+
"name": "the monkey eats bananas",
|
406
|
+
"line": 22,
|
407
|
+
"comments": [{"value": "#step comment2",
|
408
|
+
"line": 15}],
|
409
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:332"},
|
410
|
+
"result": {"status": "passed",
|
411
|
+
"duration": 1}}]}]}]})
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "with a scenario with a step with a doc string" do
|
416
|
+
define_feature <<-FEATURE
|
417
|
+
Feature: Banana party
|
418
|
+
|
419
|
+
Scenario: Monkey eats bananas
|
420
|
+
Given there are bananas
|
421
|
+
"""
|
422
|
+
the doc string
|
423
|
+
"""
|
424
|
+
FEATURE
|
425
|
+
|
426
|
+
define_steps do
|
427
|
+
Given(/^there are bananas$/) { |s| s }
|
428
|
+
end
|
429
|
+
|
430
|
+
it "includes the doc string in the json data" do
|
431
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
432
|
+
[{"id": "banana-party",
|
433
|
+
"uri": "spec.feature",
|
434
|
+
"keyword": "Feature",
|
435
|
+
"name": "Banana party",
|
436
|
+
"line": 1,
|
437
|
+
"description": "",
|
438
|
+
"elements":
|
439
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
440
|
+
"keyword": "Scenario",
|
441
|
+
"name": "Monkey eats bananas",
|
442
|
+
"line": 3,
|
443
|
+
"description": "",
|
444
|
+
"type": "scenario",
|
445
|
+
"steps":
|
446
|
+
[{"keyword": "Given ",
|
447
|
+
"name": "there are bananas",
|
448
|
+
"line": 4,
|
449
|
+
"doc_string": {"value": "the doc string",
|
450
|
+
"content_type": "",
|
451
|
+
"line": 5},
|
452
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:427"},
|
453
|
+
"result": {"status": "passed",
|
454
|
+
"duration": 1}}]}]}]})
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
describe "with a scenario with a step that use puts" do
|
459
|
+
define_feature <<-FEATURE
|
460
|
+
Feature: Banana party
|
461
|
+
|
462
|
+
Scenario: Monkey eats bananas
|
463
|
+
Given there are bananas
|
464
|
+
FEATURE
|
465
|
+
|
466
|
+
define_steps do
|
467
|
+
Given(/^there are bananas$/) { puts "from step" }
|
468
|
+
end
|
469
|
+
|
470
|
+
it "includes the output from the step in the json data" do
|
471
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
472
|
+
[{"id": "banana-party",
|
473
|
+
"uri": "spec.feature",
|
474
|
+
"keyword": "Feature",
|
475
|
+
"name": "Banana party",
|
476
|
+
"line": 1,
|
477
|
+
"description": "",
|
478
|
+
"elements":
|
479
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
480
|
+
"keyword": "Scenario",
|
481
|
+
"name": "Monkey eats bananas",
|
482
|
+
"line": 3,
|
483
|
+
"description": "",
|
484
|
+
"type": "scenario",
|
485
|
+
"steps":
|
486
|
+
[{"keyword": "Given ",
|
487
|
+
"name": "there are bananas",
|
488
|
+
"line": 4,
|
489
|
+
"output": ["from step"],
|
490
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:467"},
|
491
|
+
"result": {"status": "passed",
|
492
|
+
"duration": 1}}]}]}]})
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
describe "with a background" do
|
497
|
+
define_feature <<-FEATURE
|
498
|
+
Feature: Banana party
|
499
|
+
|
500
|
+
Background: There are bananas
|
501
|
+
Given there are bananas
|
502
|
+
|
503
|
+
Scenario: Monkey eats bananas
|
504
|
+
Then the monkey eats bananas
|
505
|
+
|
506
|
+
Scenario: Monkey eats more bananas
|
507
|
+
Then the monkey eats more bananas
|
508
|
+
FEATURE
|
509
|
+
|
510
|
+
it "includes the background in the json data each time it is executed" do
|
511
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
512
|
+
[{"id": "banana-party",
|
513
|
+
"uri": "spec.feature",
|
514
|
+
"keyword": "Feature",
|
515
|
+
"name": "Banana party",
|
516
|
+
"line": 1,
|
517
|
+
"description": "",
|
518
|
+
"elements":
|
519
|
+
[{"keyword": "Background",
|
520
|
+
"name": "There are bananas",
|
521
|
+
"line": 3,
|
522
|
+
"description": "",
|
523
|
+
"type": "background",
|
524
|
+
"steps":
|
525
|
+
[{"keyword": "Given ",
|
526
|
+
"name": "there are bananas",
|
527
|
+
"line": 4,
|
528
|
+
"match": {"location": "spec.feature:4"},
|
529
|
+
"result": {"status": "undefined"}}]},
|
530
|
+
{"id": "banana-party;monkey-eats-bananas",
|
531
|
+
"keyword": "Scenario",
|
532
|
+
"name": "Monkey eats bananas",
|
533
|
+
"line": 6,
|
534
|
+
"description": "",
|
535
|
+
"type": "scenario",
|
536
|
+
"steps":
|
537
|
+
[{"keyword": "Then ",
|
538
|
+
"name": "the monkey eats bananas",
|
539
|
+
"line": 7,
|
540
|
+
"match": {"location": "spec.feature:7"},
|
541
|
+
"result": {"status": "undefined"}}]},
|
542
|
+
{"keyword": "Background",
|
543
|
+
"name": "There are bananas",
|
544
|
+
"line": 3,
|
545
|
+
"description": "",
|
546
|
+
"type": "background",
|
547
|
+
"steps":
|
548
|
+
[{"keyword": "Given ",
|
549
|
+
"name": "there are bananas",
|
550
|
+
"line": 4,
|
551
|
+
"match": {"location": "spec.feature:4"},
|
552
|
+
"result": {"status": "undefined"}}]},
|
553
|
+
{"id": "banana-party;monkey-eats-more-bananas",
|
554
|
+
"keyword": "Scenario",
|
555
|
+
"name": "Monkey eats more bananas",
|
556
|
+
"line": 9,
|
557
|
+
"description": "",
|
558
|
+
"type": "scenario",
|
559
|
+
"steps":
|
560
|
+
[{"keyword": "Then ",
|
561
|
+
"name": "the monkey eats more bananas",
|
562
|
+
"line": 10,
|
563
|
+
"match": {"location": "spec.feature:10"},
|
564
|
+
"result": {"status": "undefined"}}]}]}]})
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
describe "with a scenario with a step that embeds data directly" do
|
569
|
+
define_feature <<-FEATURE
|
570
|
+
Feature: Banana party
|
571
|
+
|
572
|
+
Scenario: Monkey eats bananas
|
573
|
+
Given there are bananas
|
574
|
+
FEATURE
|
575
|
+
|
576
|
+
define_steps do
|
577
|
+
Given(/^there are bananas$/) { data = "YWJj"
|
578
|
+
embed data, "mime-type;base64" }
|
579
|
+
end
|
580
|
+
|
581
|
+
it "includes the data from the step in the json data" do
|
582
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
583
|
+
[{"id": "banana-party",
|
584
|
+
"uri": "spec.feature",
|
585
|
+
"keyword": "Feature",
|
586
|
+
"name": "Banana party",
|
587
|
+
"line": 1,
|
588
|
+
"description": "",
|
589
|
+
"elements":
|
590
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
591
|
+
"keyword": "Scenario",
|
592
|
+
"name": "Monkey eats bananas",
|
593
|
+
"line": 3,
|
594
|
+
"description": "",
|
595
|
+
"type": "scenario",
|
596
|
+
"steps":
|
597
|
+
[{"keyword": "Given ",
|
598
|
+
"name": "there are bananas",
|
599
|
+
"line": 4,
|
600
|
+
"embeddings": [{"mime_type": "mime-type",
|
601
|
+
"data": "YWJj"}],
|
602
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:577"},
|
603
|
+
"result": {"status": "passed",
|
604
|
+
"duration": 1}}]}]}]})
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
describe "with a scenario with a step that embeds a file" do
|
609
|
+
define_feature <<-FEATURE
|
610
|
+
Feature: Banana party
|
611
|
+
|
612
|
+
Scenario: Monkey eats bananas
|
613
|
+
Given there are bananas
|
614
|
+
FEATURE
|
615
|
+
|
616
|
+
define_steps do
|
617
|
+
Given(/^there are bananas$/) {
|
618
|
+
RSpec::Mocks.allow_message(File, :file?) { true }
|
619
|
+
f1 = RSpec::Mocks::Double.new
|
620
|
+
RSpec::Mocks.allow_message(File, :open) { |&block| block.call(f1) }
|
621
|
+
RSpec::Mocks.allow_message(f1, :read) { "foo" }
|
622
|
+
embed('out/snapshot.jpeg', 'image/png')
|
623
|
+
}
|
624
|
+
end
|
625
|
+
|
626
|
+
it "includes the file content in the json data" do
|
627
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
628
|
+
[{"id": "banana-party",
|
629
|
+
"uri": "spec.feature",
|
630
|
+
"keyword": "Feature",
|
631
|
+
"name": "Banana party",
|
632
|
+
"line": 1,
|
633
|
+
"description": "",
|
634
|
+
"elements":
|
635
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
636
|
+
"keyword": "Scenario",
|
637
|
+
"name": "Monkey eats bananas",
|
638
|
+
"line": 3,
|
639
|
+
"description": "",
|
640
|
+
"type": "scenario",
|
641
|
+
"steps":
|
642
|
+
[{"keyword": "Given ",
|
643
|
+
"name": "there are bananas",
|
644
|
+
"line": 4,
|
645
|
+
"embeddings": [{"mime_type": "image/png",
|
646
|
+
"data": "Zm9v"}],
|
647
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:617"},
|
648
|
+
"result": {"status": "passed",
|
649
|
+
"duration": 1}}]}]}]})
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
describe "with a scenario with hooks" do
|
654
|
+
define_feature <<-FEATURE
|
655
|
+
Feature: Banana party
|
656
|
+
|
657
|
+
Scenario: Monkey eats bananas
|
658
|
+
Given there are bananas
|
659
|
+
FEATURE
|
660
|
+
|
661
|
+
define_steps do
|
662
|
+
Before() {}
|
663
|
+
Before() {}
|
664
|
+
After() {}
|
665
|
+
After() {}
|
666
|
+
AfterStep() {}
|
667
|
+
AfterStep() {}
|
668
|
+
Around() { |scenario, block| block.call }
|
669
|
+
Given(/^there are bananas$/) {}
|
670
|
+
end
|
671
|
+
|
672
|
+
it "includes all hooks except the around hook in the json data" do
|
673
|
+
expect(load_normalised_json(@out)).to eq MultiJson.load(%{
|
674
|
+
[{"id": "banana-party",
|
675
|
+
"uri": "spec.feature",
|
676
|
+
"keyword": "Feature",
|
677
|
+
"name": "Banana party",
|
678
|
+
"line": 1,
|
679
|
+
"description": "",
|
680
|
+
"elements":
|
681
|
+
[{"id": "banana-party;monkey-eats-bananas",
|
682
|
+
"keyword": "Scenario",
|
683
|
+
"name": "Monkey eats bananas",
|
684
|
+
"line": 3,
|
685
|
+
"description": "",
|
686
|
+
"type": "scenario",
|
687
|
+
"before":
|
688
|
+
[{"match": {"location": "spec/cucumber/formatter/json_spec.rb:662"},
|
689
|
+
"result": {"status": "passed",
|
690
|
+
"duration": 1}},
|
691
|
+
{"match": {"location": "spec/cucumber/formatter/json_spec.rb:663"},
|
692
|
+
"result": {"status": "passed",
|
693
|
+
"duration": 1}}],
|
694
|
+
"steps":
|
695
|
+
[{"keyword": "Given ",
|
696
|
+
"name": "there are bananas",
|
697
|
+
"line": 4,
|
698
|
+
"match": {"location": "spec/cucumber/formatter/json_spec.rb:669"},
|
699
|
+
"result": {"status": "passed",
|
700
|
+
"duration": 1},
|
701
|
+
"after":
|
702
|
+
[{"match": {"location": "spec/cucumber/formatter/json_spec.rb:666"},
|
703
|
+
"result": {"status": "passed",
|
704
|
+
"duration": 1}},
|
705
|
+
{"match": {"location": "spec/cucumber/formatter/json_spec.rb:667"},
|
706
|
+
"result": {"status": "passed",
|
707
|
+
"duration": 1}}]}],
|
708
|
+
"after":
|
709
|
+
[{"match": {"location": "spec/cucumber/formatter/json_spec.rb:665"},
|
710
|
+
"result": {"status": "passed",
|
711
|
+
"duration": 1}},
|
712
|
+
{"match": {"location": "spec/cucumber/formatter/json_spec.rb:664"},
|
713
|
+
"result": {"status": "passed",
|
714
|
+
"duration": 1}}]}]}]})
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
end
|
719
|
+
|
720
|
+
def load_normalised_json(out)
|
721
|
+
normalise_json(MultiJson.load(out.string))
|
722
|
+
end
|
723
|
+
|
724
|
+
def normalise_json(json)
|
725
|
+
#make sure duration was captured (should be >= 0)
|
726
|
+
#then set it to what is "expected" since duration is dynamic
|
727
|
+
json.each do |feature|
|
728
|
+
elements = feature.fetch('elements') { [] }
|
729
|
+
elements.each do |scenario|
|
730
|
+
['steps', 'before', 'after'].each do |type|
|
731
|
+
if scenario[type]
|
732
|
+
scenario[type].each do |step_or_hook|
|
733
|
+
normalise_json_step_or_hook(step_or_hook)
|
734
|
+
if step_or_hook['after']
|
735
|
+
step_or_hook['after'].each do |hook|
|
736
|
+
normalise_json_step_or_hook(hook)
|
737
|
+
end
|
738
|
+
end
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
end
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
def normalise_json_step_or_hook(step_or_hook)
|
747
|
+
if step_or_hook['result']
|
748
|
+
if step_or_hook['result']['duration']
|
749
|
+
expect(step_or_hook['result']['duration']).to be >= 0
|
750
|
+
step_or_hook['result']['duration'] = 1
|
751
|
+
end
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
end
|
756
|
+
end
|
757
|
+
end
|