cucumber 3.2.0 → 4.0.0
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/CHANGELOG.md +166 -19
- data/CONTRIBUTING.md +2 -18
- data/README.md +4 -5
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +34 -39
- data/lib/cucumber/cli/configuration.rb +5 -5
- data/lib/cucumber/cli/main.rb +12 -12
- data/lib/cucumber/cli/options.rb +62 -71
- data/lib/cucumber/cli/profile_loader.rb +49 -26
- data/lib/cucumber/configuration.rb +31 -23
- data/lib/cucumber/constantize.rb +2 -5
- data/lib/cucumber/deprecate.rb +31 -7
- data/lib/cucumber/errors.rb +5 -7
- data/lib/cucumber/events/envelope.rb +9 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
- data/lib/cucumber/events/hook_test_step_created.rb +13 -0
- data/lib/cucumber/events/step_activated.rb +2 -1
- 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/events/undefined_parameter_type.rb +10 -0
- data/lib/cucumber/events.rb +13 -6
- data/lib/cucumber/file_specs.rb +6 -6
- data/lib/cucumber/filters/activate_steps.rb +5 -3
- data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
- data/lib/cucumber/filters/prepare_world.rb +5 -9
- data/lib/cucumber/filters/quit.rb +1 -3
- data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +40 -45
- data/lib/cucumber/formatter/ast_lookup.rb +165 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
- data/lib/cucumber/formatter/console.rb +58 -66
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +6 -3
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +3 -1
- data/lib/cucumber/formatter/errors.rb +6 -0
- data/lib/cucumber/formatter/fanout.rb +2 -0
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +1 -1
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/interceptor.rb +8 -28
- data/lib/cucumber/formatter/io.rb +1 -1
- data/lib/cucumber/formatter/json.rb +101 -115
- data/lib/cucumber/formatter/junit.rb +56 -56
- data/lib/cucumber/formatter/message.rb +22 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +359 -153
- data/lib/cucumber/formatter/progress.rb +30 -32
- 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/rerun.rb +22 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +2 -3
- data/lib/cucumber/formatter/summary.rb +16 -8
- data/lib/cucumber/formatter/unicode.rb +15 -17
- data/lib/cucumber/formatter/usage.rb +11 -10
- data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +1 -1
- data/lib/cucumber/glue/hook.rb +34 -11
- data/lib/cucumber/glue/invoke_in_world.rb +13 -18
- data/lib/cucumber/glue/proto_world.rb +42 -33
- data/lib/cucumber/glue/registry_and_more.rb +42 -12
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +42 -19
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +11 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
- data/lib/cucumber/multiline_argument/data_table.rb +97 -64
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +3 -3
- data/lib/cucumber/rake/task.rb +16 -16
- data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
- data/lib/cucumber/running_test_case.rb +2 -53
- data/lib/cucumber/runtime/after_hooks.rb +8 -4
- data/lib/cucumber/runtime/before_hooks.rb +8 -4
- data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
- data/lib/cucumber/runtime/step_hooks.rb +3 -2
- data/lib/cucumber/runtime/support_code.rb +13 -15
- data/lib/cucumber/runtime/user_interface.rb +6 -16
- data/lib/cucumber/runtime.rb +54 -58
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +12 -11
- data/lib/cucumber/step_match_search.rb +2 -1
- data/lib/cucumber/term/ansicolor.rb +9 -9
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +1 -1
- metadata +221 -77
- data/lib/cucumber/formatter/cucumber.css +0 -286
- data/lib/cucumber/formatter/cucumber.sass +0 -247
- data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
- data/lib/cucumber/formatter/html_builder.rb +0 -121
- data/lib/cucumber/formatter/inline-js.js +0 -30
- data/lib/cucumber/formatter/jquery-min.js +0 -154
- data/lib/cucumber/formatter/json_pretty.rb +0 -11
- data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
- data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
- data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
- data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
- data/lib/cucumber/step_argument.rb +0 -25
@@ -5,6 +5,7 @@ require 'cucumber/formatter/backtrace_filter'
|
|
5
5
|
require 'cucumber/formatter/io'
|
6
6
|
require 'cucumber/formatter/interceptor'
|
7
7
|
require 'fileutils'
|
8
|
+
require 'cucumber/formatter/ast_lookup'
|
8
9
|
|
9
10
|
module Cucumber
|
10
11
|
module Formatter
|
@@ -19,6 +20,7 @@ module Cucumber
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def initialize(config)
|
23
|
+
@ast_lookup = AstLookup.new(config)
|
22
24
|
config.on_event :test_case_started, &method(:on_test_case_started)
|
23
25
|
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
24
26
|
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
@@ -33,17 +35,15 @@ module Cucumber
|
|
33
35
|
tests: 0,
|
34
36
|
skipped: 0,
|
35
37
|
time: 0,
|
36
|
-
builder: Builder::XmlMarkup.new(:
|
38
|
+
builder: Builder::XmlMarkup.new(indent: 2)
|
37
39
|
}
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
def on_test_case_started(event)
|
42
44
|
test_case = event.test_case
|
43
|
-
unless same_feature_as_previous_test_case?(test_case
|
44
|
-
|
45
|
-
end
|
46
|
-
@failing_step_source = nil
|
45
|
+
start_feature(test_case) unless same_feature_as_previous_test_case?(test_case)
|
46
|
+
@failing_test_step = nil
|
47
47
|
# In order to fill out <system-err/> and <system-out/>, we need to
|
48
48
|
# intercept the $stderr and $stdout
|
49
49
|
@interceptedout = Interceptor::Pipe.wrap(:stdout)
|
@@ -52,15 +52,15 @@ module Cucumber
|
|
52
52
|
|
53
53
|
def on_test_step_finished(event)
|
54
54
|
test_step, result = *event.attributes
|
55
|
-
return if @
|
55
|
+
return if @failing_test_step
|
56
56
|
|
57
|
-
@
|
57
|
+
@failing_test_step = test_step unless result.ok?(@config.strict)
|
58
58
|
end
|
59
59
|
|
60
60
|
def on_test_case_finished(event)
|
61
61
|
test_case, result = *event.attributes
|
62
62
|
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
63
|
-
test_case_name = NameBuilder.new(test_case)
|
63
|
+
test_case_name = NameBuilder.new(test_case, @ast_lookup)
|
64
64
|
scenario = test_case_name.scenario_name
|
65
65
|
scenario_designation = "#{scenario}#{test_case_name.name_suffix}"
|
66
66
|
output = create_output_string(test_case, scenario, result, test_case_name.row_name)
|
@@ -71,45 +71,54 @@ module Cucumber
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def on_test_run_finished(_event)
|
74
|
-
@features_data.each { |
|
74
|
+
@features_data.each { |_file, data| end_feature(data) }
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
78
78
|
|
79
|
-
def same_feature_as_previous_test_case?(
|
80
|
-
@current_feature_data && @current_feature_data[:
|
79
|
+
def same_feature_as_previous_test_case?(test_case)
|
80
|
+
@current_feature_data && @current_feature_data[:uri] == test_case.location.file
|
81
81
|
end
|
82
82
|
|
83
|
-
def start_feature(
|
84
|
-
|
85
|
-
|
83
|
+
def start_feature(test_case)
|
84
|
+
uri = test_case.location.file
|
85
|
+
feature = @ast_lookup.gherkin_document(uri).feature
|
86
|
+
raise UnNamedFeatureError, uri if feature.name.empty?
|
87
|
+
@current_feature_data = @features_data[uri]
|
88
|
+
@current_feature_data[:uri] = uri unless @current_feature_data[:uri]
|
86
89
|
@current_feature_data[:feature] = feature unless @current_feature_data[:feature]
|
87
90
|
end
|
88
91
|
|
89
92
|
def end_feature(feature_data)
|
90
|
-
@testsuite = Builder::XmlMarkup.new(:
|
93
|
+
@testsuite = Builder::XmlMarkup.new(indent: 2)
|
91
94
|
@testsuite.instruct!
|
92
95
|
@testsuite.testsuite(
|
93
|
-
:
|
94
|
-
:
|
95
|
-
:
|
96
|
-
:
|
97
|
-
:
|
98
|
-
:
|
96
|
+
failures: feature_data[:failures],
|
97
|
+
errors: feature_data[:errors],
|
98
|
+
skipped: feature_data[:skipped],
|
99
|
+
tests: feature_data[:tests],
|
100
|
+
time: format('%<time>.6f', time: feature_data[:time]),
|
101
|
+
name: feature_data[:feature].name
|
99
102
|
) do
|
100
103
|
@testsuite << feature_data[:builder].target!
|
101
104
|
end
|
102
105
|
|
103
|
-
write_file(feature_result_filename(feature_data[:
|
106
|
+
write_file(feature_result_filename(feature_data[:uri]), @testsuite.target!)
|
104
107
|
end
|
105
108
|
|
106
|
-
def create_output_string(test_case, scenario, result, row_name)
|
107
|
-
|
109
|
+
def create_output_string(test_case, scenario, result, row_name) # rubocop:disable Metrics/PerceivedComplexity
|
110
|
+
scenario_source = @ast_lookup.scenario_source(test_case)
|
111
|
+
keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
|
112
|
+
output = "#{keyword}: #{scenario}\n\n"
|
108
113
|
return output if result.ok?(@config.strict)
|
109
|
-
if
|
110
|
-
if @
|
111
|
-
|
112
|
-
|
114
|
+
if scenario_source.type == :Scenario
|
115
|
+
if @failing_test_step
|
116
|
+
if @failing_test_step.hook?
|
117
|
+
output += "#{@failing_test_step.text} at #{@failing_test_step.location}\n"
|
118
|
+
else
|
119
|
+
step_source = @ast_lookup.step_source(@failing_test_step).step
|
120
|
+
output += "#{step_source.keyword}#{@failing_test_step.text}\n"
|
121
|
+
end
|
113
122
|
else # An Around hook has failed
|
114
123
|
output += "Around hook\n"
|
115
124
|
end
|
@@ -119,24 +128,20 @@ module Cucumber
|
|
119
128
|
output + "\nMessage:\n"
|
120
129
|
end
|
121
130
|
|
122
|
-
def hook?(step)
|
123
|
-
['Before hook', 'After hook', 'AfterStep hook'].include? step.text
|
124
|
-
end
|
125
|
-
|
126
131
|
def build_testcase(result, scenario_designation, output)
|
127
132
|
duration = ResultBuilder.new(result).test_case_duration
|
128
133
|
@current_feature_data[:time] += duration
|
129
134
|
classname = @current_feature_data[:feature].name
|
130
135
|
name = scenario_designation
|
131
136
|
|
132
|
-
@current_feature_data[:builder].testcase(:
|
137
|
+
@current_feature_data[:builder].testcase(classname: classname, name: name, time: format('%<duration>.6f', duration: duration)) do
|
133
138
|
if !result.passed? && result.ok?(@config.strict)
|
134
139
|
@current_feature_data[:builder].skipped
|
135
140
|
@current_feature_data[:skipped] += 1
|
136
141
|
elsif !result.passed?
|
137
142
|
status = result.to_sym
|
138
143
|
exception = get_backtrace_object(result)
|
139
|
-
@current_feature_data[:builder].failure(:
|
144
|
+
@current_feature_data[:builder].failure(message: "#{status} #{name}", type: status) do
|
140
145
|
@current_feature_data[:builder].cdata! output
|
141
146
|
@current_feature_data[:builder].cdata!(format_exception(exception)) if exception
|
142
147
|
end
|
@@ -154,11 +159,9 @@ module Cucumber
|
|
154
159
|
|
155
160
|
def get_backtrace_object(result)
|
156
161
|
if result.failed?
|
157
|
-
|
162
|
+
result.exception
|
158
163
|
elsif result.backtrace
|
159
|
-
|
160
|
-
else
|
161
|
-
return nil
|
164
|
+
result
|
162
165
|
end
|
163
166
|
end
|
164
167
|
|
@@ -171,7 +174,7 @@ module Cucumber
|
|
171
174
|
end
|
172
175
|
|
173
176
|
def basename(feature_file)
|
174
|
-
File.basename(feature_file.gsub(/[\\\/]/, '-'), '.feature')
|
177
|
+
File.basename(feature_file.gsub(/[\\\/]/, '-'), '.feature') # rubocop:disable Style/RegexpLiteral
|
175
178
|
end
|
176
179
|
|
177
180
|
def write_file(feature_filename, data)
|
@@ -187,34 +190,29 @@ module Cucumber
|
|
187
190
|
class NameBuilder
|
188
191
|
attr_reader :scenario_name, :name_suffix, :row_name
|
189
192
|
|
190
|
-
def initialize(test_case)
|
193
|
+
def initialize(test_case, ast_lookup)
|
191
194
|
@name_suffix = ''
|
192
195
|
@row_name = ''
|
193
|
-
test_case
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
196
|
+
scenario_source = ast_lookup.scenario_source(test_case)
|
197
|
+
if scenario_source.type == :Scenario
|
198
|
+
scenario(scenario_source.scenario)
|
199
|
+
else
|
200
|
+
scenario_outline(scenario_source.scenario_outline)
|
201
|
+
examples_table_row(scenario_source.row)
|
202
|
+
end
|
198
203
|
end
|
199
204
|
|
200
205
|
def scenario(scenario)
|
201
|
-
@scenario_name =
|
202
|
-
self
|
206
|
+
@scenario_name = scenario.name.empty? ? 'Unnamed scenario' : scenario.name
|
203
207
|
end
|
204
208
|
|
205
209
|
def scenario_outline(outline)
|
206
|
-
@scenario_name =
|
207
|
-
self
|
208
|
-
end
|
209
|
-
|
210
|
-
def examples_table(*)
|
211
|
-
self
|
210
|
+
@scenario_name = outline.name.empty? ? 'Unnamed scenario outline' : outline.name
|
212
211
|
end
|
213
212
|
|
214
213
|
def examples_table_row(row)
|
215
|
-
@row_name = '| ' + row.
|
214
|
+
@row_name = '| ' + row.cells.map(&:value).join(' | ') + ' |'
|
216
215
|
@name_suffix = " (outline example : #{@row_name})"
|
217
|
-
self
|
218
216
|
end
|
219
217
|
end
|
220
218
|
|
@@ -238,8 +236,10 @@ module Cucumber
|
|
238
236
|
def exception(*) end
|
239
237
|
|
240
238
|
def duration(duration, *)
|
241
|
-
duration.tap { |
|
239
|
+
duration.tap { |dur| @test_case_duration = dur.nanoseconds / 10**9.0 }
|
242
240
|
end
|
241
|
+
|
242
|
+
def attach(*) end
|
243
243
|
end
|
244
244
|
end
|
245
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,255 @@
|
|
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
|
+
config.on_event :undefined_parameter_type, &method(:on_undefined_parameter_type)
|
33
|
+
|
34
|
+
@test_case_by_step_id = {}
|
35
|
+
@current_test_case_started_id = nil
|
36
|
+
@current_test_step_id = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def output_message
|
40
|
+
raise 'To be implemented'
|
41
|
+
end
|
42
|
+
|
43
|
+
def attach(src, media_type)
|
44
|
+
attachment_data = {
|
45
|
+
test_step_id: @current_test_step_id,
|
46
|
+
test_case_started_id: @current_test_case_started_id,
|
47
|
+
media_type: media_type
|
48
|
+
}
|
49
|
+
|
50
|
+
if media_type.start_with?('text/')
|
51
|
+
attachment_data[:content_encoding] = Cucumber::Messages::Attachment::ContentEncoding::IDENTITY
|
52
|
+
attachment_data[:body] = src
|
53
|
+
else
|
54
|
+
body = src.respond_to?(:read) ? src.read : src
|
55
|
+
|
56
|
+
attachment_data[:content_encoding] = Cucumber::Messages::Attachment::ContentEncoding::BASE64
|
57
|
+
attachment_data[:body] = Base64.strict_encode64(body)
|
58
|
+
end
|
59
|
+
|
60
|
+
message = Cucumber::Messages::Envelope.new(
|
61
|
+
attachment: Cucumber::Messages::Attachment.new(**attachment_data)
|
62
|
+
)
|
63
|
+
|
64
|
+
output_envelope(message)
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def on_envelope(event)
|
70
|
+
output_envelope(event.envelope)
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_gherkin_source_read(event)
|
74
|
+
message = Cucumber::Messages::Envelope.new(
|
75
|
+
source: Cucumber::Messages::Source.new(
|
76
|
+
uri: event.path,
|
77
|
+
data: event.body,
|
78
|
+
media_type: 'text/x.cucumber.gherkin+plain'
|
79
|
+
)
|
80
|
+
)
|
81
|
+
|
82
|
+
output_envelope(message)
|
83
|
+
end
|
84
|
+
|
85
|
+
def on_test_case_ready(event)
|
86
|
+
event.test_case.test_steps.each do |step|
|
87
|
+
@test_case_by_step_id[step.id] = event.test_case
|
88
|
+
end
|
89
|
+
|
90
|
+
message = Cucumber::Messages::Envelope.new(
|
91
|
+
test_case: Cucumber::Messages::TestCase.new(
|
92
|
+
id: event.test_case.id,
|
93
|
+
pickle_id: @pickle_by_test.pickle_id(event.test_case),
|
94
|
+
test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) }
|
95
|
+
)
|
96
|
+
)
|
97
|
+
|
98
|
+
output_envelope(message)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_step_to_message(step)
|
102
|
+
return hook_step_to_message(step) if step.hook?
|
103
|
+
|
104
|
+
Cucumber::Messages::TestCase::TestStep.new(
|
105
|
+
id: step.id,
|
106
|
+
pickle_step_id: @pickle_step_by_test_step.pickle_step_id(step),
|
107
|
+
step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
|
108
|
+
step_match_arguments_lists: step_match_arguments_lists(step)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
def hook_step_to_message(step)
|
113
|
+
Cucumber::Messages::TestCase::TestStep.new(
|
114
|
+
id: step.id,
|
115
|
+
hook_id: @hook_by_test_step.hook_id(step)
|
116
|
+
)
|
117
|
+
end
|
118
|
+
|
119
|
+
def step_match_arguments_lists(step)
|
120
|
+
match_arguments = step_match_arguments(step)
|
121
|
+
[Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList.new(
|
122
|
+
step_match_arguments: match_arguments
|
123
|
+
)]
|
124
|
+
rescue Cucumber::Formatter::TestStepUnknownError
|
125
|
+
[]
|
126
|
+
end
|
127
|
+
|
128
|
+
def step_match_arguments(step)
|
129
|
+
@step_definitions_by_test_step.step_match_arguments(step).map do |argument|
|
130
|
+
Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList::StepMatchArgument.new(
|
131
|
+
group: argument_group_to_message(argument.group),
|
132
|
+
parameter_type_name: argument.parameter_type.name
|
133
|
+
)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def argument_group_to_message(group)
|
138
|
+
Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList::StepMatchArgument::Group.new(
|
139
|
+
start: group.start,
|
140
|
+
value: group.value,
|
141
|
+
children: group.children.map { |child| argument_group_to_message(child) }
|
142
|
+
)
|
143
|
+
end
|
144
|
+
|
145
|
+
def on_test_run_started(*)
|
146
|
+
message = Cucumber::Messages::Envelope.new(
|
147
|
+
test_run_started: Cucumber::Messages::TestRunStarted.new(
|
148
|
+
timestamp: time_to_timestamp(Time.now)
|
149
|
+
)
|
150
|
+
)
|
151
|
+
|
152
|
+
output_envelope(message)
|
153
|
+
end
|
154
|
+
|
155
|
+
def on_test_case_started(event)
|
156
|
+
@current_test_case_started_id = test_case_started_id(event.test_case)
|
157
|
+
|
158
|
+
message = Cucumber::Messages::Envelope.new(
|
159
|
+
test_case_started: Cucumber::Messages::TestCaseStarted.new(
|
160
|
+
id: test_case_started_id(event.test_case),
|
161
|
+
test_case_id: event.test_case.id,
|
162
|
+
timestamp: time_to_timestamp(Time.now),
|
163
|
+
attempt: @test_case_started_by_test_case.attempt_by_test_case(event.test_case)
|
164
|
+
)
|
165
|
+
)
|
166
|
+
|
167
|
+
output_envelope(message)
|
168
|
+
end
|
169
|
+
|
170
|
+
def on_test_step_started(event)
|
171
|
+
@current_test_step_id = event.test_step.id
|
172
|
+
test_case = @test_case_by_step_id[event.test_step.id]
|
173
|
+
|
174
|
+
message = Cucumber::Messages::Envelope.new(
|
175
|
+
test_step_started: Cucumber::Messages::TestStepStarted.new(
|
176
|
+
test_step_id: event.test_step.id,
|
177
|
+
test_case_started_id: test_case_started_id(test_case),
|
178
|
+
timestamp: time_to_timestamp(Time.now)
|
179
|
+
)
|
180
|
+
)
|
181
|
+
|
182
|
+
output_envelope(message)
|
183
|
+
end
|
184
|
+
|
185
|
+
def on_test_step_finished(event)
|
186
|
+
test_case = @test_case_by_step_id[event.test_step.id]
|
187
|
+
result = event
|
188
|
+
.result
|
189
|
+
.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
190
|
+
|
191
|
+
result_message = result.to_message
|
192
|
+
if result.failed? || result.pending?
|
193
|
+
result_message = Cucumber::Messages::TestStepFinished::TestStepResult.new(
|
194
|
+
status: result_message.status,
|
195
|
+
duration: result_message.duration,
|
196
|
+
message: create_error_message(result)
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
message = Cucumber::Messages::Envelope.new(
|
201
|
+
test_step_finished: Cucumber::Messages::TestStepFinished.new(
|
202
|
+
test_step_id: event.test_step.id,
|
203
|
+
test_case_started_id: test_case_started_id(test_case),
|
204
|
+
test_step_result: result_message,
|
205
|
+
timestamp: time_to_timestamp(Time.now)
|
206
|
+
)
|
207
|
+
)
|
208
|
+
|
209
|
+
output_envelope(message)
|
210
|
+
end
|
211
|
+
|
212
|
+
def create_error_message(result)
|
213
|
+
message_element = result.failed? ? result.exception : result
|
214
|
+
message = "#{message_element.message} (#{message_element.class})"
|
215
|
+
([message] + message_element.backtrace).join("\n")
|
216
|
+
end
|
217
|
+
|
218
|
+
def on_test_case_finished(event)
|
219
|
+
message = Cucumber::Messages::Envelope.new(
|
220
|
+
test_case_finished: Cucumber::Messages::TestCaseFinished.new(
|
221
|
+
test_case_started_id: test_case_started_id(event.test_case),
|
222
|
+
timestamp: time_to_timestamp(Time.now)
|
223
|
+
)
|
224
|
+
)
|
225
|
+
|
226
|
+
output_envelope(message)
|
227
|
+
end
|
228
|
+
|
229
|
+
def on_test_run_finished(*)
|
230
|
+
message = Cucumber::Messages::Envelope.new(
|
231
|
+
test_run_finished: Cucumber::Messages::TestRunFinished.new(
|
232
|
+
timestamp: time_to_timestamp(Time.now)
|
233
|
+
)
|
234
|
+
)
|
235
|
+
|
236
|
+
output_envelope(message)
|
237
|
+
end
|
238
|
+
|
239
|
+
def on_undefined_parameter_type(event)
|
240
|
+
message = Cucumber::Messages::Envelope.new(
|
241
|
+
undefined_parameter_type: Cucumber::Messages::UndefinedParameterType.new(
|
242
|
+
name: event.type_name,
|
243
|
+
expression: event.expression
|
244
|
+
)
|
245
|
+
)
|
246
|
+
|
247
|
+
output_envelope(message)
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_case_started_id(test_case)
|
251
|
+
@test_case_started_by_test_case.test_case_started_id_by_test_case(test_case)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|