cucumber 3.1.2 → 7.1.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 +5 -5
- data/CHANGELOG.md +1780 -1146
- data/CONTRIBUTING.md +224 -61
- data/README.md +144 -22
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +46 -53
- data/lib/cucumber/cli/configuration.rb +28 -6
- data/lib/cucumber/cli/main.rb +12 -12
- data/lib/cucumber/cli/options.rb +103 -77
- data/lib/cucumber/cli/profile_loader.rb +49 -26
- data/lib/cucumber/configuration.rb +44 -29
- 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 +14 -7
- 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 -52
- data/lib/cucumber/formatter/ast_lookup.rb +163 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -8
- data/lib/cucumber/formatter/console.rb +69 -69
- 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 +147 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/interceptor.rb +11 -30
- data/lib/cucumber/formatter/io.rb +55 -13
- data/lib/cucumber/formatter/json.rb +115 -122
- data/lib/cucumber/formatter/junit.rb +72 -55
- data/lib/cucumber/formatter/message.rb +23 -0
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +360 -153
- data/lib/cucumber/formatter/progress.rb +30 -32
- data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
- 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 +8 -6
- data/lib/cucumber/formatter/summary.rb +16 -8
- data/lib/cucumber/formatter/unicode.rb +15 -17
- data/lib/cucumber/formatter/url_reporter.rb +17 -0
- data/lib/cucumber/formatter/usage.rb +17 -14
- 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 +19 -0
- 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 +37 -44
- data/lib/cucumber/glue/registry_and_more.rb +71 -12
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +42 -20
- 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 +2 -2
- 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 -18
- data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
- data/lib/cucumber/rspec/doubles.rb +3 -5
- 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 +6 -2
- data/lib/cucumber/runtime/support_code.rb +13 -15
- data/lib/cucumber/runtime/user_interface.rb +6 -16
- data/lib/cucumber/runtime.rb +77 -59
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +12 -17
- data/lib/cucumber/step_match_search.rb +2 -1
- data/lib/cucumber/term/ansicolor.rb +9 -9
- data/lib/cucumber/term/banner.rb +56 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +1 -1
- metadata +272 -81
- data/lib/cucumber/core_ext/string.rb +0 -11
- data/lib/cucumber/events/gherkin_source_parsed.rb~ +0 -14
- data/lib/cucumber/formatter/ast_lookup.rb~ +0 -9
- 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
@@ -1,253 +1,460 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'gherkin/dialect'
|
4
5
|
require 'cucumber/formatter/console'
|
5
6
|
require 'cucumber/formatter/io'
|
6
7
|
require 'cucumber/gherkin/formatter/escaping'
|
7
8
|
require 'cucumber/formatter/console_counts'
|
8
9
|
require 'cucumber/formatter/console_issues'
|
10
|
+
require 'cucumber/formatter/duration_extractor'
|
11
|
+
require 'cucumber/formatter/backtrace_filter'
|
12
|
+
require 'cucumber/formatter/ast_lookup'
|
9
13
|
|
10
14
|
module Cucumber
|
11
15
|
module Formatter
|
12
16
|
# The formatter used for <tt>--format pretty</tt> (the default formatter).
|
13
17
|
#
|
14
|
-
# This formatter prints
|
15
|
-
# just prettier. That means with proper indentation and alignment of table columns.
|
18
|
+
# This formatter prints the result of the feature executions to plain text - exactly how they were parsed.
|
16
19
|
#
|
17
20
|
# If the output is STDOUT (and not a file), there are bright colours to watch too.
|
18
21
|
#
|
19
|
-
class Pretty
|
22
|
+
class Pretty # rubocop:disable Metrics/ClassLength
|
20
23
|
include FileUtils
|
21
24
|
include Console
|
22
25
|
include Io
|
23
26
|
include Cucumber::Gherkin::Formatter::Escaping
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@
|
27
|
+
attr_reader :config, :options
|
28
|
+
private :config, :options
|
29
|
+
attr_reader :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
|
30
|
+
private :current_feature_uri, :current_scenario_outline, :current_examples, :current_test_case
|
31
|
+
attr_reader :in_scenario_outline, :print_background_steps
|
32
|
+
private :in_scenario_outline, :print_background_steps
|
33
|
+
|
34
|
+
def initialize(config)
|
35
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
36
|
+
@config = config
|
37
|
+
@options = config.to_hash
|
35
38
|
@snippets_input = []
|
36
|
-
@
|
37
|
-
@
|
39
|
+
@undefined_parameter_types = []
|
40
|
+
@total_duration = 0
|
41
|
+
@exceptions = []
|
42
|
+
@gherkin_sources = {}
|
43
|
+
@step_matches = {}
|
44
|
+
@ast_lookup = AstLookup.new(config)
|
45
|
+
@counts = ConsoleCounts.new(config)
|
46
|
+
@issues = ConsoleIssues.new(config, @ast_lookup)
|
47
|
+
@first_feature = true
|
48
|
+
@current_feature_uri = ''
|
49
|
+
@current_scenario_outline = nil
|
50
|
+
@current_examples = nil
|
51
|
+
@current_test_case = nil
|
52
|
+
@in_scenario_outline = false
|
53
|
+
@print_background_steps = false
|
54
|
+
@test_step_output = []
|
55
|
+
@passed_test_cases = []
|
56
|
+
@source_indent = 0
|
57
|
+
@next_comment_to_be_printed = 0
|
58
|
+
|
59
|
+
bind_events(config)
|
60
|
+
end
|
61
|
+
|
62
|
+
def bind_events(config)
|
63
|
+
config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
|
64
|
+
config.on_event :step_activated, &method(:on_step_activated)
|
65
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
66
|
+
config.on_event :test_step_started, &method(:on_test_step_started)
|
67
|
+
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
68
|
+
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
69
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
70
|
+
config.on_event :undefined_parameter_type, &method(:collect_undefined_parameter_type_names)
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_gherkin_source_read(event)
|
74
|
+
@gherkin_sources[event.path] = event.body
|
75
|
+
end
|
76
|
+
|
77
|
+
def on_step_activated(event)
|
78
|
+
test_step, step_match = *event.attributes
|
79
|
+
@step_matches[test_step.to_s] = step_match
|
80
|
+
end
|
81
|
+
|
82
|
+
def on_test_case_started(event)
|
83
|
+
if !same_feature_as_previous_test_case?(event.test_case.location)
|
84
|
+
if first_feature?
|
85
|
+
@first_feature = false
|
86
|
+
print_profile_information
|
87
|
+
else
|
88
|
+
print_comments(gherkin_source.split("\n").length, 0)
|
89
|
+
@io.puts
|
90
|
+
end
|
91
|
+
@current_feature_uri = event.test_case.location.file
|
92
|
+
@exceptions = []
|
93
|
+
print_feature_data
|
94
|
+
if feature_has_background?
|
95
|
+
print_background_data
|
96
|
+
@print_background_steps = true
|
97
|
+
@in_scenario_outline = false
|
98
|
+
end
|
99
|
+
else
|
100
|
+
@print_background_steps = false
|
101
|
+
end
|
102
|
+
@current_test_case = event.test_case
|
103
|
+
print_step_header(current_test_case) unless print_background_steps
|
104
|
+
end
|
105
|
+
|
106
|
+
def on_test_step_started(event)
|
107
|
+
return if event.test_step.hook?
|
108
|
+
print_step_header(current_test_case) if first_step_after_printing_background_steps?(event.test_step)
|
109
|
+
end
|
110
|
+
|
111
|
+
def on_test_step_finished(event)
|
112
|
+
collect_snippet_data(event.test_step, @ast_lookup) if event.result.undefined?
|
113
|
+
return if in_scenario_outline && !options[:expand]
|
114
|
+
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
115
|
+
print_step_data(event.test_step, event.result) if print_step_data?(event, exception_to_be_printed)
|
116
|
+
print_step_output
|
117
|
+
return unless exception_to_be_printed
|
118
|
+
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
119
|
+
@exceptions << exception_to_be_printed
|
120
|
+
end
|
121
|
+
|
122
|
+
def on_test_case_finished(event)
|
123
|
+
@total_duration += DurationExtractor.new(event.result).result_duration
|
124
|
+
@passed_test_cases << event.test_case if config.wip? && event.result.passed?
|
125
|
+
if in_scenario_outline && !options[:expand]
|
126
|
+
print_row_data(event.test_case, event.result)
|
127
|
+
else
|
128
|
+
exception_to_be_printed = find_exception_to_be_printed(event.result)
|
129
|
+
return unless exception_to_be_printed
|
130
|
+
print_exception(exception_to_be_printed, event.result.to_sym, 6)
|
131
|
+
@exceptions << exception_to_be_printed
|
132
|
+
end
|
38
133
|
end
|
39
134
|
|
40
|
-
def
|
41
|
-
|
135
|
+
def on_test_run_finished(_event)
|
136
|
+
print_comments(gherkin_source.split("\n").length, 0) unless current_feature_uri.empty?
|
137
|
+
@io.puts
|
138
|
+
print_summary
|
42
139
|
end
|
43
140
|
|
44
|
-
def
|
45
|
-
|
141
|
+
def attach(src, media_type)
|
142
|
+
return unless media_type == 'text/x.cucumber.log+plain'
|
143
|
+
@test_step_output.push src
|
46
144
|
end
|
47
145
|
|
48
|
-
|
49
|
-
|
50
|
-
|
146
|
+
private
|
147
|
+
|
148
|
+
def find_exception_to_be_printed(result)
|
149
|
+
return nil if result.ok?(options[:strict])
|
150
|
+
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
151
|
+
exception = result.failed? ? result.exception : result
|
152
|
+
return nil if @exceptions.include?(exception)
|
153
|
+
exception
|
51
154
|
end
|
52
155
|
|
53
|
-
def
|
54
|
-
|
55
|
-
@
|
156
|
+
def calculate_source_indent(test_case)
|
157
|
+
scenario = scenario_source(test_case).scenario
|
158
|
+
@source_indent = calculate_source_indent_for_ast_node(scenario)
|
56
159
|
end
|
57
160
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
161
|
+
def calculate_source_indent_for_ast_node(ast_node)
|
162
|
+
indent = 4 + ast_node.keyword.length
|
163
|
+
indent += 1 + ast_node.name.length
|
164
|
+
ast_node.steps.each do |step|
|
165
|
+
step_indent = 5 + step.keyword.length + step.text.length
|
166
|
+
indent = step_indent if step_indent > indent
|
62
167
|
end
|
168
|
+
indent
|
63
169
|
end
|
64
170
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
171
|
+
def calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
|
172
|
+
indent = 7 + scenario_keyword.length
|
173
|
+
indent += 2 + expanded_name.length
|
174
|
+
test_case.test_steps.each do |step|
|
175
|
+
if !step.hook? && step.location.lines.max >= test_case.location.lines.max
|
176
|
+
step_indent = 9 + test_step_keyword(step).length + step.text.length
|
177
|
+
indent = step_indent if step_indent > indent
|
178
|
+
end
|
179
|
+
end
|
180
|
+
indent
|
70
181
|
end
|
71
182
|
|
72
|
-
def
|
73
|
-
@io.puts(
|
74
|
-
@
|
75
|
-
@io.flush
|
183
|
+
def print_step_output
|
184
|
+
@test_step_output.each { |message| @io.puts(indent(format_string(message, :tag), 6)) }
|
185
|
+
@test_step_output = []
|
76
186
|
end
|
77
187
|
|
78
|
-
def
|
79
|
-
@
|
80
|
-
@scenario_indent = 2
|
188
|
+
def first_feature?
|
189
|
+
@first_feature
|
81
190
|
end
|
82
191
|
|
83
|
-
def
|
84
|
-
|
85
|
-
@io.puts
|
86
|
-
@io.flush
|
192
|
+
def same_feature_as_previous_test_case?(location)
|
193
|
+
location.file == current_feature_uri
|
87
194
|
end
|
88
195
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
|
196
|
+
def feature_has_background?
|
197
|
+
feature_children = gherkin_document.feature.children
|
198
|
+
return false if feature_children.empty?
|
199
|
+
!feature_children.first.background.nil?
|
93
200
|
end
|
94
201
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
202
|
+
def print_step_header(test_case)
|
203
|
+
if from_scenario_outline?(test_case)
|
204
|
+
@in_scenario_outline = true
|
205
|
+
unless same_outline_as_previous_test_case?(test_case)
|
206
|
+
@current_scenario_outline = scenario_source(test_case).scenario_outline
|
207
|
+
@io.puts
|
208
|
+
print_outline_data(current_scenario_outline)
|
209
|
+
end
|
210
|
+
unless same_examples_as_previous_test_case?(test_case)
|
211
|
+
@current_examples = scenario_source(test_case).examples
|
212
|
+
@io.puts
|
213
|
+
print_examples_data(current_examples)
|
214
|
+
end
|
215
|
+
print_expanded_row_data(current_test_case) if options[:expand]
|
216
|
+
else
|
217
|
+
@in_scenario_outline = false
|
218
|
+
@current_scenario_outline = nil
|
219
|
+
@current_examples = nil
|
220
|
+
@io.puts
|
221
|
+
@source_indent = calculate_source_indent(current_test_case)
|
222
|
+
print_scenario_data(test_case)
|
223
|
+
end
|
100
224
|
end
|
101
225
|
|
102
|
-
def
|
103
|
-
|
226
|
+
def same_outline_as_previous_test_case?(test_case)
|
227
|
+
scenario_source(test_case).scenario_outline == current_scenario_outline
|
104
228
|
end
|
105
229
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
230
|
+
def same_examples_as_previous_test_case?(test_case)
|
231
|
+
scenario_source(test_case).examples == current_examples
|
232
|
+
end
|
233
|
+
|
234
|
+
def from_scenario_outline?(test_case)
|
235
|
+
scenario = scenario_source(test_case)
|
236
|
+
scenario.type != :Scenario
|
110
237
|
end
|
111
238
|
|
112
|
-
def
|
113
|
-
|
114
|
-
|
115
|
-
@
|
239
|
+
def first_step_after_printing_background_steps?(test_step)
|
240
|
+
return false unless print_background_steps
|
241
|
+
return false unless test_step.location.lines.max >= current_test_case.location.lines.max
|
242
|
+
@print_background_steps = false
|
243
|
+
true
|
244
|
+
end
|
245
|
+
|
246
|
+
def print_feature_data
|
247
|
+
feature = gherkin_document.feature
|
248
|
+
print_language_comment(feature.location.line)
|
249
|
+
print_comments(feature.location.line, 0)
|
250
|
+
print_tags(feature.tags, 0)
|
251
|
+
print_feature_line(feature)
|
252
|
+
print_description(feature.description)
|
116
253
|
@io.flush
|
117
|
-
@indent = 6
|
118
|
-
@scenario_indent = 6
|
119
254
|
end
|
120
255
|
|
121
|
-
def
|
122
|
-
|
256
|
+
def print_language_comment(feature_line)
|
257
|
+
gherkin_source.split("\n")[0..feature_line].each do |line|
|
258
|
+
@io.puts(format_string(line, :comment)) if /# *language *:/ =~ line
|
259
|
+
end
|
123
260
|
end
|
124
261
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
262
|
+
def print_comments(up_to_line, indent_amount)
|
263
|
+
comments = gherkin_document.comments
|
264
|
+
return if comments.empty? || comments.length <= @next_comment_to_be_printed
|
265
|
+
comments[@next_comment_to_be_printed..-1].each do |comment|
|
266
|
+
if comment.location.line <= up_to_line
|
267
|
+
@io.puts(indent(format_string(comment.text.strip, :comment), indent_amount))
|
268
|
+
@next_comment_to_be_printed += 1
|
269
|
+
end
|
270
|
+
break if @next_comment_to_be_printed >= comments.length
|
271
|
+
end
|
128
272
|
end
|
129
273
|
|
130
|
-
def
|
131
|
-
|
274
|
+
def print_tags(tags, indent_amount)
|
275
|
+
return if !tags || tags.empty?
|
276
|
+
|
277
|
+
@io.puts(indent(tags.map { |tag| format_string(tag.name, :tag) }.join(' '), indent_amount))
|
132
278
|
end
|
133
279
|
|
134
|
-
def
|
135
|
-
|
136
|
-
@indent = 6
|
137
|
-
print_messages
|
280
|
+
def print_feature_line(feature)
|
281
|
+
print_keyword_name(feature.keyword, feature.name, 0)
|
138
282
|
end
|
139
283
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
@exceptions << exception
|
284
|
+
def print_keyword_name(keyword, name, indent_amount, location = nil)
|
285
|
+
line = "#{keyword}:"
|
286
|
+
line += " #{name}"
|
287
|
+
@io.print(indent(line, indent_amount))
|
288
|
+
if location && options[:source]
|
289
|
+
line_comment = indent(format_string("# #{location}", :comment), @source_indent - line.length - indent_amount)
|
290
|
+
@io.print(line_comment)
|
148
291
|
end
|
149
|
-
|
150
|
-
|
151
|
-
|
292
|
+
@io.puts
|
293
|
+
end
|
294
|
+
|
295
|
+
def print_description(description)
|
296
|
+
return unless description
|
297
|
+
description.split("\n").each do |line|
|
298
|
+
@io.puts(line)
|
152
299
|
end
|
153
|
-
@status = status
|
154
300
|
end
|
155
301
|
|
156
|
-
def
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
302
|
+
def print_background_data
|
303
|
+
@io.puts
|
304
|
+
background = gherkin_document.feature.children.first.background
|
305
|
+
@source_indent = calculate_source_indent_for_ast_node(background) if options[:source]
|
306
|
+
print_comments(background.location.line, 2)
|
307
|
+
print_background_line(background)
|
308
|
+
print_description(background.description)
|
309
|
+
@io.flush
|
162
310
|
end
|
163
311
|
|
164
|
-
def
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
312
|
+
def print_background_line(background)
|
313
|
+
print_keyword_name(background.keyword, background.name, 2, "#{current_feature_uri}:#{background.location.line}")
|
314
|
+
end
|
315
|
+
|
316
|
+
def print_scenario_data(test_case)
|
317
|
+
scenario = scenario_source(test_case).scenario
|
318
|
+
print_comments(scenario.location.line, 2)
|
319
|
+
print_tags(scenario.tags, 2)
|
320
|
+
print_scenario_line(scenario, test_case.location)
|
321
|
+
print_description(scenario.description)
|
169
322
|
@io.flush
|
170
323
|
end
|
171
324
|
|
172
|
-
def
|
173
|
-
|
174
|
-
|
175
|
-
|
325
|
+
def print_scenario_line(scenario, location = nil)
|
326
|
+
print_keyword_name(scenario.keyword, scenario.name, 2, location)
|
327
|
+
end
|
328
|
+
|
329
|
+
def print_step_data?(event, exception_to_be_printed)
|
330
|
+
!event.test_step.hook? && (
|
331
|
+
print_background_steps ||
|
332
|
+
event.test_step.location.lines.max >= current_test_case.location.lines.max ||
|
333
|
+
exception_to_be_printed
|
334
|
+
)
|
335
|
+
end
|
336
|
+
|
337
|
+
def print_step_data(test_step, result)
|
338
|
+
base_indent = options[:expand] && in_scenario_outline ? 8 : 4
|
339
|
+
step_keyword = test_step_keyword(test_step)
|
340
|
+
indent = options[:source] ? @source_indent - step_keyword.length - test_step.text.length - base_indent : nil
|
341
|
+
print_comments(test_step.location.lines.max, base_indent)
|
342
|
+
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)
|
343
|
+
@io.puts(indent(name_to_report, base_indent))
|
344
|
+
print_multiline_argument(test_step, result, base_indent + 2) unless options[:no_multiline]
|
176
345
|
@io.flush
|
177
346
|
end
|
178
347
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
348
|
+
def test_step_keyword(test_step)
|
349
|
+
step = step_source(test_step).step
|
350
|
+
step.keyword
|
182
351
|
end
|
183
352
|
|
184
|
-
def
|
185
|
-
@
|
353
|
+
def step_source(test_step)
|
354
|
+
@ast_lookup.step_source(test_step)
|
186
355
|
end
|
187
356
|
|
188
|
-
def
|
189
|
-
|
190
|
-
@col_index = 0
|
191
|
-
@io.print ' |'.indent(@indent - 2)
|
357
|
+
def scenario_source(test_case)
|
358
|
+
@ast_lookup.scenario_source(test_case)
|
192
359
|
end
|
193
360
|
|
194
|
-
def
|
195
|
-
|
196
|
-
print_table_row_messages
|
197
|
-
@io.puts
|
198
|
-
if table_row.exception && !@exceptions.include?(table_row.exception)
|
199
|
-
print_exception(table_row.exception, table_row.status, @indent)
|
200
|
-
end
|
361
|
+
def gherkin_source
|
362
|
+
@gherkin_sources[current_feature_uri]
|
201
363
|
end
|
202
364
|
|
203
|
-
def
|
204
|
-
|
205
|
-
@col_index += 1
|
365
|
+
def gherkin_document
|
366
|
+
@ast_lookup.gherkin_document(current_feature_uri)
|
206
367
|
end
|
207
368
|
|
208
|
-
def
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
@io.print(' ' + format_string("#{prefix}#{padded}", status) + ::Cucumber::Term::ANSIColor.reset(' |'))
|
216
|
-
@io.flush
|
369
|
+
def print_multiline_argument(test_step, result, indent)
|
370
|
+
step = step_source(test_step).step
|
371
|
+
if !step.doc_string.nil?
|
372
|
+
print_doc_string(step.doc_string.content, result.to_sym, indent)
|
373
|
+
elsif !step.data_table.nil?
|
374
|
+
print_data_table(step.data_table, result.to_sym, indent)
|
375
|
+
end
|
217
376
|
end
|
218
377
|
|
219
|
-
def
|
220
|
-
|
378
|
+
def print_data_table(data_table, status, indent_amount)
|
379
|
+
data_table.rows.each do |row|
|
380
|
+
print_comments(row.location.line, indent_amount)
|
381
|
+
@io.puts indent(format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status), indent_amount)
|
382
|
+
end
|
221
383
|
end
|
222
384
|
|
223
|
-
def
|
224
|
-
|
385
|
+
def print_outline_data(scenario_outline) # rubocop:disable Metrics/AbcSize
|
386
|
+
print_comments(scenario_outline.location.line, 2)
|
387
|
+
print_tags(scenario_outline.tags, 2)
|
388
|
+
@source_indent = calculate_source_indent_for_ast_node(scenario_outline) if options[:source]
|
389
|
+
print_scenario_line(scenario_outline, "#{current_feature_uri}:#{scenario_outline.location.line}")
|
390
|
+
print_description(scenario_outline.description)
|
391
|
+
scenario_outline.steps.each do |step|
|
392
|
+
print_comments(step.location.line, 4)
|
393
|
+
step_line = " #{step.keyword}#{step.text}"
|
394
|
+
@io.print(format_string(step_line, :skipped))
|
395
|
+
if options[:source]
|
396
|
+
comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
|
397
|
+
@io.print(indent(comment_line, @source_indent - step_line.length))
|
398
|
+
end
|
399
|
+
@io.puts
|
400
|
+
next if options[:no_multiline]
|
401
|
+
print_doc_string(step.doc_string.content, :skipped, 6) unless step.doc_string.nil?
|
402
|
+
print_data_table(step.data_table, :skipped, 6) unless step.data_table.nil?
|
403
|
+
end
|
404
|
+
@io.flush
|
225
405
|
end
|
226
406
|
|
227
|
-
|
407
|
+
def print_doc_string(content, status, indent_amount)
|
408
|
+
s = indent(%("""\n#{content}\n"""), indent_amount)
|
409
|
+
s = s.split("\n").map { |l| l =~ /^\s+$/ ? '' : l }.join("\n")
|
410
|
+
@io.puts(format_string(s, status))
|
411
|
+
end
|
228
412
|
|
229
|
-
def
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
@io.
|
413
|
+
def print_examples_data(examples)
|
414
|
+
print_comments(examples.location.line, 4)
|
415
|
+
print_tags(examples.tags, 4)
|
416
|
+
print_keyword_name(examples.keyword, examples.name, 4)
|
417
|
+
print_description(examples.description)
|
418
|
+
unless options[:expand]
|
419
|
+
print_comments(examples.table_header.location.line, 6)
|
420
|
+
@io.puts(indent(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip, 6))
|
237
421
|
end
|
422
|
+
@io.flush
|
423
|
+
end
|
424
|
+
|
425
|
+
def print_row_data(test_case, result)
|
426
|
+
print_comments(test_case.location.lines.max, 6)
|
427
|
+
@io.print(indent(format_string(gherkin_source.split("\n")[test_case.location.lines.max - 1].strip, result.to_sym), 6))
|
428
|
+
@io.print(indent(format_string(@test_step_output.join(', '), :tag), 2)) unless @test_step_output.empty?
|
429
|
+
@test_step_output = []
|
238
430
|
@io.puts
|
239
|
-
|
431
|
+
if result.failed? || result.pending?
|
432
|
+
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
433
|
+
exception = result.failed? ? result.exception : result
|
434
|
+
unless @exceptions.include?(exception)
|
435
|
+
print_exception(exception, result.to_sym, 6)
|
436
|
+
@exceptions << exception
|
437
|
+
end
|
438
|
+
end
|
240
439
|
@io.flush
|
241
440
|
end
|
242
441
|
|
243
|
-
def
|
244
|
-
|
442
|
+
def print_expanded_row_data(test_case)
|
443
|
+
feature = gherkin_document.feature
|
444
|
+
language_code = feature.language || 'en'
|
445
|
+
language = ::Gherkin::Dialect.for(language_code)
|
446
|
+
scenario_keyword = language.scenario_keywords[0]
|
447
|
+
row = scenario_source(test_case).row
|
448
|
+
expanded_name = '| ' + row.cells.map(&:value).join(' | ') + ' |'
|
449
|
+
@source_indent = calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
|
450
|
+
@io.puts
|
451
|
+
print_keyword_name(scenario_keyword, expanded_name, 6, test_case.location)
|
245
452
|
end
|
246
453
|
|
247
|
-
def print_summary
|
248
|
-
print_statistics(
|
249
|
-
print_snippets(
|
250
|
-
print_passing_wip(@
|
454
|
+
def print_summary
|
455
|
+
print_statistics(@total_duration, config, @counts, @issues)
|
456
|
+
print_snippets(options)
|
457
|
+
print_passing_wip(config, @passed_test_cases, @ast_lookup)
|
251
458
|
end
|
252
459
|
end
|
253
460
|
end
|