cucumber 4.0.0.rc.1 → 4.0.0.rc.6
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 +5 -5
- data/CHANGELOG.md +97 -4
- data/CONTRIBUTING.md +1 -18
- data/README.md +4 -5
- data/lib/autotest/cucumber_mixin.rb +2 -10
- data/lib/cucumber.rb +1 -1
- data/lib/cucumber/cli/configuration.rb +1 -1
- data/lib/cucumber/cli/main.rb +1 -0
- data/lib/cucumber/cli/options.rb +18 -13
- data/lib/cucumber/cli/profile_loader.rb +23 -12
- data/lib/cucumber/configuration.rb +11 -2
- data/lib/cucumber/deprecate.rb +29 -5
- data/lib/cucumber/errors.rb +5 -2
- data/lib/cucumber/events.rb +12 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/hook_test_step_created.rb +13 -0
- data/lib/cucumber/events/test_case_created.rb +13 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_step_created.rb +13 -0
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/formatter/ast_lookup.rb +43 -38
- data/lib/cucumber/formatter/backtrace_filter.rb +4 -1
- data/lib/cucumber/formatter/console.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +1 -1
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +2 -0
- data/lib/cucumber/formatter/errors.rb +6 -0
- data/lib/cucumber/formatter/html.rb +24 -0
- data/lib/cucumber/formatter/http_io.rb +146 -0
- data/lib/cucumber/formatter/interceptor.rb +3 -21
- data/lib/cucumber/formatter/io.rb +14 -8
- data/lib/cucumber/formatter/json.rb +46 -36
- data/lib/cucumber/formatter/junit.rb +13 -11
- data/lib/cucumber/formatter/message.rb +22 -0
- data/lib/cucumber/formatter/message_builder.rb +243 -0
- data/lib/cucumber/formatter/pretty.rb +65 -60
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
- data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
- data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
- data/lib/cucumber/formatter/summary.rb +1 -1
- data/lib/cucumber/formatter/usage.rb +3 -3
- data/lib/cucumber/gherkin/data_table_parser.rb +12 -3
- data/lib/cucumber/gherkin/steps_parser.rb +13 -3
- data/lib/cucumber/glue/hook.rb +18 -2
- data/lib/cucumber/glue/proto_world.rb +30 -18
- data/lib/cucumber/glue/registry_and_more.rb +40 -3
- data/lib/cucumber/glue/snippet.rb +2 -2
- data/lib/cucumber/glue/step_definition.rb +28 -4
- data/lib/cucumber/hooks.rb +8 -8
- data/lib/cucumber/multiline_argument.rb +1 -1
- data/lib/cucumber/multiline_argument/data_table.rb +17 -13
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/rake/task.rb +3 -0
- data/lib/cucumber/runtime.rb +29 -3
- data/lib/cucumber/runtime/after_hooks.rb +6 -2
- data/lib/cucumber/runtime/before_hooks.rb +6 -2
- data/lib/cucumber/runtime/for_programming_languages.rb +1 -0
- data/lib/cucumber/runtime/step_hooks.rb +3 -2
- data/lib/cucumber/runtime/support_code.rb +3 -3
- data/lib/cucumber/runtime/user_interface.rb +2 -10
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/version +1 -1
- metadata +227 -73
@@ -9,30 +9,18 @@ module Cucumber
|
|
9
9
|
@pipe = pipe
|
10
10
|
@buffer = StringIO.new
|
11
11
|
@wrapped = true
|
12
|
+
@lock = Mutex.new
|
12
13
|
end
|
13
14
|
|
14
15
|
def write(str)
|
15
|
-
lock.synchronize do
|
16
|
+
@lock.synchronize do
|
16
17
|
@buffer << str if @wrapped
|
17
18
|
return @pipe.write(str)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
# @deprecated use #buffer_string
|
22
|
-
def buffer
|
23
|
-
require 'cucumber/deprecate.rb'
|
24
|
-
Cucumber.deprecate(
|
25
|
-
'Use Cucumber::Formatter::Interceptor::Pipe#buffer_string instead',
|
26
|
-
'Cucumber::Formatter::Interceptor::Pipe#buffer',
|
27
|
-
'3.99'
|
28
|
-
)
|
29
|
-
lock.synchronize do
|
30
|
-
return @buffer.string.lines
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
22
|
def buffer_string
|
35
|
-
lock.synchronize do
|
23
|
+
@lock.synchronize do
|
36
24
|
return @buffer.string.dup
|
37
25
|
end
|
38
26
|
end
|
@@ -80,12 +68,6 @@ module Cucumber
|
|
80
68
|
return $stdout
|
81
69
|
end
|
82
70
|
end
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def lock
|
87
|
-
@lock ||= Mutex.new
|
88
|
-
end
|
89
71
|
end
|
90
72
|
end
|
91
73
|
end
|
@@ -1,21 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'cucumber/formatter/http_io'
|
4
|
+
|
3
5
|
module Cucumber
|
4
6
|
module Formatter
|
5
7
|
module Io
|
6
8
|
module_function
|
7
9
|
|
8
|
-
def ensure_io(
|
9
|
-
return nil if
|
10
|
-
return
|
11
|
-
|
10
|
+
def ensure_io(path_or_url_or_io)
|
11
|
+
return nil if path_or_url_or_io.nil?
|
12
|
+
return path_or_url_or_io if path_or_url_or_io.respond_to?(:write)
|
13
|
+
io = if path_or_url_or_io.match(%r{^https?://})
|
14
|
+
HTTPIO.open(path_or_url_or_io)
|
15
|
+
else
|
16
|
+
File.open(path_or_url_or_io, Cucumber.file_mode('w'))
|
17
|
+
end
|
12
18
|
at_exit do
|
13
|
-
unless
|
14
|
-
|
15
|
-
|
19
|
+
unless io.closed?
|
20
|
+
io.flush
|
21
|
+
io.close
|
16
22
|
end
|
17
23
|
end
|
18
|
-
|
24
|
+
io
|
19
25
|
end
|
20
26
|
|
21
27
|
def ensure_file(path, name)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'json'
|
4
4
|
require 'base64'
|
5
5
|
require 'cucumber/formatter/backtrace_filter'
|
6
6
|
require 'cucumber/formatter/io'
|
7
7
|
require 'cucumber/formatter/ast_lookup'
|
8
|
+
require 'cucumber/deprecate'
|
8
9
|
|
9
10
|
module Cucumber
|
10
11
|
module Formatter
|
@@ -13,6 +14,14 @@ module Cucumber
|
|
13
14
|
include Io
|
14
15
|
|
15
16
|
def initialize(config)
|
17
|
+
Cucumber::Deprecate::CliOption.deprecate(
|
18
|
+
config.error_stream,
|
19
|
+
'--format=json',
|
20
|
+
"Please use --format=message and stand-alone json-formatter.\n" \
|
21
|
+
'json-formatter homepage: https://github.com/cucumber/cucumber/tree/master/json-formatter#cucumber-json-formatter',
|
22
|
+
'5.0.0'
|
23
|
+
)
|
24
|
+
|
16
25
|
@io = ensure_io(config.out_stream)
|
17
26
|
@ast_lookup = AstLookup.new(config)
|
18
27
|
@feature_hashes = []
|
@@ -77,14 +86,14 @@ module Cucumber
|
|
77
86
|
end
|
78
87
|
|
79
88
|
def on_test_run_finished(_event)
|
80
|
-
@io.write(
|
81
|
-
end
|
82
|
-
|
83
|
-
def puts(message)
|
84
|
-
test_step_output << message
|
89
|
+
@io.write(JSON.generate(@feature_hashes, pretty: true))
|
85
90
|
end
|
86
91
|
|
87
|
-
def
|
92
|
+
def attach(src, mime_type)
|
93
|
+
if mime_type == 'text/x.cucumber.log+plain'
|
94
|
+
test_step_output << src
|
95
|
+
return
|
96
|
+
end
|
88
97
|
if File.file?(src)
|
89
98
|
content = File.open(src, 'rb', &:read)
|
90
99
|
data = encode64(content)
|
@@ -163,33 +172,34 @@ module Cucumber
|
|
163
172
|
def create_step_hash(test_step)
|
164
173
|
step_source = @ast_lookup.step_source(test_step).step
|
165
174
|
step_hash = {
|
166
|
-
keyword: step_source
|
175
|
+
keyword: step_source.keyword,
|
167
176
|
name: test_step.text,
|
168
177
|
line: test_step.location.lines.min
|
169
178
|
}
|
170
|
-
step_hash[:doc_string] = create_doc_string_hash(step_source
|
171
|
-
step_hash[:rows] = create_data_table_value(step_source
|
179
|
+
step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string) unless step_source.doc_string.nil?
|
180
|
+
step_hash[:rows] = create_data_table_value(step_source.data_table) unless step_source.data_table.nil?
|
172
181
|
step_hash
|
173
182
|
end
|
174
183
|
|
175
184
|
def create_doc_string_hash(doc_string)
|
176
|
-
content_type = doc_string
|
185
|
+
content_type = doc_string.media_type || ''
|
177
186
|
{
|
178
|
-
value: doc_string
|
187
|
+
value: doc_string.content,
|
179
188
|
content_type: content_type,
|
180
|
-
line: doc_string
|
189
|
+
line: doc_string.location.line
|
181
190
|
}
|
182
191
|
end
|
183
192
|
|
184
193
|
def create_data_table_value(data_table)
|
185
|
-
data_table
|
186
|
-
{ cells: row
|
194
|
+
data_table.rows.map do |row|
|
195
|
+
{ cells: row.cells.map(&:value) }
|
187
196
|
end
|
188
197
|
end
|
189
198
|
|
190
199
|
def add_match_and_result(test_step, result)
|
191
200
|
@step_or_hook_hash[:match] = create_match_hash(test_step, result)
|
192
201
|
@step_or_hook_hash[:result] = create_result_hash(result)
|
202
|
+
result.embeddings.each { |e| embed(e['src'], e['mime_type'], e['label']) } if result.respond_to?(:embeddings)
|
193
203
|
end
|
194
204
|
|
195
205
|
def add_failed_around_hook(result)
|
@@ -230,9 +240,9 @@ module Cucumber
|
|
230
240
|
def initialize(test_case, ast_lookup)
|
231
241
|
@background_hash = nil
|
232
242
|
uri = test_case.location.file
|
233
|
-
feature = ast_lookup.gherkin_document(uri)
|
243
|
+
feature = ast_lookup.gherkin_document(uri).feature
|
234
244
|
feature(feature, uri)
|
235
|
-
background(feature
|
245
|
+
background(feature.children.first.background) unless feature.children.first.background.nil?
|
236
246
|
scenario(ast_lookup.scenario_source(test_case), test_case)
|
237
247
|
end
|
238
248
|
|
@@ -242,23 +252,23 @@ module Cucumber
|
|
242
252
|
|
243
253
|
def feature(feature, uri)
|
244
254
|
@feature_hash = {
|
245
|
-
id: create_id(feature
|
255
|
+
id: create_id(feature.name),
|
246
256
|
uri: uri,
|
247
|
-
keyword: feature
|
248
|
-
name: feature
|
249
|
-
description: value_or_empty_string(feature
|
250
|
-
line: feature
|
257
|
+
keyword: feature.keyword,
|
258
|
+
name: feature.name,
|
259
|
+
description: value_or_empty_string(feature.description),
|
260
|
+
line: feature.location.line
|
251
261
|
}
|
252
|
-
return if feature
|
253
|
-
@feature_hash[:tags] = create_tags_array_from_hash_array(feature
|
262
|
+
return if feature.tags.empty?
|
263
|
+
@feature_hash[:tags] = create_tags_array_from_hash_array(feature.tags)
|
254
264
|
end
|
255
265
|
|
256
266
|
def background(background)
|
257
267
|
@background_hash = {
|
258
|
-
keyword: background
|
259
|
-
name: background
|
260
|
-
description: value_or_empty_string(background
|
261
|
-
line: background
|
268
|
+
keyword: background.keyword,
|
269
|
+
name: background.name,
|
270
|
+
description: value_or_empty_string(background.description),
|
271
|
+
line: background.location.line,
|
262
272
|
type: 'background'
|
263
273
|
}
|
264
274
|
end
|
@@ -267,9 +277,9 @@ module Cucumber
|
|
267
277
|
scenario = scenario_source.type == :Scenario ? scenario_source.scenario : scenario_source.scenario_outline
|
268
278
|
@test_case_hash = {
|
269
279
|
id: "#{@feature_hash[:id]};#{create_id_from_scenario_source(scenario_source)}",
|
270
|
-
keyword: scenario
|
271
|
-
name:
|
272
|
-
description: value_or_empty_string(scenario
|
280
|
+
keyword: scenario.keyword,
|
281
|
+
name: test_case.name,
|
282
|
+
description: value_or_empty_string(scenario.description),
|
273
283
|
line: test_case.location.lines.max,
|
274
284
|
type: 'scenario'
|
275
285
|
}
|
@@ -288,24 +298,24 @@ module Cucumber
|
|
288
298
|
|
289
299
|
def create_id_from_scenario_source(scenario_source)
|
290
300
|
if scenario_source.type == :Scenario
|
291
|
-
create_id(scenario_source.scenario
|
301
|
+
create_id(scenario_source.scenario.name)
|
292
302
|
else
|
293
|
-
scenario_outline_name = scenario_source.scenario_outline
|
294
|
-
examples_name = scenario_source.examples
|
303
|
+
scenario_outline_name = scenario_source.scenario_outline.name
|
304
|
+
examples_name = scenario_source.examples.name
|
295
305
|
row_number = calculate_row_number(scenario_source)
|
296
306
|
"#{create_id(scenario_outline_name)};#{create_id(examples_name)};#{row_number}"
|
297
307
|
end
|
298
308
|
end
|
299
309
|
|
300
310
|
def calculate_row_number(scenario_source)
|
301
|
-
scenario_source.examples
|
311
|
+
scenario_source.examples.table_body.each_with_index do |row, index|
|
302
312
|
return index + 2 if row == scenario_source.row
|
303
313
|
end
|
304
314
|
end
|
305
315
|
|
306
316
|
def create_tags_array_from_hash_array(tags)
|
307
317
|
tags_array = []
|
308
|
-
tags.each { |tag| tags_array << { name: tag
|
318
|
+
tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
|
309
319
|
tags_array
|
310
320
|
end
|
311
321
|
|
@@ -82,8 +82,8 @@ module Cucumber
|
|
82
82
|
|
83
83
|
def start_feature(test_case)
|
84
84
|
uri = test_case.location.file
|
85
|
-
feature = @ast_lookup.gherkin_document(uri)
|
86
|
-
raise UnNamedFeatureError, uri if feature
|
85
|
+
feature = @ast_lookup.gherkin_document(uri).feature
|
86
|
+
raise UnNamedFeatureError, uri if feature.name.empty?
|
87
87
|
@current_feature_data = @features_data[uri]
|
88
88
|
@current_feature_data[:uri] = uri unless @current_feature_data[:uri]
|
89
89
|
@current_feature_data[:feature] = feature unless @current_feature_data[:feature]
|
@@ -97,8 +97,8 @@ module Cucumber
|
|
97
97
|
errors: feature_data[:errors],
|
98
98
|
skipped: feature_data[:skipped],
|
99
99
|
tests: feature_data[:tests],
|
100
|
-
time: format('
|
101
|
-
name: feature_data[:feature]
|
100
|
+
time: format('%<time>.6f', time: feature_data[:time]),
|
101
|
+
name: feature_data[:feature].name
|
102
102
|
) do
|
103
103
|
@testsuite << feature_data[:builder].target!
|
104
104
|
end
|
@@ -108,7 +108,7 @@ module Cucumber
|
|
108
108
|
|
109
109
|
def create_output_string(test_case, scenario, result, row_name) # rubocop:disable Metrics/PerceivedComplexity
|
110
110
|
scenario_source = @ast_lookup.scenario_source(test_case)
|
111
|
-
keyword = scenario_source.type == :Scenario ? scenario_source.scenario
|
111
|
+
keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
|
112
112
|
output = "#{keyword}: #{scenario}\n\n"
|
113
113
|
return output if result.ok?(@config.strict)
|
114
114
|
if scenario_source.type == :Scenario
|
@@ -117,7 +117,7 @@ module Cucumber
|
|
117
117
|
output += "#{@failing_test_step.text} at #{@failing_test_step.location}\n"
|
118
118
|
else
|
119
119
|
step_source = @ast_lookup.step_source(@failing_test_step).step
|
120
|
-
output += "#{step_source
|
120
|
+
output += "#{step_source.keyword}#{@failing_test_step.text}\n"
|
121
121
|
end
|
122
122
|
else # An Around hook has failed
|
123
123
|
output += "Around hook\n"
|
@@ -131,10 +131,10 @@ module Cucumber
|
|
131
131
|
def build_testcase(result, scenario_designation, output)
|
132
132
|
duration = ResultBuilder.new(result).test_case_duration
|
133
133
|
@current_feature_data[:time] += duration
|
134
|
-
classname = @current_feature_data[:feature]
|
134
|
+
classname = @current_feature_data[:feature].name
|
135
135
|
name = scenario_designation
|
136
136
|
|
137
|
-
@current_feature_data[:builder].testcase(classname: classname, name: name, time: format('
|
137
|
+
@current_feature_data[:builder].testcase(classname: classname, name: name, time: format('%<duration>.6f', duration: duration)) do
|
138
138
|
if !result.passed? && result.ok?(@config.strict)
|
139
139
|
@current_feature_data[:builder].skipped
|
140
140
|
@current_feature_data[:skipped] += 1
|
@@ -203,15 +203,15 @@ module Cucumber
|
|
203
203
|
end
|
204
204
|
|
205
205
|
def scenario(scenario)
|
206
|
-
@scenario_name = scenario
|
206
|
+
@scenario_name = scenario.name.empty? ? 'Unnamed scenario' : scenario.name
|
207
207
|
end
|
208
208
|
|
209
209
|
def scenario_outline(outline)
|
210
|
-
@scenario_name = outline
|
210
|
+
@scenario_name = outline.name.empty? ? 'Unnamed scenario outline' : outline.name
|
211
211
|
end
|
212
212
|
|
213
213
|
def examples_table_row(row)
|
214
|
-
@row_name = '| ' + row
|
214
|
+
@row_name = '| ' + row.cells.map(&:value).join(' | ') + ' |'
|
215
215
|
@name_suffix = " (outline example : #{@row_name})"
|
216
216
|
end
|
217
217
|
end
|
@@ -238,6 +238,8 @@ module Cucumber
|
|
238
238
|
def duration(duration, *)
|
239
239
|
duration.tap { |dur| @test_case_duration = dur.nanoseconds / 10**9.0 }
|
240
240
|
end
|
241
|
+
|
242
|
+
def attach(*) end
|
241
243
|
end
|
242
244
|
end
|
243
245
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cucumber/formatter/io'
|
4
|
+
require 'cucumber/formatter/message_builder'
|
5
|
+
|
6
|
+
module Cucumber
|
7
|
+
module Formatter
|
8
|
+
# The formatter used for <tt>--format message</tt>
|
9
|
+
class Message < MessageBuilder
|
10
|
+
include Io
|
11
|
+
|
12
|
+
def initialize(config)
|
13
|
+
@io = ensure_io(config.out_stream)
|
14
|
+
super(config)
|
15
|
+
end
|
16
|
+
|
17
|
+
def output_envelope(envelope)
|
18
|
+
envelope.write_ndjson_to(@io)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'cucumber/formatter/backtrace_filter'
|
3
|
+
require 'cucumber/formatter/query/hook_by_test_step'
|
4
|
+
require 'cucumber/formatter/query/pickle_by_test'
|
5
|
+
require 'cucumber/formatter/query/pickle_step_by_test_step'
|
6
|
+
require 'cucumber/formatter/query/step_definitions_by_test_step'
|
7
|
+
require 'cucumber/formatter/query/test_case_started_by_test_case'
|
8
|
+
|
9
|
+
module Cucumber
|
10
|
+
module Formatter
|
11
|
+
class MessageBuilder
|
12
|
+
include Cucumber::Messages::TimeConversion
|
13
|
+
|
14
|
+
def initialize(config)
|
15
|
+
@config = config
|
16
|
+
|
17
|
+
@hook_by_test_step = Query::HookByTestStep.new(config)
|
18
|
+
@pickle_by_test = Query::PickleByTest.new(config)
|
19
|
+
@pickle_step_by_test_step = Query::PickleStepByTestStep.new(config)
|
20
|
+
@step_definitions_by_test_step = Query::StepDefinitionsByTestStep.new(config)
|
21
|
+
@test_case_started_by_test_case = Query::TestCaseStartedByTestCase.new(config)
|
22
|
+
|
23
|
+
config.on_event :envelope, &method(:on_envelope)
|
24
|
+
config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
|
25
|
+
config.on_event :test_case_ready, &method(:on_test_case_ready)
|
26
|
+
config.on_event :test_run_started, &method(:on_test_run_started)
|
27
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
28
|
+
config.on_event :test_step_started, &method(:on_test_step_started)
|
29
|
+
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
30
|
+
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
31
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
32
|
+
|
33
|
+
@test_case_by_step_id = {}
|
34
|
+
@current_test_case_started_id = nil
|
35
|
+
@current_test_step_id = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
def output_message
|
39
|
+
raise 'To be implemented'
|
40
|
+
end
|
41
|
+
|
42
|
+
def attach(src, media_type)
|
43
|
+
attachment_data = {
|
44
|
+
test_step_id: @current_test_step_id,
|
45
|
+
test_case_started_id: @current_test_case_started_id,
|
46
|
+
media_type: media_type
|
47
|
+
}
|
48
|
+
|
49
|
+
if media_type.start_with?('text/')
|
50
|
+
attachment_data[:content_encoding] = Cucumber::Messages::Attachment::ContentEncoding::IDENTITY
|
51
|
+
attachment_data[:body] = src
|
52
|
+
else
|
53
|
+
body = src.respond_to?(:read) ? src.read : src
|
54
|
+
|
55
|
+
attachment_data[:content_encoding] = Cucumber::Messages::Attachment::ContentEncoding::BASE64
|
56
|
+
attachment_data[:body] = Base64.strict_encode64(body)
|
57
|
+
end
|
58
|
+
|
59
|
+
message = Cucumber::Messages::Envelope.new(
|
60
|
+
attachment: Cucumber::Messages::Attachment.new(**attachment_data)
|
61
|
+
)
|
62
|
+
|
63
|
+
output_envelope(message)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def on_envelope(event)
|
69
|
+
output_envelope(event.envelope)
|
70
|
+
end
|
71
|
+
|
72
|
+
def on_gherkin_source_read(event)
|
73
|
+
message = Cucumber::Messages::Envelope.new(
|
74
|
+
source: Cucumber::Messages::Source.new(
|
75
|
+
uri: event.path,
|
76
|
+
data: event.body,
|
77
|
+
media_type: 'text/x.cucumber.gherkin+plain'
|
78
|
+
)
|
79
|
+
)
|
80
|
+
|
81
|
+
output_envelope(message)
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_test_case_ready(event)
|
85
|
+
event.test_case.test_steps.each do |step|
|
86
|
+
@test_case_by_step_id[step.id] = event.test_case
|
87
|
+
end
|
88
|
+
|
89
|
+
message = Cucumber::Messages::Envelope.new(
|
90
|
+
test_case: Cucumber::Messages::TestCase.new(
|
91
|
+
id: event.test_case.id,
|
92
|
+
pickle_id: @pickle_by_test.pickle_id(event.test_case),
|
93
|
+
test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) }
|
94
|
+
)
|
95
|
+
)
|
96
|
+
|
97
|
+
output_envelope(message)
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_step_to_message(step)
|
101
|
+
return hook_step_to_message(step) if step.hook?
|
102
|
+
|
103
|
+
Cucumber::Messages::TestCase::TestStep.new(
|
104
|
+
id: step.id,
|
105
|
+
pickle_step_id: @pickle_step_by_test_step.pickle_step_id(step),
|
106
|
+
step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
|
107
|
+
step_match_arguments_lists: step_match_arguments_lists(step)
|
108
|
+
)
|
109
|
+
end
|
110
|
+
|
111
|
+
def hook_step_to_message(step)
|
112
|
+
Cucumber::Messages::TestCase::TestStep.new(
|
113
|
+
id: step.id,
|
114
|
+
hook_id: @hook_by_test_step.hook_id(step)
|
115
|
+
)
|
116
|
+
end
|
117
|
+
|
118
|
+
def step_match_arguments_lists(step)
|
119
|
+
match_arguments = step_match_arguments(step)
|
120
|
+
[Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList.new(
|
121
|
+
step_match_arguments: match_arguments
|
122
|
+
)]
|
123
|
+
rescue Cucumber::Formatter::TestStepUnknownError
|
124
|
+
[]
|
125
|
+
end
|
126
|
+
|
127
|
+
def step_match_arguments(step)
|
128
|
+
@step_definitions_by_test_step.step_match_arguments(step).map do |argument|
|
129
|
+
Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList::StepMatchArgument.new(
|
130
|
+
group: argument_group_to_message(argument.group),
|
131
|
+
parameter_type_name: argument.parameter_type.name
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def argument_group_to_message(group)
|
137
|
+
Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList::StepMatchArgument::Group.new(
|
138
|
+
start: group.start,
|
139
|
+
value: group.value,
|
140
|
+
children: group.children.map { |child| argument_group_to_message(child) }
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
def on_test_run_started(*)
|
145
|
+
message = Cucumber::Messages::Envelope.new(
|
146
|
+
test_run_started: Cucumber::Messages::TestRunStarted.new(
|
147
|
+
timestamp: time_to_timestamp(Time.now)
|
148
|
+
)
|
149
|
+
)
|
150
|
+
|
151
|
+
output_envelope(message)
|
152
|
+
end
|
153
|
+
|
154
|
+
def on_test_case_started(event)
|
155
|
+
@current_test_case_started_id = test_case_started_id(event.test_case)
|
156
|
+
|
157
|
+
message = Cucumber::Messages::Envelope.new(
|
158
|
+
test_case_started: Cucumber::Messages::TestCaseStarted.new(
|
159
|
+
id: test_case_started_id(event.test_case),
|
160
|
+
test_case_id: event.test_case.id,
|
161
|
+
timestamp: time_to_timestamp(Time.now),
|
162
|
+
attempt: @test_case_started_by_test_case.attempt_by_test_case(event.test_case)
|
163
|
+
)
|
164
|
+
)
|
165
|
+
|
166
|
+
output_envelope(message)
|
167
|
+
end
|
168
|
+
|
169
|
+
def on_test_step_started(event)
|
170
|
+
@current_test_step_id = event.test_step.id
|
171
|
+
test_case = @test_case_by_step_id[event.test_step.id]
|
172
|
+
|
173
|
+
message = Cucumber::Messages::Envelope.new(
|
174
|
+
test_step_started: Cucumber::Messages::TestStepStarted.new(
|
175
|
+
test_step_id: event.test_step.id,
|
176
|
+
test_case_started_id: test_case_started_id(test_case),
|
177
|
+
timestamp: time_to_timestamp(Time.now)
|
178
|
+
)
|
179
|
+
)
|
180
|
+
|
181
|
+
output_envelope(message)
|
182
|
+
end
|
183
|
+
|
184
|
+
def on_test_step_finished(event)
|
185
|
+
test_case = @test_case_by_step_id[event.test_step.id]
|
186
|
+
result = event
|
187
|
+
.result
|
188
|
+
.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
189
|
+
|
190
|
+
result_message = result.to_message
|
191
|
+
if result.failed? || result.pending?
|
192
|
+
result_message = Cucumber::Messages::TestStepFinished::TestStepResult.new(
|
193
|
+
status: result_message.status,
|
194
|
+
duration: result_message.duration,
|
195
|
+
message: create_error_message(result)
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
message = Cucumber::Messages::Envelope.new(
|
200
|
+
test_step_finished: Cucumber::Messages::TestStepFinished.new(
|
201
|
+
test_step_id: event.test_step.id,
|
202
|
+
test_case_started_id: test_case_started_id(test_case),
|
203
|
+
test_step_result: result_message,
|
204
|
+
timestamp: time_to_timestamp(Time.now)
|
205
|
+
)
|
206
|
+
)
|
207
|
+
|
208
|
+
output_envelope(message)
|
209
|
+
end
|
210
|
+
|
211
|
+
def create_error_message(result)
|
212
|
+
message_element = result.failed? ? result.exception : result
|
213
|
+
message = "#{message_element.message} (#{message_element.class})"
|
214
|
+
([message] + message_element.backtrace).join("\n")
|
215
|
+
end
|
216
|
+
|
217
|
+
def on_test_case_finished(event)
|
218
|
+
message = Cucumber::Messages::Envelope.new(
|
219
|
+
test_case_finished: Cucumber::Messages::TestCaseFinished.new(
|
220
|
+
test_case_started_id: test_case_started_id(event.test_case),
|
221
|
+
timestamp: time_to_timestamp(Time.now)
|
222
|
+
)
|
223
|
+
)
|
224
|
+
|
225
|
+
output_envelope(message)
|
226
|
+
end
|
227
|
+
|
228
|
+
def on_test_run_finished(*)
|
229
|
+
message = Cucumber::Messages::Envelope.new(
|
230
|
+
test_run_finished: Cucumber::Messages::TestRunFinished.new(
|
231
|
+
timestamp: time_to_timestamp(Time.now)
|
232
|
+
)
|
233
|
+
)
|
234
|
+
|
235
|
+
output_envelope(message)
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_case_started_id(test_case)
|
239
|
+
@test_case_started_by_test_case.test_case_started_id_by_test_case(test_case)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|