cucumber 10.2.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 +17 -8
- data/VERSION +1 -1
- data/lib/cucumber/cli/configuration.rb +1 -1
- data/lib/cucumber/cli/main.rb +22 -0
- data/lib/cucumber/cli/options.rb +3 -18
- data/lib/cucumber/cli/profile_loader.rb +2 -2
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/cli.rb +3 -0
- data/lib/cucumber/configuration.rb +33 -24
- data/lib/cucumber/events/attach_called.rb +19 -0
- data/lib/cucumber/events/base.rb +25 -0
- data/lib/cucumber/events/envelope.rb +29 -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 +19 -0
- data/lib/cucumber/events/test_run_hook_started.rb +20 -0
- 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 +3 -0
- data/lib/cucumber/filters/fire_before_all_hooks.rb +36 -0
- data/lib/cucumber/filters/randomizer.rb +5 -5
- data/lib/cucumber/filters/reverser.rb +41 -0
- data/lib/cucumber/filters.rb +1 -12
- data/lib/cucumber/formatter/ansicolor.rb +3 -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 +2 -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 -6
- data/lib/cucumber/formatter/json.rb +14 -10
- data/lib/cucumber/formatter/junit.rb +5 -34
- data/lib/cucumber/formatter/message.rb +5 -5
- data/lib/cucumber/formatter/message_builder.rb +255 -143
- data/lib/cucumber/formatter/message_handlers.rb +13 -0
- data/lib/cucumber/formatter/pretty.rb +7 -9
- data/lib/cucumber/formatter/progress.rb +2 -2
- data/lib/cucumber/formatter/rerun.rb +82 -31
- data/lib/cucumber/formatter/summary.rb +15 -1
- data/lib/cucumber/formatter/usage.rb +2 -3
- data/lib/cucumber/formatter.rb +3 -0
- data/lib/cucumber/glue/proto_world.rb +3 -2
- data/lib/cucumber/glue/registry_and_more.rb +122 -20
- data/lib/cucumber/glue.rb +3 -0
- data/lib/cucumber/multiline_argument/data_table.rb +0 -11
- data/lib/cucumber/platform.rb +2 -2
- data/lib/cucumber/query.rb +273 -0
- data/lib/cucumber/rake/forked_cucumber_runner.rb +57 -0
- data/lib/cucumber/rake/in_process_cucumber_runner.rb +27 -0
- data/lib/cucumber/rake/task.rb +36 -106
- data/lib/cucumber/rake.rb +3 -0
- data/lib/cucumber/repository.rb +136 -0
- data/lib/cucumber/rspec/disable_option_parser.rb +3 -3
- data/lib/cucumber/runtime/user_interface.rb +4 -2
- data/lib/cucumber/runtime.rb +39 -17
- data/lib/cucumber/step_match.rb +1 -1
- data/lib/cucumber.rb +2 -13
- metadata +35 -31
- 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/pickle_step_by_test_step.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 -44
- data/lib/cucumber/formatter/query/test_run_started.rb +0 -17
- data/lib/cucumber/step_definition_light.rb +0 -29
|
@@ -1,52 +1,103 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'cucumber/
|
|
3
|
+
require 'cucumber/query'
|
|
4
|
+
|
|
5
|
+
require_relative 'io'
|
|
4
6
|
|
|
5
7
|
module Cucumber
|
|
6
8
|
module Formatter
|
|
7
9
|
class Rerun
|
|
8
|
-
include
|
|
10
|
+
include Io
|
|
9
11
|
|
|
10
12
|
def initialize(config)
|
|
11
|
-
@io = ensure_io(config.out_stream, config.error_stream)
|
|
12
13
|
@config = config
|
|
13
|
-
@
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
|
15
|
+
@repository = Cucumber::Repository.new
|
|
16
|
+
@query = Cucumber::Query.new(@repository)
|
|
17
|
+
config.on_event :envelope, &method(:output_envelope)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def output_envelope(event)
|
|
21
|
+
envelope = event.envelope
|
|
22
|
+
@repository.update(envelope)
|
|
23
|
+
finish_report if envelope.test_run_finished
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def finish_report
|
|
29
|
+
@query.find_all_test_case_started.each do |test_case|
|
|
30
|
+
status = @query.find_most_severe_test_step_result_by(test_case).status
|
|
31
|
+
# RULE: Don't log test cases without a pickle (Unsure what these could be?)
|
|
32
|
+
pickle = @query.find_pickle_by(test_case)
|
|
33
|
+
next if pickle.nil?
|
|
34
|
+
|
|
35
|
+
# RULE: (Configuration specific)
|
|
36
|
+
# -> If the test case has already been logged (And so we're retrying), we remove prior references of failures
|
|
37
|
+
if passing?(test_case) && !rerun_flaky_tests?
|
|
38
|
+
uri_and_location_hash[pickle.uri].delete(pickle.location.line)
|
|
39
|
+
next
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# RULE: (Configuration specific - to be amended once CCK conformance is finalised)
|
|
43
|
+
# -> If the strict configuration permits the result - handle it accordingly
|
|
44
|
+
if status == 'UNDEFINED' && !@config.strict.strict?(:undefined)
|
|
45
|
+
Cucumber.deprecate(
|
|
46
|
+
'The strict configuration in cucumber is going away and moving towards a standardised set of behaviours',
|
|
47
|
+
'--strict=undefined',
|
|
48
|
+
'12.0.0'
|
|
49
|
+
)
|
|
50
|
+
next
|
|
30
51
|
end
|
|
52
|
+
|
|
53
|
+
if status == 'PENDING' && !@config.strict.strict?(:pending)
|
|
54
|
+
Cucumber.deprecate(
|
|
55
|
+
'The strict configuration in cucumber is going away and moving towards a standardised set of behaviours',
|
|
56
|
+
'--strict=pending',
|
|
57
|
+
'12.0.0'
|
|
58
|
+
)
|
|
59
|
+
next
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# RULE: Passing test cases are not considered failures (Don't log these)
|
|
63
|
+
next if passing?(test_case)
|
|
64
|
+
|
|
65
|
+
# RULE: Skipped test cases are not considered failures (on their own, don't log these)
|
|
66
|
+
next if skipped?(test_case)
|
|
67
|
+
|
|
68
|
+
# RULE: Before logging a failure, ensure we are not on a retried test case (Don't log a retry multiple times)
|
|
69
|
+
next if test_case.attempt > 1
|
|
70
|
+
|
|
71
|
+
# Log the failure if every other skip rule has not been met, and the failure has not already been logged
|
|
72
|
+
uri_and_location_hash[pickle.uri] << pickle.location.line
|
|
31
73
|
end
|
|
32
|
-
config.on_event :test_run_finished do
|
|
33
|
-
add_to_failures(@latest_failed_test_case) unless @latest_failed_test_case.nil?
|
|
34
|
-
next if @failures.empty?
|
|
35
74
|
|
|
36
|
-
|
|
75
|
+
# Generate the final output from the logged failures to be formatted in the io output
|
|
76
|
+
@io.print(failure_array.join("\n"))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def failure_array
|
|
80
|
+
uri_and_location_hash.filter_map do |uri, lines|
|
|
81
|
+
"#{uri}:#{lines.join(':')}" if lines.any?
|
|
37
82
|
end
|
|
38
83
|
end
|
|
39
84
|
|
|
40
|
-
|
|
85
|
+
def uri_and_location_hash
|
|
86
|
+
@uri_and_location_hash ||= Hash.new { |hash, key| hash[key] = Set.new }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def rerun_flaky_tests?
|
|
90
|
+
@config.strict.strict?(:flaky)
|
|
91
|
+
end
|
|
41
92
|
|
|
42
|
-
def
|
|
43
|
-
|
|
93
|
+
def passing?(test_case_started)
|
|
94
|
+
most_severe_test_step_result = @query.find_most_severe_test_step_result_by(test_case_started)
|
|
95
|
+
most_severe_test_step_result.status == Cucumber::Messages::TestStepResultStatus::PASSED
|
|
44
96
|
end
|
|
45
97
|
|
|
46
|
-
def
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
@failures[location.file] << location.lines.max unless @failures[location.file].include?(location.lines.max)
|
|
98
|
+
def skipped?(test_case_started)
|
|
99
|
+
most_severe_test_step_result = @query.find_most_severe_test_step_result_by(test_case_started)
|
|
100
|
+
most_severe_test_step_result.status == Cucumber::Messages::TestStepResultStatus::SKIPPED
|
|
50
101
|
end
|
|
51
102
|
end
|
|
52
103
|
end
|
|
@@ -4,12 +4,13 @@ require 'cucumber/formatter/io'
|
|
|
4
4
|
require 'cucumber/formatter/console'
|
|
5
5
|
require 'cucumber/formatter/console_counts'
|
|
6
6
|
require 'cucumber/formatter/console_issues'
|
|
7
|
+
require 'cucumber/formatter/backtrace_filter'
|
|
7
8
|
require 'cucumber/core/test/result'
|
|
8
9
|
require 'cucumber/formatter/ast_lookup'
|
|
9
10
|
|
|
10
11
|
module Cucumber
|
|
11
12
|
module Formatter
|
|
12
|
-
# Summary formatter, outputting
|
|
13
|
+
# Summary formatter, outputting feature / scenario titles plus failure details
|
|
13
14
|
class Summary
|
|
14
15
|
include Io
|
|
15
16
|
include Console
|
|
@@ -20,6 +21,7 @@ module Cucumber
|
|
|
20
21
|
@ast_lookup = AstLookup.new(config)
|
|
21
22
|
@counts = ConsoleCounts.new(@config)
|
|
22
23
|
@issues = ConsoleIssues.new(@config, @ast_lookup)
|
|
24
|
+
@failed_results = []
|
|
23
25
|
@start_time = Time.now
|
|
24
26
|
|
|
25
27
|
@config.on_event :test_case_started do |event|
|
|
@@ -31,9 +33,14 @@ module Cucumber
|
|
|
31
33
|
print_result event.result
|
|
32
34
|
end
|
|
33
35
|
|
|
36
|
+
@config.on_event :test_step_finished do |event|
|
|
37
|
+
collect_failed_result(event.test_step, event.result)
|
|
38
|
+
end
|
|
39
|
+
|
|
34
40
|
@config.on_event :test_run_finished do |_event|
|
|
35
41
|
duration = Time.now - @start_time
|
|
36
42
|
@io.puts
|
|
43
|
+
print_elements(@failed_results, :failed, 'steps')
|
|
37
44
|
print_statistics(duration, @config, @counts, @issues)
|
|
38
45
|
end
|
|
39
46
|
end
|
|
@@ -61,6 +68,13 @@ module Cucumber
|
|
|
61
68
|
def print_result(result)
|
|
62
69
|
@io.puts format_string(result, result.to_sym)
|
|
63
70
|
end
|
|
71
|
+
|
|
72
|
+
def collect_failed_result(test_step, result)
|
|
73
|
+
return if test_step.hook?
|
|
74
|
+
|
|
75
|
+
result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
|
|
76
|
+
@failed_results << result if result.failed?
|
|
77
|
+
end
|
|
64
78
|
end
|
|
65
79
|
end
|
|
66
80
|
end
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'cucumber/formatter/progress'
|
|
4
|
-
require 'cucumber/step_definition_light'
|
|
5
4
|
require 'cucumber/formatter/console'
|
|
6
5
|
|
|
7
6
|
module Cucumber
|
|
8
7
|
module Formatter
|
|
9
8
|
class Usage < Progress
|
|
10
9
|
include Console
|
|
10
|
+
|
|
11
11
|
class StepDefKey
|
|
12
12
|
attr_accessor :mean_duration, :status
|
|
13
13
|
attr_reader :regexp_source, :location
|
|
@@ -32,8 +32,7 @@ module Cucumber
|
|
|
32
32
|
@total_duration = 0
|
|
33
33
|
@matches = {}
|
|
34
34
|
config.on_event :step_activated do |event|
|
|
35
|
-
test_step
|
|
36
|
-
@matches[test_step.to_s] = step_match
|
|
35
|
+
@matches[event.test_step.to_s] = event.step_match
|
|
37
36
|
end
|
|
38
37
|
config.on_event :step_definition_registered, &method(:on_step_definition_registered)
|
|
39
38
|
end
|
|
@@ -94,9 +94,10 @@ module Cucumber
|
|
|
94
94
|
media_type = MiniMime.lookup_by_filename(file)&.content_type if media_type.nil?
|
|
95
95
|
file = File.read(file, mode: 'rb')
|
|
96
96
|
end
|
|
97
|
-
|
|
97
|
+
# We pass in the concept of whether the file is streamed to ensure that the envelope encoding is correct
|
|
98
|
+
super(file, media_type, filename)
|
|
98
99
|
rescue StandardError
|
|
99
|
-
super
|
|
100
|
+
super(file, media_type, filename)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
# Mark the matched step as pending.
|
|
@@ -4,6 +4,8 @@ require 'cucumber/cucumber_expressions/parameter_type_registry'
|
|
|
4
4
|
require 'cucumber/cucumber_expressions/cucumber_expression'
|
|
5
5
|
require 'cucumber/cucumber_expressions/regular_expression'
|
|
6
6
|
require 'cucumber/cucumber_expressions/cucumber_expression_generator'
|
|
7
|
+
require 'cucumber/messages/helpers/time_conversion'
|
|
8
|
+
|
|
7
9
|
require 'cucumber/glue/dsl'
|
|
8
10
|
require 'cucumber/glue/snippet'
|
|
9
11
|
require 'cucumber/glue/hook'
|
|
@@ -13,7 +15,7 @@ require 'cucumber/glue/world_factory'
|
|
|
13
15
|
require 'cucumber/gherkin/i18n'
|
|
14
16
|
require 'multi_test'
|
|
15
17
|
require 'cucumber/step_match'
|
|
16
|
-
require 'cucumber/
|
|
18
|
+
require 'cucumber/events/base'
|
|
17
19
|
require 'cucumber/events/step_definition_registered'
|
|
18
20
|
|
|
19
21
|
module Cucumber
|
|
@@ -49,6 +51,8 @@ module Cucumber
|
|
|
49
51
|
class RegistryAndMore
|
|
50
52
|
attr_reader :current_world, :step_definitions
|
|
51
53
|
|
|
54
|
+
include Cucumber::Messages::Helpers::TimeConversion
|
|
55
|
+
|
|
52
56
|
all_keywords = ::Gherkin::DIALECTS.keys.map do |dialect_name|
|
|
53
57
|
dialect = ::Gherkin::Dialect.for(dialect_name)
|
|
54
58
|
dialect.given_keywords + dialect.when_keywords + dialect.then_keywords + dialect.and_keywords + dialect.but_keywords
|
|
@@ -99,14 +103,20 @@ module Cucumber
|
|
|
99
103
|
def register_rb_step_definition(string_or_regexp, proc_or_sym, options)
|
|
100
104
|
step_definition = StepDefinition.new(@configuration.id_generator.new_id, self, string_or_regexp, proc_or_sym, options)
|
|
101
105
|
@step_definitions << step_definition
|
|
102
|
-
@configuration.notify
|
|
103
|
-
@configuration.notify
|
|
106
|
+
@configuration.notify(:step_definition_registered, step_definition)
|
|
107
|
+
@configuration.notify(:envelope, step_definition.to_envelope)
|
|
104
108
|
step_definition
|
|
105
109
|
rescue Cucumber::CucumberExpressions::UndefinedParameterTypeError => e
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
@configuration.notify(:undefined_parameter_type, e.undefined_parameter_type_name, string_or_regexp)
|
|
111
|
+
# Move the below code into cucumber-expressions. Once done. Switch the line for
|
|
112
|
+
# @configuration.notify(:envelope, e.to_envelope(string_or_regexp))
|
|
113
|
+
to_envelope = Cucumber::Messages::Envelope.new(
|
|
114
|
+
undefined_parameter_type: Cucumber::Messages::UndefinedParameterType.new(
|
|
115
|
+
name: e.undefined_parameter_type_name,
|
|
116
|
+
expression: string_or_regexp
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
@configuration.notify(:envelope, to_envelope)
|
|
110
120
|
end
|
|
111
121
|
|
|
112
122
|
def build_rb_world_factory(world_modules, namespaced_world_modules, proc)
|
|
@@ -128,17 +138,12 @@ module Cucumber
|
|
|
128
138
|
return unless File.extname(code_file) == '.rb'
|
|
129
139
|
|
|
130
140
|
# This will cause self.add_step_definition, self.add_hook, and self.define_parameter_type to be called from Glue::Dsl
|
|
131
|
-
|
|
132
|
-
if Cucumber.use_legacy_autoloader
|
|
133
|
-
load File.expand_path(code_file)
|
|
134
|
-
else
|
|
135
|
-
require File.expand_path(code_file)
|
|
136
|
-
end
|
|
141
|
+
require File.expand_path(code_file)
|
|
137
142
|
end
|
|
138
143
|
|
|
139
144
|
def begin_scenario(test_case)
|
|
140
145
|
@current_world = WorldFactory.new(@world_proc).create_world
|
|
141
|
-
@current_world.extend(ProtoWorld.for(@runtime, test_case
|
|
146
|
+
@current_world.extend(ProtoWorld.for(@runtime, test_case&.language))
|
|
142
147
|
MultiTest.extend_with_best_assertion_library(@current_world)
|
|
143
148
|
@current_world.add_modules!(@world_modules || [], @namespaced_world_modules || {})
|
|
144
149
|
end
|
|
@@ -154,15 +159,27 @@ module Cucumber
|
|
|
154
159
|
end
|
|
155
160
|
|
|
156
161
|
def before_all
|
|
162
|
+
set_up_world_for_global_hooks
|
|
163
|
+
all_succeeded = true
|
|
164
|
+
# Run each `BeforeAll` hook. Ensuring that we store the overall result as the worst status
|
|
157
165
|
hooks[:before_all].each do |hook|
|
|
158
|
-
hook
|
|
166
|
+
result = invoke_run_hook(hook, 'BeforeAll')
|
|
167
|
+
all_succeeded = false unless result
|
|
159
168
|
end
|
|
169
|
+
@current_world = nil
|
|
170
|
+
all_succeeded
|
|
160
171
|
end
|
|
161
172
|
|
|
162
173
|
def after_all
|
|
174
|
+
set_up_world_for_global_hooks
|
|
175
|
+
all_succeeded = true
|
|
176
|
+
# Run each `AfterAll` hook. Ensuring that we store the overall result as the worst status
|
|
163
177
|
hooks[:after_all].each do |hook|
|
|
164
|
-
hook
|
|
178
|
+
result = invoke_run_hook(hook, 'AfterAll')
|
|
179
|
+
all_succeeded = false unless result
|
|
165
180
|
end
|
|
181
|
+
@current_world = nil
|
|
182
|
+
all_succeeded
|
|
166
183
|
end
|
|
167
184
|
|
|
168
185
|
def add_hook(type, hook)
|
|
@@ -187,6 +204,78 @@ module Cucumber
|
|
|
187
204
|
|
|
188
205
|
private
|
|
189
206
|
|
|
207
|
+
def invoke_run_hook(hook, pseudo_method)
|
|
208
|
+
@configuration.notify(:test_run_hook_started, hook)
|
|
209
|
+
|
|
210
|
+
current_test_run_hook_started_id = @configuration.id_generator.new_id
|
|
211
|
+
started_envelope = test_run_hook_started_envelope(hook, current_test_run_hook_started_id)
|
|
212
|
+
@configuration.notify(:envelope, started_envelope)
|
|
213
|
+
|
|
214
|
+
timer = Core::Test::Timer.new.start
|
|
215
|
+
begin
|
|
216
|
+
hook.invoke(pseudo_method, [])
|
|
217
|
+
@configuration.notify(:test_run_hook_finished, hook, Core::Test::Result::Passed.new(timer.duration))
|
|
218
|
+
finished_envelope = test_run_hook_finished_envelope(Core::Test::Result::Passed.new(timer.duration), current_test_run_hook_started_id)
|
|
219
|
+
@configuration.notify(:envelope, finished_envelope)
|
|
220
|
+
true
|
|
221
|
+
rescue StandardError => e
|
|
222
|
+
@configuration.notify(:test_run_hook_finished, hook, Core::Test::Result::Failed.new(timer.duration, e))
|
|
223
|
+
finished_envelope = test_run_hook_finished_envelope(Core::Test::Result::Failed.new(timer.duration, e), current_test_run_hook_started_id)
|
|
224
|
+
@configuration.notify(:envelope, finished_envelope)
|
|
225
|
+
false
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def test_run_hook_started_envelope(hook, id)
|
|
230
|
+
Cucumber::Messages::Envelope.new(
|
|
231
|
+
test_run_hook_started: Cucumber::Messages::TestRunHookStarted.new(
|
|
232
|
+
id: id,
|
|
233
|
+
hook_id: hook.id,
|
|
234
|
+
test_run_started_id: @configuration.test_run_started_id,
|
|
235
|
+
timestamp: time_to_timestamp(Time.now)
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def test_run_hook_finished_envelope(test_result, test_run_hook_started_id)
|
|
241
|
+
result = test_result
|
|
242
|
+
result_message = result.to_message
|
|
243
|
+
|
|
244
|
+
if result.failed?
|
|
245
|
+
result_message = Cucumber::Messages::TestStepResult.new(
|
|
246
|
+
status: result_message.status,
|
|
247
|
+
duration: result_message.duration,
|
|
248
|
+
message: create_error_message(result.exception),
|
|
249
|
+
exception: create_exception_object(result, result.exception)
|
|
250
|
+
)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
Cucumber::Messages::Envelope.new(
|
|
254
|
+
test_run_hook_finished: Cucumber::Messages::TestRunHookFinished.new(
|
|
255
|
+
test_run_hook_started_id: test_run_hook_started_id,
|
|
256
|
+
timestamp: time_to_timestamp(Time.now),
|
|
257
|
+
result: result_message
|
|
258
|
+
)
|
|
259
|
+
)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def create_error_message(message_element)
|
|
263
|
+
<<~ERROR_MESSAGE
|
|
264
|
+
#{message_element.message} (#{message_element.class})
|
|
265
|
+
#{message_element.backtrace}
|
|
266
|
+
ERROR_MESSAGE
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def create_exception_object(result, message_element)
|
|
270
|
+
return unless result.failed?
|
|
271
|
+
|
|
272
|
+
Cucumber::Messages::Exception.new(
|
|
273
|
+
type: message_element.class,
|
|
274
|
+
message: message_element.message,
|
|
275
|
+
stack_trace: message_element.backtrace.join("\n")
|
|
276
|
+
)
|
|
277
|
+
end
|
|
278
|
+
|
|
190
279
|
def parameter_type_envelope(parameter_type)
|
|
191
280
|
# TODO: should this be moved to Cucumber::Expression::ParameterType#to_envelope ??
|
|
192
281
|
# Note: that would mean that cucumber-expression would depend on cucumber-messages
|
|
@@ -197,17 +286,30 @@ module Cucumber
|
|
|
197
286
|
regular_expressions: parameter_type.regexps.map(&:to_s),
|
|
198
287
|
prefer_for_regular_expression_match: parameter_type.prefer_for_regexp_match,
|
|
199
288
|
use_for_snippets: parameter_type.use_for_snippets,
|
|
200
|
-
source_reference:
|
|
201
|
-
uri: parameter_type.transformer.source_location[0],
|
|
202
|
-
location: Cucumber::Messages::Location.new(line: parameter_type.transformer.source_location[1])
|
|
203
|
-
)
|
|
289
|
+
source_reference: source_reference_for(parameter_type.transformer)
|
|
204
290
|
)
|
|
205
291
|
)
|
|
206
292
|
end
|
|
207
293
|
|
|
294
|
+
def source_reference_for(transformer)
|
|
295
|
+
# #source_location may return nil if no definition was found
|
|
296
|
+
# This is the case for transformers created using method(sym) or similar
|
|
297
|
+
return nil if transformer.source_location.nil?
|
|
298
|
+
|
|
299
|
+
Cucumber::Messages::SourceReference.new(
|
|
300
|
+
uri: transformer.source_location[0],
|
|
301
|
+
location: Cucumber::Messages::Location.new(line: transformer.source_location[1])
|
|
302
|
+
)
|
|
303
|
+
end
|
|
304
|
+
|
|
208
305
|
def hooks
|
|
209
306
|
@hooks ||= Hash.new { |h, k| h[k] = [] }
|
|
210
307
|
end
|
|
308
|
+
|
|
309
|
+
def set_up_world_for_global_hooks
|
|
310
|
+
# We don't need a language as we're just creating a world object to attach the BeforeAll / AfterAll hooks to
|
|
311
|
+
begin_scenario(nil)
|
|
312
|
+
end
|
|
211
313
|
end
|
|
212
314
|
end
|
|
213
315
|
end
|
|
@@ -364,17 +364,6 @@ module Cucumber
|
|
|
364
364
|
raise %(The table must have exactly #{width} columns) unless raw[0].size == width
|
|
365
365
|
end
|
|
366
366
|
|
|
367
|
-
# TODO: remove the below function if it's not actually being used.
|
|
368
|
-
# Nothing else in this repo calls it.
|
|
369
|
-
def text?(text)
|
|
370
|
-
Cucumber.deprecate(
|
|
371
|
-
'This method is no longer supported for checking text',
|
|
372
|
-
'#text?',
|
|
373
|
-
'11.0.0'
|
|
374
|
-
)
|
|
375
|
-
raw.flatten.compact.detect { |cell_value| cell_value.index(text) }
|
|
376
|
-
end
|
|
377
|
-
|
|
378
367
|
def cells_rows
|
|
379
368
|
@rows ||= cell_matrix.map do |cell_row|
|
|
380
369
|
Cells.new(self, cell_row)
|
data/lib/cucumber/platform.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rbconfig'
|
|
4
|
-
require 'cucumber/core/platform'
|
|
5
4
|
|
|
6
5
|
module Cucumber
|
|
7
6
|
VERSION = File.read(File.expand_path('../../VERSION', __dir__)).strip
|
|
8
7
|
BINARY = File.expand_path("#{File.dirname(__FILE__)}/../../bin/cucumber")
|
|
9
|
-
LIBDIR = File.expand_path("#{File.dirname(__FILE__)}/../../lib")
|
|
10
8
|
RUBY_BINARY = File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
|
|
9
|
+
JRUBY = defined?(JRUBY_VERSION)
|
|
10
|
+
WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
|
11
11
|
|
|
12
12
|
class << self
|
|
13
13
|
attr_writer :use_full_backtrace
|