cucumber 11.0.0 → 11.1.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/README.md +15 -6
- data/VERSION +1 -1
- data/lib/cucumber/cli/main.rb +22 -0
- data/lib/cucumber/configuration.rb +4 -0
- data/lib/cucumber/events/attach_called.rb +19 -0
- data/lib/cucumber/events/base.rb +25 -0
- data/lib/cucumber/events/envelope.rb +11 -2
- data/lib/cucumber/events/gherkin_source_parsed.rb +12 -3
- data/lib/cucumber/events/gherkin_source_read.rb +11 -3
- data/lib/cucumber/events/hook_test_step_created.rb +12 -2
- data/lib/cucumber/events/step_activated.rb +13 -7
- data/lib/cucumber/events/step_definition_registered.rb +12 -4
- data/lib/cucumber/events/test_case_created.rb +11 -3
- data/lib/cucumber/events/test_case_finished.rb +12 -4
- data/lib/cucumber/events/test_case_ready.rb +10 -4
- data/lib/cucumber/events/test_case_started.rb +11 -2
- data/lib/cucumber/events/test_run_finished.rb +10 -3
- data/lib/cucumber/events/test_run_hook_finished.rb +11 -3
- data/lib/cucumber/events/test_run_hook_started.rb +10 -1
- data/lib/cucumber/events/test_run_started.rb +11 -2
- data/lib/cucumber/events/test_step_created.rb +12 -2
- data/lib/cucumber/events/test_step_finished.rb +12 -2
- data/lib/cucumber/events/test_step_started.rb +11 -2
- data/lib/cucumber/events/undefined_parameter_type.rb +11 -3
- data/lib/cucumber/events.rb +1 -0
- data/lib/cucumber/filters/fire_before_all_hooks.rb +36 -0
- data/lib/cucumber/formatter/console.rb +19 -11
- data/lib/cucumber/formatter/console_issues.rb +5 -5
- data/lib/cucumber/formatter/duration_extractor.rb +0 -2
- data/lib/cucumber/formatter/fail_fast.rb +3 -4
- data/lib/cucumber/formatter/global_hooks_summary.rb +36 -0
- data/lib/cucumber/formatter/html.rb +6 -4
- data/lib/cucumber/formatter/json.rb +14 -10
- data/lib/cucumber/formatter/junit.rb +4 -6
- data/lib/cucumber/formatter/message.rb +5 -6
- data/lib/cucumber/formatter/message_builder.rb +213 -205
- data/lib/cucumber/formatter/message_handlers.rb +13 -0
- data/lib/cucumber/formatter/pretty.rb +7 -9
- data/lib/cucumber/formatter/progress.rb +1 -2
- data/lib/cucumber/formatter/rerun.rb +12 -5
- data/lib/cucumber/formatter/summary.rb +15 -1
- data/lib/cucumber/formatter/usage.rb +1 -2
- data/lib/cucumber/glue/proto_world.rb +3 -2
- data/lib/cucumber/glue/registry_and_more.rb +98 -9
- data/lib/cucumber/runtime/user_interface.rb +4 -2
- data/lib/cucumber/runtime.rb +38 -17
- metadata +11 -15
- data/lib/cucumber/formatter/errors.rb +0 -9
- data/lib/cucumber/formatter/fanout.rb +0 -28
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +0 -34
- data/lib/cucumber/formatter/query/pickle_by_test.rb +0 -28
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +0 -42
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +0 -45
|
@@ -1,48 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'base64'
|
|
4
|
-
require '
|
|
5
|
-
require 'cucumber/formatter/query/hook_by_test_step'
|
|
6
|
-
require 'cucumber/formatter/query/pickle_by_test'
|
|
7
|
-
require 'cucumber/formatter/query/step_definitions_by_test_step'
|
|
8
|
-
require 'cucumber/formatter/query/test_case_started_by_test_case'
|
|
4
|
+
require 'json'
|
|
9
5
|
|
|
6
|
+
require 'cucumber/formatter/backtrace_filter'
|
|
10
7
|
require 'cucumber/query'
|
|
11
8
|
|
|
9
|
+
require_relative 'message_handlers'
|
|
10
|
+
|
|
12
11
|
module Cucumber
|
|
13
12
|
module Formatter
|
|
14
13
|
class MessageBuilder
|
|
15
14
|
include Cucumber::Messages::Helpers::TimeConversion
|
|
16
15
|
include Io
|
|
16
|
+
include MessageHandlers
|
|
17
|
+
include Console
|
|
17
18
|
|
|
18
19
|
def initialize(config)
|
|
19
20
|
@config = config
|
|
20
|
-
|
|
21
|
-
@hook_by_test_step = Query::HookByTestStep.new(config)
|
|
22
|
-
@pickle_by_test = Query::PickleByTest.new(config)
|
|
23
|
-
@step_definitions_by_test_step = Query::StepDefinitionsByTestStep.new(config)
|
|
24
|
-
@test_case_started_by_test_case = Query::TestCaseStartedByTestCase.new(config)
|
|
25
|
-
|
|
21
|
+
@ast_lookup = AstLookup.new(config)
|
|
26
22
|
@repository = Cucumber::Repository.new
|
|
27
|
-
@query = Cucumber::Query.new(@repository)
|
|
28
23
|
|
|
29
|
-
@test_run_started_id = config.
|
|
24
|
+
@test_run_started_id = config.test_run_started_id
|
|
25
|
+
|
|
26
|
+
# Fake Query objects
|
|
30
27
|
@test_case_by_step_id = {}
|
|
28
|
+
@pickle_id_by_test_case_id = {}
|
|
31
29
|
@pickle_id_step_by_test_step_id = {}
|
|
30
|
+
@hook_id_by_test_step_id = {}
|
|
31
|
+
@step_definition_ids_by_test_step_id = {}
|
|
32
|
+
@step_match_arguments_by_test_step_id = {}
|
|
32
33
|
|
|
33
34
|
# Ensure all handlers for events occur after all ivars are instantiated
|
|
34
35
|
|
|
35
|
-
config.on_event :envelope, &method(:on_envelope)
|
|
36
|
-
|
|
37
36
|
config.on_event :gherkin_source_parsed, &method(:on_gherkin_source_parsed)
|
|
38
|
-
config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
|
|
39
37
|
|
|
40
38
|
config.on_event :hook_test_step_created, &method(:on_hook_test_step_created)
|
|
41
39
|
|
|
42
40
|
config.on_event :step_activated, &method(:on_step_activated)
|
|
43
|
-
config.on_event :step_definition_registered, &method(:on_step_definition_registered)
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
config.on_event :test_case_created, &method(:on_test_case_created)
|
|
46
43
|
config.on_event :test_case_ready, &method(:on_test_case_ready)
|
|
47
44
|
config.on_event :test_case_started, &method(:on_test_case_started)
|
|
48
45
|
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
|
@@ -50,69 +47,75 @@ module Cucumber
|
|
|
50
47
|
config.on_event :test_run_started, &method(:on_test_run_started)
|
|
51
48
|
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
|
52
49
|
|
|
53
|
-
config.on_event :test_run_hook_started, &method(:on_test_run_hook_started)
|
|
54
|
-
config.on_event :test_run_hook_finished, &method(:on_test_run_hook_finished)
|
|
55
|
-
|
|
56
50
|
config.on_event :test_step_created, &method(:on_test_step_created)
|
|
57
51
|
config.on_event :test_step_started, &method(:on_test_step_started)
|
|
58
52
|
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
|
59
53
|
|
|
60
|
-
config.on_event :
|
|
54
|
+
config.on_event :attach_called, &method(:on_attach_called)
|
|
55
|
+
config.on_event :envelope, &method(:on_envelope)
|
|
61
56
|
end
|
|
62
57
|
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
test_case_started_id: @current_test_case_started_id,
|
|
67
|
-
media_type: media_type,
|
|
68
|
-
file_name: filename,
|
|
69
|
-
timestamp: time_to_timestamp(Time.now)
|
|
70
|
-
}
|
|
58
|
+
def on_envelope(event)
|
|
59
|
+
store_current_test_run_hook_started_id(event)
|
|
60
|
+
end
|
|
71
61
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
62
|
+
def on_attach_called(event)
|
|
63
|
+
attachment_data =
|
|
64
|
+
if @current_test_run_hook_started_id.nil?
|
|
65
|
+
{
|
|
66
|
+
test_step_id: @current_test_step_id,
|
|
67
|
+
test_case_started_id: @current_test_case_started_id,
|
|
68
|
+
media_type: event.media_type,
|
|
69
|
+
file_name: event.filename,
|
|
70
|
+
timestamp: time_to_timestamp(Time.now)
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
{
|
|
74
|
+
test_run_hook_started_id: @current_test_run_hook_started_id,
|
|
75
|
+
media_type: event.media_type,
|
|
76
|
+
file_name: event.filename,
|
|
77
|
+
timestamp: time_to_timestamp(Time.now)
|
|
78
|
+
}
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
streamed_file = event.src.encoding == Encoding::BINARY
|
|
82
|
+
|
|
83
|
+
if streamed_file
|
|
77
84
|
attachment_data[:content_encoding] = Cucumber::Messages::AttachmentContentEncoding::BASE64
|
|
78
|
-
attachment_data[:body] = Base64.strict_encode64(
|
|
85
|
+
attachment_data[:body] = Base64.strict_encode64(event.src)
|
|
86
|
+
else
|
|
87
|
+
attachment_data[:content_encoding] = Cucumber::Messages::AttachmentContentEncoding::IDENTITY
|
|
88
|
+
attachment_data[:body] = event.src.is_a?(Hash) ? event.src.to_json : event.src
|
|
79
89
|
end
|
|
80
90
|
|
|
81
91
|
message = Cucumber::Messages::Envelope.new(attachment: Cucumber::Messages::Attachment.new(**attachment_data))
|
|
82
|
-
|
|
92
|
+
@config.event_bus.envelope(message)
|
|
83
93
|
end
|
|
84
94
|
|
|
85
95
|
private
|
|
86
96
|
|
|
87
|
-
def on_envelope(event)
|
|
88
|
-
output_envelope(event.envelope)
|
|
89
|
-
end
|
|
90
|
-
|
|
91
97
|
def on_gherkin_source_parsed(_event)
|
|
92
98
|
# TODO: Handle GherkinSourceParsed
|
|
93
99
|
end
|
|
94
100
|
|
|
95
|
-
def
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
uri: event.path,
|
|
99
|
-
data: event.body,
|
|
100
|
-
media_type: 'text/x.cucumber.gherkin+plain'
|
|
101
|
-
)
|
|
102
|
-
)
|
|
101
|
+
def on_hook_test_step_created(event)
|
|
102
|
+
@hook_id_by_test_step_id[event.test_step.id] = event.hook.id
|
|
103
|
+
end
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
def on_step_activated(event)
|
|
106
|
+
@step_definition_ids_by_test_step_id[event.test_step.id] << event.step_match.step_definition.id
|
|
107
|
+
@step_match_arguments_by_test_step_id[event.test_step.id] = event.step_match.step_arguments
|
|
105
108
|
end
|
|
106
109
|
|
|
107
|
-
def
|
|
108
|
-
|
|
110
|
+
def on_test_case_created(event)
|
|
111
|
+
@pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id
|
|
109
112
|
end
|
|
110
113
|
|
|
111
114
|
def on_test_case_ready(event)
|
|
112
115
|
message = Cucumber::Messages::Envelope.new(
|
|
113
116
|
test_case: Cucumber::Messages::TestCase.new(
|
|
114
117
|
id: event.test_case.id,
|
|
115
|
-
pickle_id:
|
|
118
|
+
pickle_id: fake_query_pickle_id(event.test_case),
|
|
116
119
|
test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) },
|
|
117
120
|
test_run_started_id: @test_run_started_id
|
|
118
121
|
)
|
|
@@ -121,63 +124,56 @@ module Cucumber
|
|
|
121
124
|
# TODO: This may be a redundant update. But for now we're leaving this in whilst we're in the transitory phase
|
|
122
125
|
@repository.update(message)
|
|
123
126
|
|
|
124
|
-
|
|
125
|
-
# TODO: The finder in query is `find_test_step_by` (Using +TestStepStarted+ message)
|
|
126
|
-
event.test_case.test_steps.each do |step|
|
|
127
|
-
@test_case_by_step_id[step.id] = event.test_case
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
output_envelope(message)
|
|
127
|
+
@config.event_bus.envelope(message)
|
|
131
128
|
end
|
|
132
129
|
|
|
133
|
-
def
|
|
134
|
-
|
|
130
|
+
def on_test_case_started(event)
|
|
131
|
+
# For any new test_case_started events, we must ALWAYS generate a new id for a new run
|
|
132
|
+
@current_test_case_started_id = @config.id_generator.new_id
|
|
133
|
+
@current_test_run_hook_started_id = nil
|
|
135
134
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
pickle_step_id: @pickle_id_step_by_test_step_id[step.id],
|
|
141
|
-
step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
|
|
142
|
-
step_match_arguments_lists: step_match_arguments_lists(step)
|
|
143
|
-
)
|
|
144
|
-
end
|
|
135
|
+
find_all_test_case_started_by_test_case_id =
|
|
136
|
+
@repository.test_case_started_by_id
|
|
137
|
+
.values
|
|
138
|
+
.select { |test_case_started| test_case_started.test_case_id == event.test_case.id }
|
|
145
139
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
140
|
+
# If no TestCaseStarted messages exist. We must be on attempt 1 (Hence the .to_i casting for a `nil` value)
|
|
141
|
+
attempts_previously_made = find_all_test_case_started_by_test_case_id.map(&:attempt).max.to_i
|
|
142
|
+
|
|
143
|
+
message = Cucumber::Messages::Envelope.new(
|
|
144
|
+
test_case_started: Cucumber::Messages::TestCaseStarted.new(
|
|
145
|
+
id: @current_test_case_started_id,
|
|
146
|
+
test_case_id: event.test_case.id,
|
|
147
|
+
timestamp: time_to_timestamp(Time.now),
|
|
148
|
+
attempt: attempts_previously_made + 1
|
|
149
|
+
)
|
|
150
150
|
)
|
|
151
|
-
end
|
|
152
151
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
[Cucumber::Messages::StepMatchArgumentsList.new(
|
|
156
|
-
step_match_arguments: match_arguments
|
|
157
|
-
)]
|
|
158
|
-
rescue Cucumber::Formatter::TestStepUnknownError
|
|
159
|
-
[]
|
|
152
|
+
@config.event_bus.envelope(message)
|
|
153
|
+
@repository.update(message)
|
|
160
154
|
end
|
|
161
155
|
|
|
162
|
-
def
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
end
|
|
169
|
-
end
|
|
156
|
+
def on_test_case_finished(event)
|
|
157
|
+
test_case_started_id =
|
|
158
|
+
@repository.test_case_started_by_id
|
|
159
|
+
.values
|
|
160
|
+
.detect { |test_case_started_message| test_case_started_message.test_case_id == event.test_case.id }
|
|
161
|
+
.id
|
|
170
162
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
163
|
+
test_case_started_message = @repository.test_case_started_by_id[test_case_started_id]
|
|
164
|
+
max_attempts = @config.retry_attempts
|
|
165
|
+
retries_attempted = test_case_started_message.attempt - 1
|
|
166
|
+
will_be_retried = event.result.failed? && (retries_attempted < max_attempts)
|
|
167
|
+
|
|
168
|
+
message = Cucumber::Messages::Envelope.new(
|
|
169
|
+
test_case_finished: Cucumber::Messages::TestCaseFinished.new(
|
|
170
|
+
test_case_started_id: test_case_started_id,
|
|
171
|
+
timestamp: time_to_timestamp(Time.now),
|
|
172
|
+
will_be_retried: will_be_retried
|
|
173
|
+
)
|
|
176
174
|
)
|
|
177
|
-
end
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
step_match_argument.parameter_type&.name if step_match_argument.respond_to?(:parameter_type)
|
|
176
|
+
@config.event_bus.envelope(message)
|
|
181
177
|
end
|
|
182
178
|
|
|
183
179
|
def on_test_run_started(*)
|
|
@@ -188,63 +184,63 @@ module Cucumber
|
|
|
188
184
|
)
|
|
189
185
|
)
|
|
190
186
|
|
|
191
|
-
|
|
187
|
+
@config.event_bus.envelope(message)
|
|
192
188
|
end
|
|
193
189
|
|
|
194
|
-
def
|
|
195
|
-
@current_test_case_started_id = test_case_started_id(event.test_case)
|
|
196
|
-
|
|
190
|
+
def on_test_run_finished(event)
|
|
197
191
|
message = Cucumber::Messages::Envelope.new(
|
|
198
|
-
|
|
199
|
-
id: test_case_started_id(event.test_case),
|
|
200
|
-
test_case_id: event.test_case.id,
|
|
192
|
+
test_run_finished: Cucumber::Messages::TestRunFinished.new(
|
|
201
193
|
timestamp: time_to_timestamp(Time.now),
|
|
202
|
-
|
|
194
|
+
success: event.success,
|
|
195
|
+
test_run_started_id: @test_run_started_id
|
|
203
196
|
)
|
|
204
197
|
)
|
|
205
198
|
|
|
206
|
-
|
|
199
|
+
@config.event_bus.envelope(message)
|
|
207
200
|
end
|
|
208
201
|
|
|
209
202
|
def on_test_step_created(event)
|
|
210
203
|
@pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id
|
|
211
|
-
|
|
212
|
-
# TODO: We need to determine what message to output here (Unsure - Placeholder added)
|
|
213
|
-
# message = Cucumber::Messages::Envelope.new(
|
|
214
|
-
# pickle: {
|
|
215
|
-
# id: '',
|
|
216
|
-
# uri: '',
|
|
217
|
-
# location: nil,
|
|
218
|
-
# name: '',
|
|
219
|
-
# language: '',
|
|
220
|
-
# steps: test_step_to_message(event.test_step),
|
|
221
|
-
# tags: [],
|
|
222
|
-
# ast_node_ids: []
|
|
223
|
-
# }
|
|
224
|
-
# )
|
|
225
|
-
#
|
|
226
|
-
# output_envelope(message)
|
|
204
|
+
@step_definition_ids_by_test_step_id[event.test_step.id] = []
|
|
227
205
|
end
|
|
228
206
|
|
|
229
207
|
def on_test_step_started(event)
|
|
230
208
|
@current_test_step_id = event.test_step.id
|
|
231
|
-
|
|
209
|
+
find_test_case_by_step_id =
|
|
210
|
+
@repository.test_case_by_id
|
|
211
|
+
.values
|
|
212
|
+
.detect { |test_case_message| test_case_message.test_steps.any? { |step_message| step_message.id == event.test_step.id } }
|
|
213
|
+
|
|
214
|
+
find_test_case_started_by_test_case =
|
|
215
|
+
@repository.test_case_started_by_id
|
|
216
|
+
.values
|
|
217
|
+
.select { |test_case_started_message| test_case_started_message.test_case_id == find_test_case_by_step_id.id }
|
|
218
|
+
.max_by(&:attempt)
|
|
232
219
|
|
|
233
220
|
message = Cucumber::Messages::Envelope.new(
|
|
234
221
|
test_step_started: Cucumber::Messages::TestStepStarted.new(
|
|
235
222
|
test_step_id: event.test_step.id,
|
|
236
|
-
test_case_started_id:
|
|
223
|
+
test_case_started_id: find_test_case_started_by_test_case.id,
|
|
237
224
|
timestamp: time_to_timestamp(Time.now)
|
|
238
225
|
)
|
|
239
226
|
)
|
|
240
227
|
|
|
241
|
-
|
|
228
|
+
@config.event_bus.envelope(message)
|
|
242
229
|
end
|
|
243
230
|
|
|
244
231
|
def on_test_step_finished(event)
|
|
245
|
-
|
|
246
|
-
|
|
232
|
+
find_test_case_by_step_id =
|
|
233
|
+
@repository.test_case_by_id
|
|
234
|
+
.values
|
|
235
|
+
.detect { |test_case_message| test_case_message.test_steps.any? { |step_message| step_message.id == event.test_step.id } }
|
|
236
|
+
|
|
237
|
+
find_test_case_started_by_test_case =
|
|
238
|
+
@repository.test_case_started_by_id
|
|
239
|
+
.values
|
|
240
|
+
.select { |test_case_started_message| test_case_started_message.test_case_id == find_test_case_by_step_id.id }
|
|
241
|
+
.max_by(&:attempt)
|
|
247
242
|
|
|
243
|
+
result = event.result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
|
248
244
|
result_message = result.to_message
|
|
249
245
|
if result.failed? || result.pending?
|
|
250
246
|
message_element = result.failed? ? result.exception : result
|
|
@@ -257,126 +253,138 @@ module Cucumber
|
|
|
257
253
|
)
|
|
258
254
|
end
|
|
259
255
|
|
|
256
|
+
output_snippet_envelope(event)
|
|
257
|
+
|
|
260
258
|
message = Cucumber::Messages::Envelope.new(
|
|
261
259
|
test_step_finished: Cucumber::Messages::TestStepFinished.new(
|
|
262
260
|
test_step_id: event.test_step.id,
|
|
263
|
-
test_case_started_id:
|
|
261
|
+
test_case_started_id: find_test_case_started_by_test_case.id,
|
|
264
262
|
test_step_result: result_message,
|
|
265
263
|
timestamp: time_to_timestamp(Time.now)
|
|
266
264
|
)
|
|
267
265
|
)
|
|
268
266
|
|
|
269
|
-
|
|
267
|
+
@config.event_bus.envelope(message)
|
|
270
268
|
end
|
|
271
269
|
|
|
272
|
-
def
|
|
273
|
-
|
|
274
|
-
#{message_element.message} (#{message_element.class})
|
|
275
|
-
#{message_element.backtrace}
|
|
276
|
-
ERROR_MESSAGE
|
|
277
|
-
end
|
|
270
|
+
def output_snippet_envelope(event)
|
|
271
|
+
return unless event.result.undefined?
|
|
278
272
|
|
|
279
|
-
|
|
280
|
-
|
|
273
|
+
collect_snippet_data(event.test_step, @ast_lookup)
|
|
274
|
+
snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
|
|
275
|
+
snippet_text(step_keyword, step_name, multiline_arg)
|
|
276
|
+
end
|
|
281
277
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
)
|
|
278
|
+
message = generate_snippet_envelope(snippet_text_proc, event)
|
|
279
|
+
@config.event_bus.envelope(message)
|
|
280
|
+
# To ensure we don't redistribute the "same" snippets over and over again
|
|
281
|
+
snippets_input.clear
|
|
287
282
|
end
|
|
288
283
|
|
|
289
|
-
def
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
# See "fake query" for reason this is index shifted
|
|
294
|
-
retries_attempted = test_case_started_message.attempt - 1
|
|
295
|
-
will_be_retried = event.result.failed? && (retries_attempted < max_attempts)
|
|
284
|
+
def generate_snippet_envelope(snippet_text_proc, event)
|
|
285
|
+
snippets_array = snippets_input.map do |data|
|
|
286
|
+
snippet_text_proc.call(data.actual_keyword, data.step.text, data.step.multiline_arg)
|
|
287
|
+
end.uniq
|
|
296
288
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
289
|
+
Cucumber::Messages::Envelope.new(
|
|
290
|
+
suggestion: Cucumber::Messages::Suggestion.new(
|
|
291
|
+
id: @config.id_generator.new_id,
|
|
292
|
+
pickle_step_id: @repository.test_step_by_id[event.test_step.id].pickle_step_id,
|
|
293
|
+
snippets: snippets_array.map { |code_snippet| Cucumber::Messages::Snippet.new(language: 'ruby', code: code_snippet) }
|
|
302
294
|
)
|
|
303
295
|
)
|
|
304
|
-
|
|
305
|
-
output_envelope(message)
|
|
306
296
|
end
|
|
307
297
|
|
|
308
|
-
def
|
|
298
|
+
def on_undefined_parameter_type(event)
|
|
309
299
|
message = Cucumber::Messages::Envelope.new(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
test_run_started_id: @test_run_started_id
|
|
300
|
+
undefined_parameter_type: Cucumber::Messages::UndefinedParameterType.new(
|
|
301
|
+
name: event.type_name,
|
|
302
|
+
expression: event.expression
|
|
314
303
|
)
|
|
315
304
|
)
|
|
316
305
|
|
|
317
|
-
|
|
306
|
+
@config.event_bus.envelope(message)
|
|
318
307
|
end
|
|
319
308
|
|
|
320
|
-
def
|
|
321
|
-
|
|
309
|
+
def test_step_to_message(step)
|
|
310
|
+
return hook_step_to_message(step) if step.hook?
|
|
311
|
+
|
|
312
|
+
Cucumber::Messages::TestStep.new(
|
|
313
|
+
id: step.id,
|
|
314
|
+
pickle_step_id: @pickle_id_step_by_test_step_id[step.id],
|
|
315
|
+
step_definition_ids: fake_query_step_definition_ids(step),
|
|
316
|
+
step_match_arguments_lists: step_match_arguments_lists(step)
|
|
317
|
+
)
|
|
322
318
|
end
|
|
323
319
|
|
|
324
|
-
def
|
|
325
|
-
|
|
320
|
+
def hook_step_to_message(step)
|
|
321
|
+
Cucumber::Messages::TestStep.new(
|
|
322
|
+
id: step.id,
|
|
323
|
+
hook_id: @hook_id_by_test_step_id[step.id]
|
|
324
|
+
)
|
|
326
325
|
end
|
|
327
326
|
|
|
328
|
-
def
|
|
329
|
-
|
|
327
|
+
def step_match_arguments_lists(step)
|
|
328
|
+
match_arguments = step_match_arguments(step)
|
|
329
|
+
if match_arguments.nil?
|
|
330
|
+
[]
|
|
331
|
+
else
|
|
332
|
+
[Cucumber::Messages::StepMatchArgumentsList.new(step_match_arguments: match_arguments)]
|
|
333
|
+
end
|
|
334
|
+
end
|
|
330
335
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
timestamp: time_to_timestamp(Time.now)
|
|
336
|
+
def step_match_arguments(step)
|
|
337
|
+
fake_query_step_match_arguments(step)&.map do |argument|
|
|
338
|
+
Cucumber::Messages::StepMatchArgument.new(
|
|
339
|
+
group: argument_group_to_message(argument.group),
|
|
340
|
+
parameter_type_name: parameter_type_name(argument)
|
|
337
341
|
)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
def argument_group_to_message(group)
|
|
346
|
+
Cucumber::Messages::Group.new(
|
|
347
|
+
start: group.start,
|
|
348
|
+
value: group.value,
|
|
349
|
+
children: group.children&.map { |child| argument_group_to_message(child) }
|
|
338
350
|
)
|
|
351
|
+
end
|
|
339
352
|
|
|
340
|
-
|
|
353
|
+
def parameter_type_name(step_match_argument)
|
|
354
|
+
step_match_argument.parameter_type&.name if step_match_argument.respond_to?(:parameter_type)
|
|
341
355
|
end
|
|
342
356
|
|
|
343
|
-
def
|
|
344
|
-
|
|
345
|
-
|
|
357
|
+
def create_error_message(message_element)
|
|
358
|
+
<<~ERROR_MESSAGE
|
|
359
|
+
#{message_element.message} (#{message_element.class})
|
|
360
|
+
#{message_element.backtrace}
|
|
361
|
+
ERROR_MESSAGE
|
|
362
|
+
end
|
|
346
363
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
status: result_message.status,
|
|
350
|
-
duration: result_message.duration,
|
|
351
|
-
message: create_error_message(result.exception),
|
|
352
|
-
exception: create_exception_object(result, result.exception)
|
|
353
|
-
)
|
|
354
|
-
end
|
|
364
|
+
def create_exception_object(result, message_element)
|
|
365
|
+
return unless result.failed?
|
|
355
366
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
result: result_message
|
|
361
|
-
)
|
|
367
|
+
Cucumber::Messages::Exception.new(
|
|
368
|
+
type: message_element.class,
|
|
369
|
+
message: message_element.message,
|
|
370
|
+
stack_trace: message_element.backtrace.join("\n")
|
|
362
371
|
)
|
|
372
|
+
end
|
|
363
373
|
|
|
364
|
-
|
|
374
|
+
def fake_query_hook_id(test_step)
|
|
375
|
+
@hook_id_by_test_step_id.fetch(test_step.id)
|
|
365
376
|
end
|
|
366
377
|
|
|
367
|
-
def
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
name: event.type_name,
|
|
371
|
-
expression: event.expression
|
|
372
|
-
)
|
|
373
|
-
)
|
|
378
|
+
def fake_query_pickle_id(test_case)
|
|
379
|
+
@pickle_id_by_test_case_id.fetch(test_case.id)
|
|
380
|
+
end
|
|
374
381
|
|
|
375
|
-
|
|
382
|
+
def fake_query_step_definition_ids(test_step)
|
|
383
|
+
@step_definition_ids_by_test_step_id.fetch(test_step.id)
|
|
376
384
|
end
|
|
377
385
|
|
|
378
|
-
def
|
|
379
|
-
@
|
|
386
|
+
def fake_query_step_match_arguments(test_step)
|
|
387
|
+
@step_match_arguments_by_test_step_id.fetch(test_step.id, nil)
|
|
380
388
|
end
|
|
381
389
|
end
|
|
382
390
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Cucumber
|
|
4
|
+
module Formatter
|
|
5
|
+
# Common Message Handlers to be used across all message-based formatters
|
|
6
|
+
# Designed to work solely with events of type `Envelope`
|
|
7
|
+
module MessageHandlers
|
|
8
|
+
def store_current_test_run_hook_started_id(event)
|
|
9
|
+
@current_test_run_hook_started_id = event.envelope.test_run_hook_started.id if event.envelope.test_run_hook_started
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -33,8 +33,6 @@ module Cucumber
|
|
|
33
33
|
@io = ensure_io(config.out_stream, config.error_stream)
|
|
34
34
|
@config = config
|
|
35
35
|
@options = config.to_hash
|
|
36
|
-
@snippets_input = []
|
|
37
|
-
@undefined_parameter_types = []
|
|
38
36
|
@total_duration = 0
|
|
39
37
|
@exceptions = []
|
|
40
38
|
@gherkin_sources = {}
|
|
@@ -66,6 +64,7 @@ module Cucumber
|
|
|
66
64
|
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
|
67
65
|
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
|
68
66
|
config.on_event :undefined_parameter_type, &method(:collect_undefined_parameter_type_names)
|
|
67
|
+
config.on_event :attach_called, &method(:on_attach_called)
|
|
69
68
|
end
|
|
70
69
|
|
|
71
70
|
def on_gherkin_source_read(event)
|
|
@@ -73,8 +72,7 @@ module Cucumber
|
|
|
73
72
|
end
|
|
74
73
|
|
|
75
74
|
def on_step_activated(event)
|
|
76
|
-
test_step
|
|
77
|
-
@step_matches[test_step.to_s] = step_match
|
|
75
|
+
@step_matches[event.test_step.to_s] = event.step_match
|
|
78
76
|
end
|
|
79
77
|
|
|
80
78
|
def on_test_case_started(event)
|
|
@@ -140,13 +138,13 @@ module Cucumber
|
|
|
140
138
|
print_summary
|
|
141
139
|
end
|
|
142
140
|
|
|
143
|
-
def
|
|
144
|
-
return unless media_type == 'text/x.cucumber.log+plain'
|
|
141
|
+
def on_attach_called(event)
|
|
142
|
+
return unless event.media_type == 'text/x.cucumber.log+plain'
|
|
145
143
|
|
|
146
|
-
if filename
|
|
147
|
-
@test_step_output.push("#{filename}: #{src}")
|
|
144
|
+
if event.filename
|
|
145
|
+
@test_step_output.push("#{event.filename}: #{event.src}")
|
|
148
146
|
else
|
|
149
|
-
@test_step_output.push(src)
|
|
147
|
+
@test_step_output.push(event.src)
|
|
150
148
|
end
|
|
151
149
|
end
|
|
152
150
|
|
|
@@ -20,8 +20,6 @@ module Cucumber
|
|
|
20
20
|
def initialize(config)
|
|
21
21
|
@config = config
|
|
22
22
|
@io = ensure_io(config.out_stream, config.error_stream)
|
|
23
|
-
@snippets_input = []
|
|
24
|
-
@undefined_parameter_types = []
|
|
25
23
|
@total_duration = 0
|
|
26
24
|
@matches = {}
|
|
27
25
|
@pending_step_matches = []
|
|
@@ -38,6 +36,7 @@ module Cucumber
|
|
|
38
36
|
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
|
39
37
|
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
|
40
38
|
config.on_event :undefined_parameter_type, &method(:collect_undefined_parameter_type_names)
|
|
39
|
+
config.on_event :attach_called, &method(:on_attach_called)
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def on_step_activated(event)
|