cucumber 6.0.0 → 8.0.0.rc.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/CHANGELOG.md +371 -168
- data/CONTRIBUTING.md +216 -55
- data/README.md +139 -21
- data/lib/autotest/cucumber_mixin.rb +5 -2
- data/lib/autotest/discover.rb +3 -2
- data/lib/cucumber/cli/configuration.rb +4 -1
- data/lib/cucumber/cli/main.rb +4 -3
- data/lib/cucumber/cli/options.rb +14 -4
- data/lib/cucumber/cli/profile_loader.rb +1 -5
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/configuration.rb +5 -4
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/deprecate.rb +2 -1
- data/lib/cucumber/errors.rb +1 -1
- data/lib/cucumber/events/hook_test_step_created.rb +1 -2
- data/lib/cucumber/events/step_activated.rb +0 -6
- data/lib/cucumber/events/step_definition_registered.rb +0 -5
- data/lib/cucumber/events/test_case_created.rb +1 -2
- data/lib/cucumber/events/test_run_finished.rb +2 -1
- data/lib/cucumber/events/test_step_created.rb +1 -2
- data/lib/cucumber/events/undefined_parameter_type.rb +1 -2
- data/lib/cucumber/events.rb +2 -2
- data/lib/cucumber/file_specs.rb +2 -1
- data/lib/cucumber/filters/activate_steps.rb +1 -0
- data/lib/cucumber/filters/tag_limits/verifier.rb +1 -3
- data/lib/cucumber/filters/tag_limits.rb +1 -3
- data/lib/cucumber/formatter/ansicolor.rb +63 -70
- data/lib/cucumber/formatter/ast_lookup.rb +2 -2
- data/lib/cucumber/formatter/backtrace_filter.rb +1 -1
- data/lib/cucumber/formatter/console.rb +20 -4
- data/lib/cucumber/formatter/console_issues.rb +6 -1
- data/lib/cucumber/formatter/duration_extractor.rb +1 -0
- data/lib/cucumber/formatter/errors.rb +1 -0
- data/lib/cucumber/formatter/fanout.rb +1 -1
- data/lib/cucumber/formatter/http_io.rb +6 -1
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/io.rb +3 -1
- data/lib/cucumber/formatter/json.rb +32 -26
- data/lib/cucumber/formatter/junit.rb +6 -3
- data/lib/cucumber/formatter/message.rb +2 -1
- data/lib/cucumber/formatter/message_builder.rb +11 -10
- data/lib/cucumber/formatter/pretty.rb +34 -23
- data/lib/cucumber/formatter/progress.rb +1 -0
- data/lib/cucumber/formatter/publish_banner_printer.rb +1 -1
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +1 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +2 -0
- data/lib/cucumber/formatter/rerun.rb +2 -0
- data/lib/cucumber/formatter/steps.rb +5 -2
- data/lib/cucumber/formatter/summary.rb +1 -0
- data/lib/cucumber/formatter/unicode.rb +4 -4
- data/lib/cucumber/formatter/usage.rb +9 -7
- data/lib/cucumber/gherkin/data_table_parser.rb +2 -1
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +1 -1
- data/lib/cucumber/glue/dsl.rb +19 -5
- data/lib/cucumber/glue/hook.rb +2 -1
- data/lib/cucumber/glue/invoke_in_world.rb +4 -4
- data/lib/cucumber/glue/proto_world.rb +12 -9
- data/lib/cucumber/glue/registry_and_more.rb +20 -5
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/step_definition.rb +9 -7
- data/lib/cucumber/hooks.rb +1 -0
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +2 -1
- data/lib/cucumber/multiline_argument/data_table.rb +58 -71
- data/lib/cucumber/platform.rb +2 -2
- data/lib/cucumber/rake/task.rb +10 -7
- data/lib/cucumber/rspec/disable_option_parser.rb +6 -3
- data/lib/cucumber/running_test_case.rb +1 -0
- data/lib/cucumber/runtime/meta_message_builder.rb +106 -0
- data/lib/cucumber/runtime/support_code.rb +3 -0
- data/lib/cucumber/runtime/user_interface.rb +5 -4
- data/lib/cucumber/runtime.rb +42 -23
- data/lib/cucumber/step_match.rb +6 -10
- data/lib/cucumber/step_match_search.rb +3 -2
- data/lib/cucumber/term/ansicolor.rb +74 -50
- data/lib/cucumber/term/banner.rb +1 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +2 -1
- data/lib/simplecov_setup.rb +1 -1
- metadata +90 -89
- data/lib/cucumber/core_ext/string.rb +0 -11
@@ -21,7 +21,7 @@ module Cucumber
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def respond_to_missing?(name, include_private = false)
|
24
|
-
recipients.any? { |recipient| recipient.respond_to?(name, include_private) }
|
24
|
+
recipients.any? { |recipient| recipient.respond_to?(name, include_private) } || super(name, include_private)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -35,6 +35,7 @@ module Cucumber
|
|
35
35
|
headers = headers.merge(parse_header(header_arg))
|
36
36
|
else
|
37
37
|
raise StandardError, "#{options} was not a valid curl command. Can't set url to #{arg} it is already set to #{url}" if url
|
38
|
+
|
38
39
|
url = arg
|
39
40
|
end
|
40
41
|
end
|
@@ -49,12 +50,14 @@ module Cucumber
|
|
49
50
|
|
50
51
|
def self.remove_arg_for(args, arg)
|
51
52
|
return args.shift unless args.empty?
|
53
|
+
|
52
54
|
raise StandardError, "Missing argument for #{arg}"
|
53
55
|
end
|
54
56
|
|
55
57
|
def self.parse_header(header_arg)
|
56
58
|
parts = header_arg.split(':', 2)
|
57
59
|
raise StandardError, "#{header_arg} was not a valid header" unless parts.length == 2
|
60
|
+
|
58
61
|
{ parts[0].strip => parts[1].strip }
|
59
62
|
end
|
60
63
|
end
|
@@ -76,6 +79,7 @@ module Cucumber
|
|
76
79
|
@reporter.report(response.body)
|
77
80
|
@write_io.close
|
78
81
|
return if response.is_a?(Net::HTTPSuccess) || response.is_a?(Net::HTTPRedirection)
|
82
|
+
|
79
83
|
raise StandardError, "request to #{uri} failed with status #{response.code}"
|
80
84
|
end
|
81
85
|
|
@@ -98,6 +102,7 @@ module Cucumber
|
|
98
102
|
http = build_client(uri, @https_verify_mode)
|
99
103
|
|
100
104
|
raise StandardError, "request to #{uri} failed (too many redirections)" if attempt <= 0
|
105
|
+
|
101
106
|
req = build_request(
|
102
107
|
uri,
|
103
108
|
method,
|
@@ -126,7 +131,7 @@ module Cucumber
|
|
126
131
|
end
|
127
132
|
|
128
133
|
def build_request(uri, method, headers)
|
129
|
-
method_class_name = "#{method[0].upcase}#{method[1
|
134
|
+
method_class_name = "#{method[0].upcase}#{method[1..].downcase}"
|
130
135
|
req = Net::HTTP.const_get(method_class_name).new(uri)
|
131
136
|
headers.each do |header, value|
|
132
137
|
req[header] = value
|
@@ -57,19 +57,21 @@ module Cucumber
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def url?(path_or_url_or_io)
|
60
|
-
path_or_url_or_io.match(
|
60
|
+
path_or_url_or_io.match(/^https?:\/\//)
|
61
61
|
end
|
62
62
|
|
63
63
|
def ensure_file(path, name)
|
64
64
|
raise "You *must* specify --out FILE for the #{name} formatter" unless String == path.class
|
65
65
|
raise "I can't write #{name} to a directory - it has to be a file" if File.directory?(path)
|
66
66
|
raise "I can't write #{name} to a file in the non-existing directory #{File.dirname(path)}" unless File.directory?(File.dirname(path))
|
67
|
+
|
67
68
|
ensure_io(path, nil)
|
68
69
|
end
|
69
70
|
|
70
71
|
def ensure_dir(path, name)
|
71
72
|
raise "You *must* specify --out DIR for the #{name} formatter" unless String == path.class
|
72
73
|
raise "I can't write #{name} reports to a file - it has to be a directory" if File.file?(path)
|
74
|
+
|
73
75
|
FileUtils.mkdir_p(path) unless File.directory?(path)
|
74
76
|
File.absolute_path path
|
75
77
|
end
|
@@ -5,7 +5,6 @@ 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'
|
9
8
|
|
10
9
|
module Cucumber
|
11
10
|
module Formatter
|
@@ -14,14 +13,6 @@ module Cucumber
|
|
14
13
|
include Io
|
15
14
|
|
16
15
|
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
|
-
'6.0.0'
|
23
|
-
)
|
24
|
-
|
25
16
|
@io = ensure_io(config.out_stream, config.error_stream)
|
26
17
|
@ast_lookup = AstLookup.new(config)
|
27
18
|
@feature_hashes = []
|
@@ -41,21 +32,23 @@ module Cucumber
|
|
41
32
|
@feature_hashes << @feature_hash
|
42
33
|
end
|
43
34
|
@test_case_hash = builder.test_case_hash
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
@in_background = false
|
50
|
-
feature_elements << @test_case_hash
|
51
|
-
@element_hash = @test_case_hash
|
52
|
-
end
|
35
|
+
|
36
|
+
@element_hash = nil
|
37
|
+
@element_background_hash = builder.background_hash
|
38
|
+
@in_background = builder.background?
|
39
|
+
|
53
40
|
@any_step_failed = false
|
54
41
|
end
|
55
42
|
|
56
43
|
def on_test_step_started(event)
|
57
44
|
test_step = event.test_step
|
58
45
|
return if internal_hook?(test_step)
|
46
|
+
|
47
|
+
if @element_hash.nil?
|
48
|
+
@element_hash = create_element_hash(test_step)
|
49
|
+
feature_elements << @element_hash
|
50
|
+
end
|
51
|
+
|
59
52
|
if test_step.hook?
|
60
53
|
@step_or_hook_hash = {}
|
61
54
|
hooks_of_type(test_step) << @step_or_hook_hash
|
@@ -75,18 +68,21 @@ module Cucumber
|
|
75
68
|
test_step, result = *event.attributes
|
76
69
|
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
77
70
|
return if internal_hook?(test_step)
|
71
|
+
|
78
72
|
add_match_and_result(test_step, result)
|
79
73
|
@any_step_failed = true if result.failed?
|
80
74
|
end
|
81
75
|
|
82
76
|
def on_test_case_finished(event)
|
77
|
+
feature_elements << @test_case_hash if @in_background
|
78
|
+
|
83
79
|
_test_case, result = *event.attributes
|
84
80
|
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
85
81
|
add_failed_around_hook(result) if result.failed? && !@any_step_failed
|
86
82
|
end
|
87
83
|
|
88
84
|
def on_test_run_finished(_event)
|
89
|
-
@io.write(JSON.
|
85
|
+
@io.write(JSON.pretty_generate(@feature_hashes))
|
90
86
|
end
|
91
87
|
|
92
88
|
def attach(src, mime_type)
|
@@ -110,7 +106,7 @@ module Cucumber
|
|
110
106
|
end
|
111
107
|
|
112
108
|
def first_step_after_background?(test_step)
|
113
|
-
@in_background && test_step.location.lines.max >= @test_case_hash[:line]
|
109
|
+
@in_background && test_step.location.file == @feature_hash[:uri] && test_step.location.lines.max >= @test_case_hash[:line]
|
114
110
|
end
|
115
111
|
|
116
112
|
def internal_hook?(test_step)
|
@@ -138,7 +134,7 @@ module Cucumber
|
|
138
134
|
when 'AfterStep hook'
|
139
135
|
after_step_hooks
|
140
136
|
else
|
141
|
-
raise
|
137
|
+
raise "Unknown hook type #{hook_step}"
|
142
138
|
end
|
143
139
|
end
|
144
140
|
|
@@ -166,6 +162,13 @@ module Cucumber
|
|
166
162
|
@step_or_hook_hash[:embeddings] ||= []
|
167
163
|
end
|
168
164
|
|
165
|
+
def create_element_hash(test_step)
|
166
|
+
return @element_background_hash if @in_background && !first_step_after_background?(test_step)
|
167
|
+
|
168
|
+
@in_background = false
|
169
|
+
@test_case_hash
|
170
|
+
end
|
171
|
+
|
169
172
|
def create_step_hash(test_step)
|
170
173
|
step_source = @ast_lookup.step_source(test_step).step
|
171
174
|
step_hash = {
|
@@ -173,15 +176,15 @@ module Cucumber
|
|
173
176
|
name: test_step.text,
|
174
177
|
line: test_step.location.lines.min
|
175
178
|
}
|
176
|
-
step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string) unless step_source.doc_string.nil?
|
179
|
+
step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string, test_step.multiline_arg.content) unless step_source.doc_string.nil?
|
177
180
|
step_hash[:rows] = create_data_table_value(step_source.data_table) unless step_source.data_table.nil?
|
178
181
|
step_hash
|
179
182
|
end
|
180
183
|
|
181
|
-
def create_doc_string_hash(doc_string)
|
184
|
+
def create_doc_string_hash(doc_string, doc_string_content)
|
182
185
|
content_type = doc_string.media_type || ''
|
183
186
|
{
|
184
|
-
value:
|
187
|
+
value: doc_string_content,
|
185
188
|
content_type: content_type,
|
186
189
|
line: doc_string.location.line
|
187
190
|
}
|
@@ -257,6 +260,7 @@ module Cucumber
|
|
257
260
|
line: feature.location.line
|
258
261
|
}
|
259
262
|
return if feature.tags.empty?
|
263
|
+
|
260
264
|
@feature_hash[:tags] = create_tags_array_from_hash_array(feature.tags)
|
261
265
|
end
|
262
266
|
|
@@ -266,7 +270,8 @@ module Cucumber
|
|
266
270
|
name: background.name,
|
267
271
|
description: value_or_empty_string(background.description),
|
268
272
|
line: background.location.line,
|
269
|
-
type: 'background'
|
273
|
+
type: 'background',
|
274
|
+
steps: []
|
270
275
|
}
|
271
276
|
end
|
272
277
|
|
@@ -278,7 +283,8 @@ module Cucumber
|
|
278
283
|
name: test_case.name,
|
279
284
|
description: value_or_empty_string(scenario.description),
|
280
285
|
line: test_case.location.lines.max,
|
281
|
-
type: 'scenario'
|
286
|
+
type: 'scenario',
|
287
|
+
steps: []
|
282
288
|
}
|
283
289
|
@test_case_hash[:tags] = create_tags_array_from_tags_array(test_case.tags) unless test_case.tags.empty?
|
284
290
|
end
|
@@ -84,6 +84,7 @@ module Cucumber
|
|
84
84
|
uri = test_case.location.file
|
85
85
|
feature = @ast_lookup.gherkin_document(uri).feature
|
86
86
|
raise UnNamedFeatureError, uri if feature.name.empty?
|
87
|
+
|
87
88
|
@current_feature_data = @features_data[uri]
|
88
89
|
@current_feature_data[:uri] = uri unless @current_feature_data[:uri]
|
89
90
|
@current_feature_data[:feature] = feature unless @current_feature_data[:feature]
|
@@ -111,6 +112,7 @@ module Cucumber
|
|
111
112
|
keyword = scenario_source.type == :Scenario ? scenario_source.scenario.keyword : scenario_source.scenario_outline.keyword
|
112
113
|
output = "#{keyword}: #{scenario}\n\n"
|
113
114
|
return output if result.ok?(@config.strict)
|
115
|
+
|
114
116
|
if scenario_source.type == :Scenario
|
115
117
|
if @failing_test_step
|
116
118
|
if @failing_test_step.hook?
|
@@ -125,7 +127,7 @@ module Cucumber
|
|
125
127
|
else
|
126
128
|
output += "Example row: #{row_name}\n"
|
127
129
|
end
|
128
|
-
output
|
130
|
+
"#{output}\nMessage:\n"
|
129
131
|
end
|
130
132
|
|
131
133
|
def build_testcase(result, scenario_designation, output)
|
@@ -191,7 +193,7 @@ module Cucumber
|
|
191
193
|
end
|
192
194
|
|
193
195
|
def basename(feature_file)
|
194
|
-
File.basename(feature_file.gsub(/[\\\/]/, '-'), '.feature')
|
196
|
+
File.basename(feature_file.gsub(/[\\\/]/, '-'), '.feature')
|
195
197
|
end
|
196
198
|
|
197
199
|
def write_file(feature_filename, data)
|
@@ -228,13 +230,14 @@ module Cucumber
|
|
228
230
|
end
|
229
231
|
|
230
232
|
def examples_table_row(row)
|
231
|
-
@row_name =
|
233
|
+
@row_name = "| #{row.cells.map(&:value).join(' | ')} |"
|
232
234
|
@name_suffix = " (outline example : #{@row_name})"
|
233
235
|
end
|
234
236
|
end
|
235
237
|
|
236
238
|
class ResultBuilder
|
237
239
|
attr_reader :test_case_duration
|
240
|
+
|
238
241
|
def initialize(result)
|
239
242
|
@test_case_duration = 0
|
240
243
|
result.describe_to(self)
|
@@ -48,12 +48,12 @@ module Cucumber
|
|
48
48
|
}
|
49
49
|
|
50
50
|
if media_type.start_with?('text/')
|
51
|
-
attachment_data[:content_encoding] = Cucumber::Messages::
|
51
|
+
attachment_data[:content_encoding] = Cucumber::Messages::AttachmentContentEncoding::IDENTITY
|
52
52
|
attachment_data[:body] = src
|
53
53
|
else
|
54
54
|
body = src.respond_to?(:read) ? src.read : src
|
55
55
|
|
56
|
-
attachment_data[:content_encoding] = Cucumber::Messages::
|
56
|
+
attachment_data[:content_encoding] = Cucumber::Messages::AttachmentContentEncoding::BASE64
|
57
57
|
attachment_data[:body] = Base64.strict_encode64(body)
|
58
58
|
end
|
59
59
|
|
@@ -101,7 +101,7 @@ module Cucumber
|
|
101
101
|
def test_step_to_message(step)
|
102
102
|
return hook_step_to_message(step) if step.hook?
|
103
103
|
|
104
|
-
Cucumber::Messages::
|
104
|
+
Cucumber::Messages::TestStep.new(
|
105
105
|
id: step.id,
|
106
106
|
pickle_step_id: @pickle_step_by_test_step.pickle_step_id(step),
|
107
107
|
step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
|
@@ -110,7 +110,7 @@ module Cucumber
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def hook_step_to_message(step)
|
113
|
-
Cucumber::Messages::
|
113
|
+
Cucumber::Messages::TestStep.new(
|
114
114
|
id: step.id,
|
115
115
|
hook_id: @hook_by_test_step.hook_id(step)
|
116
116
|
)
|
@@ -118,7 +118,7 @@ module Cucumber
|
|
118
118
|
|
119
119
|
def step_match_arguments_lists(step)
|
120
120
|
match_arguments = step_match_arguments(step)
|
121
|
-
[Cucumber::Messages::
|
121
|
+
[Cucumber::Messages::StepMatchArgumentsList.new(
|
122
122
|
step_match_arguments: match_arguments
|
123
123
|
)]
|
124
124
|
rescue Cucumber::Formatter::TestStepUnknownError
|
@@ -127,7 +127,7 @@ module Cucumber
|
|
127
127
|
|
128
128
|
def step_match_arguments(step)
|
129
129
|
@step_definitions_by_test_step.step_match_arguments(step).map do |argument|
|
130
|
-
Cucumber::Messages::
|
130
|
+
Cucumber::Messages::StepMatchArgument.new(
|
131
131
|
group: argument_group_to_message(argument.group),
|
132
132
|
parameter_type_name: argument.parameter_type.name
|
133
133
|
)
|
@@ -135,7 +135,7 @@ module Cucumber
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def argument_group_to_message(group)
|
138
|
-
Cucumber::Messages::
|
138
|
+
Cucumber::Messages::Group.new(
|
139
139
|
start: group.start,
|
140
140
|
value: group.value,
|
141
141
|
children: group.children.map { |child| argument_group_to_message(child) }
|
@@ -190,7 +190,7 @@ module Cucumber
|
|
190
190
|
|
191
191
|
result_message = result.to_message
|
192
192
|
if result.failed? || result.pending?
|
193
|
-
result_message = Cucumber::Messages::
|
193
|
+
result_message = Cucumber::Messages::TestStepResult.new(
|
194
194
|
status: result_message.status,
|
195
195
|
duration: result_message.duration,
|
196
196
|
message: create_error_message(result)
|
@@ -226,10 +226,11 @@ module Cucumber
|
|
226
226
|
output_envelope(message)
|
227
227
|
end
|
228
228
|
|
229
|
-
def on_test_run_finished(
|
229
|
+
def on_test_run_finished(event)
|
230
230
|
message = Cucumber::Messages::Envelope.new(
|
231
231
|
test_run_finished: Cucumber::Messages::TestRunFinished.new(
|
232
|
-
timestamp: time_to_timestamp(Time.now)
|
232
|
+
timestamp: time_to_timestamp(Time.now),
|
233
|
+
success: event.success
|
233
234
|
)
|
234
235
|
)
|
235
236
|
|
@@ -24,11 +24,9 @@ module Cucumber
|
|
24
24
|
include Console
|
25
25
|
include Io
|
26
26
|
include Cucumber::Gherkin::Formatter::Escaping
|
27
|
-
attr_reader :config, :options
|
27
|
+
attr_reader :config, :options, :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case, :in_scenario_outline, :print_background_steps
|
28
28
|
private :config, :options
|
29
|
-
attr_reader :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
|
30
29
|
private :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
|
31
|
-
attr_reader :in_scenario_outline, :print_background_steps
|
32
30
|
private :in_scenario_outline, :print_background_steps
|
33
31
|
|
34
32
|
def initialize(config)
|
@@ -105,16 +103,19 @@ module Cucumber
|
|
105
103
|
|
106
104
|
def on_test_step_started(event)
|
107
105
|
return if event.test_step.hook?
|
106
|
+
|
108
107
|
print_step_header(current_test_case) if first_step_after_printing_background_steps?(event.test_step)
|
109
108
|
end
|
110
109
|
|
111
110
|
def on_test_step_finished(event)
|
112
111
|
collect_snippet_data(event.test_step, @ast_lookup) if event.result.undefined?
|
113
112
|
return if in_scenario_outline && !options[:expand]
|
113
|
+
|
114
114
|
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
115
115
|
print_step_data(event.test_step, event.result) if print_step_data?(event, exception_to_be_printed)
|
116
116
|
print_step_output
|
117
117
|
return unless exception_to_be_printed
|
118
|
+
|
118
119
|
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
119
120
|
@exceptions << exception_to_be_printed
|
120
121
|
end
|
@@ -127,6 +128,7 @@ module Cucumber
|
|
127
128
|
else
|
128
129
|
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
129
130
|
return unless exception_to_be_printed
|
131
|
+
|
130
132
|
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
131
133
|
@exceptions << exception_to_be_printed
|
132
134
|
end
|
@@ -140,6 +142,7 @@ module Cucumber
|
|
140
142
|
|
141
143
|
def attach(src, media_type)
|
142
144
|
return unless media_type == 'text/x.cucumber.log+plain'
|
145
|
+
|
143
146
|
@test_step_output.push src
|
144
147
|
end
|
145
148
|
|
@@ -147,9 +150,11 @@ module Cucumber
|
|
147
150
|
|
148
151
|
def find_exception_to_be_printed(result)
|
149
152
|
return nil if result.ok?(options[:strict])
|
153
|
+
|
150
154
|
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
151
155
|
exception = result.failed? ? result.exception : result
|
152
156
|
return nil if @exceptions.include?(exception)
|
157
|
+
|
153
158
|
exception
|
154
159
|
end
|
155
160
|
|
@@ -181,7 +186,7 @@ module Cucumber
|
|
181
186
|
end
|
182
187
|
|
183
188
|
def print_step_output
|
184
|
-
@test_step_output.each { |message| @io.puts(format_string(message, :tag)
|
189
|
+
@test_step_output.each { |message| @io.puts(indent(format_string(message, :tag), 6)) }
|
185
190
|
@test_step_output = []
|
186
191
|
end
|
187
192
|
|
@@ -196,6 +201,7 @@ module Cucumber
|
|
196
201
|
def feature_has_background?
|
197
202
|
feature_children = gherkin_document.feature.children
|
198
203
|
return false if feature_children.empty?
|
204
|
+
|
199
205
|
!feature_children.first.background.nil?
|
200
206
|
end
|
201
207
|
|
@@ -239,6 +245,7 @@ module Cucumber
|
|
239
245
|
def first_step_after_printing_background_steps?(test_step)
|
240
246
|
return false unless print_background_steps
|
241
247
|
return false unless test_step.location.lines.max >= current_test_case.location.lines.max
|
248
|
+
|
242
249
|
@print_background_steps = false
|
243
250
|
true
|
244
251
|
end
|
@@ -259,33 +266,35 @@ module Cucumber
|
|
259
266
|
end
|
260
267
|
end
|
261
268
|
|
262
|
-
def print_comments(up_to_line,
|
269
|
+
def print_comments(up_to_line, indent_amount)
|
263
270
|
comments = gherkin_document.comments
|
264
271
|
return if comments.empty? || comments.length <= @next_comment_to_be_printed
|
265
|
-
|
272
|
+
|
273
|
+
comments[@next_comment_to_be_printed..].each do |comment|
|
266
274
|
if comment.location.line <= up_to_line
|
267
|
-
@io.puts(format_string(comment.text.strip, :comment)
|
275
|
+
@io.puts(indent(format_string(comment.text.strip, :comment), indent_amount))
|
268
276
|
@next_comment_to_be_printed += 1
|
269
277
|
end
|
270
278
|
break if @next_comment_to_be_printed >= comments.length
|
271
279
|
end
|
272
280
|
end
|
273
281
|
|
274
|
-
def print_tags(tags,
|
282
|
+
def print_tags(tags, indent_amount)
|
275
283
|
return if !tags || tags.empty?
|
276
|
-
|
284
|
+
|
285
|
+
@io.puts(indent(tags.map { |tag| format_string(tag.name, :tag) }.join(' '), indent_amount))
|
277
286
|
end
|
278
287
|
|
279
288
|
def print_feature_line(feature)
|
280
289
|
print_keyword_name(feature.keyword, feature.name, 0)
|
281
290
|
end
|
282
291
|
|
283
|
-
def print_keyword_name(keyword, name,
|
292
|
+
def print_keyword_name(keyword, name, indent_amount, location = nil)
|
284
293
|
line = "#{keyword}:"
|
285
294
|
line += " #{name}"
|
286
|
-
@io.print(
|
295
|
+
@io.print(indent(line, indent_amount))
|
287
296
|
if location && options[:source]
|
288
|
-
line_comment = format_string("# #{location}", :comment)
|
297
|
+
line_comment = indent(format_string("# #{location}", :comment), @source_indent - line.length - indent_amount)
|
289
298
|
@io.print(line_comment)
|
290
299
|
end
|
291
300
|
@io.puts
|
@@ -293,6 +302,7 @@ module Cucumber
|
|
293
302
|
|
294
303
|
def print_description(description)
|
295
304
|
return unless description
|
305
|
+
|
296
306
|
description.split("\n").each do |line|
|
297
307
|
@io.puts(line)
|
298
308
|
end
|
@@ -339,7 +349,7 @@ module Cucumber
|
|
339
349
|
indent = options[:source] ? @source_indent - step_keyword.length - test_step.text.length - base_indent : nil
|
340
350
|
print_comments(test_step.location.lines.max, base_indent)
|
341
351
|
name_to_report = format_step(step_keyword, @step_matches.fetch(test_step.to_s) { NoStepMatch.new(test_step, test_step.text) }, result.to_sym, indent)
|
342
|
-
@io.puts(
|
352
|
+
@io.puts(indent(name_to_report, base_indent))
|
343
353
|
print_multiline_argument(test_step, result, base_indent + 2) unless options[:no_multiline]
|
344
354
|
@io.flush
|
345
355
|
end
|
@@ -374,10 +384,10 @@ module Cucumber
|
|
374
384
|
end
|
375
385
|
end
|
376
386
|
|
377
|
-
def print_data_table(data_table, status,
|
387
|
+
def print_data_table(data_table, status, indent_amount)
|
378
388
|
data_table.rows.each do |row|
|
379
|
-
print_comments(row.location.line,
|
380
|
-
@io.puts format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status)
|
389
|
+
print_comments(row.location.line, indent_amount)
|
390
|
+
@io.puts indent(format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status), indent_amount)
|
381
391
|
end
|
382
392
|
end
|
383
393
|
|
@@ -393,18 +403,19 @@ module Cucumber
|
|
393
403
|
@io.print(format_string(step_line, :skipped))
|
394
404
|
if options[:source]
|
395
405
|
comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
|
396
|
-
@io.print(
|
406
|
+
@io.print(indent(comment_line, @source_indent - step_line.length))
|
397
407
|
end
|
398
408
|
@io.puts
|
399
409
|
next if options[:no_multiline]
|
410
|
+
|
400
411
|
print_doc_string(step.doc_string.content, :skipped, 6) unless step.doc_string.nil?
|
401
412
|
print_data_table(step.data_table, :skipped, 6) unless step.data_table.nil?
|
402
413
|
end
|
403
414
|
@io.flush
|
404
415
|
end
|
405
416
|
|
406
|
-
def print_doc_string(content, status,
|
407
|
-
s = %("""\n#{content}\n""")
|
417
|
+
def print_doc_string(content, status, indent_amount)
|
418
|
+
s = indent(%("""\n#{content}\n"""), indent_amount)
|
408
419
|
s = s.split("\n").map { |l| l =~ /^\s+$/ ? '' : l }.join("\n")
|
409
420
|
@io.puts(format_string(s, status))
|
410
421
|
end
|
@@ -416,15 +427,15 @@ module Cucumber
|
|
416
427
|
print_description(examples.description)
|
417
428
|
unless options[:expand]
|
418
429
|
print_comments(examples.table_header.location.line, 6)
|
419
|
-
@io.puts(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip
|
430
|
+
@io.puts(indent(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip, 6))
|
420
431
|
end
|
421
432
|
@io.flush
|
422
433
|
end
|
423
434
|
|
424
435
|
def print_row_data(test_case, result)
|
425
436
|
print_comments(test_case.location.lines.max, 6)
|
426
|
-
@io.print(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym)
|
427
|
-
@io.print(format_string(@test_step_output.join(', '), :tag)
|
437
|
+
@io.print(indent(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym), 6))
|
438
|
+
@io.print(indent(format_string(@test_step_output.join(', '), :tag), 2)) unless @test_step_output.empty?
|
428
439
|
@test_step_output = []
|
429
440
|
@io.puts
|
430
441
|
if result.failed? || result.pending?
|
@@ -444,7 +455,7 @@ module Cucumber
|
|
444
455
|
language = ::Gherkin::Dialect.for(language_code)
|
445
456
|
scenario_keyword = language.scenario_keywords[0]
|
446
457
|
row = scenario_source(test_case).row
|
447
|
-
expanded_name =
|
458
|
+
expanded_name = "| #{row.cells.map(&:value).join(' | ')} |"
|
448
459
|
@source_indent = calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
|
449
460
|
@io.puts
|
450
461
|
print_keyword_name(scenario_keyword, expanded_name, 6, test_case.location)
|
@@ -58,6 +58,7 @@ module Cucumber
|
|
58
58
|
progress(result.to_sym) if !test_step.hook? || result.failed?
|
59
59
|
|
60
60
|
return if test_step.hook?
|
61
|
+
|
61
62
|
collect_snippet_data(test_step, @ast_lookup) if result.undefined?
|
62
63
|
@pending_step_matches << @matches[test_step.to_s] if result.pending?
|
63
64
|
@failed_results << result if result.failed?
|
@@ -13,6 +13,7 @@ module Cucumber
|
|
13
13
|
|
14
14
|
def hook_id(test_step)
|
15
15
|
return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id)
|
16
|
+
|
16
17
|
raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}"
|
17
18
|
end
|
18
19
|
|
@@ -15,11 +15,13 @@ module Cucumber
|
|
15
15
|
|
16
16
|
def attempt_by_test_case(test_case)
|
17
17
|
raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@attempts_by_test_case_id.keys}" unless @attempts_by_test_case_id.key?(test_case.id)
|
18
|
+
|
18
19
|
@attempts_by_test_case_id[test_case.id]
|
19
20
|
end
|
20
21
|
|
21
22
|
def test_case_started_id_by_test_case(test_case)
|
22
23
|
raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@test_case_started_id_by_test_case_id.keys}" unless @test_case_started_id_by_test_case_id.key?(test_case.id)
|
24
|
+
|
23
25
|
@test_case_started_id_by_test_case_id[test_case.id]
|
24
26
|
end
|
25
27
|
|
@@ -15,6 +15,7 @@ module Cucumber
|
|
15
15
|
test_case, result = *event.attributes
|
16
16
|
if @config.strict.strict?(:flaky)
|
17
17
|
next if result.ok?(@config.strict)
|
18
|
+
|
18
19
|
add_to_failures(test_case)
|
19
20
|
else
|
20
21
|
unless @latest_failed_test_case.nil?
|
@@ -31,6 +32,7 @@ module Cucumber
|
|
31
32
|
config.on_event :test_run_finished do
|
32
33
|
add_to_failures(@latest_failed_test_case) unless @latest_failed_test_case.nil?
|
33
34
|
next if @failures.empty?
|
35
|
+
|
34
36
|
@io.print file_failures.join("\n")
|
35
37
|
end
|
36
38
|
end
|