cucumber 3.1.2 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1880 -1146
- data/CONTRIBUTING.md +220 -61
- data/README.md +143 -22
- data/bin/cucumber +1 -1
- data/lib/autotest/cucumber_mixin.rb +49 -53
- data/lib/autotest/discover.rb +3 -2
- data/lib/cucumber/cli/configuration.rb +32 -7
- data/lib/cucumber/cli/main.rb +16 -15
- data/lib/cucumber/cli/options.rb +111 -79
- data/lib/cucumber/cli/profile_loader.rb +45 -26
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/configuration.rb +47 -31
- data/lib/cucumber/constantize.rb +3 -6
- data/lib/cucumber/deprecate.rb +32 -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 +12 -0
- data/lib/cucumber/events/step_activated.rb +0 -5
- data/lib/cucumber/events/step_definition_registered.rb +0 -5
- data/lib/cucumber/events/test_case_created.rb +12 -0
- data/lib/cucumber/events/test_case_ready.rb +12 -0
- data/lib/cucumber/events/test_run_finished.rb +2 -1
- data/lib/cucumber/events/test_step_created.rb +12 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +9 -0
- data/lib/cucumber/events.rb +15 -8
- data/lib/cucumber/file_specs.rb +8 -7
- data/lib/cucumber/filters/activate_steps.rb +6 -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 +3 -7
- data/lib/cucumber/filters/tag_limits.rb +1 -3
- data/lib/cucumber/filters.rb +1 -0
- data/lib/cucumber/formatter/ansicolor.rb +74 -86
- data/lib/cucumber/formatter/ast_lookup.rb +163 -0
- data/lib/cucumber/formatter/backtrace_filter.rb +10 -7
- data/lib/cucumber/formatter/console.rb +76 -68
- data/lib/cucumber/formatter/console_counts.rb +4 -9
- data/lib/cucumber/formatter/console_issues.rb +12 -4
- data/lib/cucumber/formatter/duration.rb +1 -1
- data/lib/cucumber/formatter/duration_extractor.rb +4 -1
- data/lib/cucumber/formatter/errors.rb +7 -0
- data/lib/cucumber/formatter/fanout.rb +3 -1
- data/lib/cucumber/formatter/html.rb +11 -598
- data/lib/cucumber/formatter/http_io.rb +152 -0
- data/lib/cucumber/formatter/ignore_missing_messages.rb +2 -2
- data/lib/cucumber/formatter/interceptor.rb +11 -30
- data/lib/cucumber/formatter/io.rb +57 -13
- data/lib/cucumber/formatter/json.rb +119 -124
- data/lib/cucumber/formatter/junit.rb +75 -55
- data/lib/cucumber/formatter/message.rb +23 -0
- data/lib/cucumber/formatter/message_builder.rb +256 -0
- data/lib/cucumber/formatter/pretty.rb +370 -153
- data/lib/cucumber/formatter/progress.rb +31 -32
- data/lib/cucumber/formatter/publish_banner_printer.rb +77 -0
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +32 -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 +42 -0
- data/lib/cucumber/formatter/rerun.rb +24 -4
- data/lib/cucumber/formatter/stepdefs.rb +1 -2
- data/lib/cucumber/formatter/steps.rb +8 -6
- data/lib/cucumber/formatter/summary.rb +17 -8
- data/lib/cucumber/formatter/unicode.rb +18 -20
- data/lib/cucumber/formatter/url_reporter.rb +17 -0
- data/lib/cucumber/formatter/usage.rb +18 -15
- data/lib/cucumber/gherkin/data_table_parser.rb +18 -6
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +14 -18
- data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
- data/lib/cucumber/gherkin/steps_parser.rb +17 -8
- data/lib/cucumber/glue/dsl.rb +29 -15
- data/lib/cucumber/glue/hook.rb +37 -11
- data/lib/cucumber/glue/invoke_in_world.rb +17 -22
- data/lib/cucumber/glue/proto_world.rb +47 -53
- data/lib/cucumber/glue/registry_and_more.rb +62 -17
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/snippet.rb +23 -22
- data/lib/cucumber/glue/step_definition.rb +48 -23
- data/lib/cucumber/glue/world_factory.rb +1 -1
- data/lib/cucumber/hooks.rb +12 -11
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +4 -3
- data/lib/cucumber/multiline_argument/data_table.rb +143 -123
- data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
- data/lib/cucumber/multiline_argument.rb +4 -6
- data/lib/cucumber/platform.rb +5 -5
- data/lib/cucumber/rake/task.rb +34 -25
- data/lib/cucumber/rspec/disable_option_parser.rb +15 -11
- data/lib/cucumber/rspec/doubles.rb +3 -5
- data/lib/cucumber/running_test_case.rb +3 -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/meta_message_builder.rb +106 -0
- data/lib/cucumber/runtime/step_hooks.rb +6 -2
- data/lib/cucumber/runtime/support_code.rb +16 -15
- data/lib/cucumber/runtime/user_interface.rb +10 -19
- data/lib/cucumber/runtime.rb +78 -76
- data/lib/cucumber/step_definition_light.rb +4 -3
- data/lib/cucumber/step_definitions.rb +2 -2
- data/lib/cucumber/step_match.rb +17 -20
- data/lib/cucumber/step_match_search.rb +5 -3
- data/lib/cucumber/term/ansicolor.rb +72 -48
- data/lib/cucumber/term/banner.rb +57 -0
- data/lib/cucumber/version +1 -1
- data/lib/cucumber.rb +3 -2
- data/lib/simplecov_setup.rb +1 -1
- metadata +279 -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
data/lib/cucumber/rake/task.rb
CHANGED
@@ -5,9 +5,7 @@ require 'cucumber/gherkin/formatter/ansi_escapes'
|
|
5
5
|
begin
|
6
6
|
# Support Rake > 0.8.7
|
7
7
|
require 'rake/dsl_definition'
|
8
|
-
# rubocop:disable Lint/HandleExceptions
|
9
8
|
rescue LoadError
|
10
|
-
# rubocop:enable Lint/HandleExceptions
|
11
9
|
end
|
12
10
|
|
13
11
|
module Cucumber
|
@@ -32,14 +30,15 @@ module Cucumber
|
|
32
30
|
include Cucumber::Gherkin::Formatter::AnsiEscapes
|
33
31
|
include ::Rake::DSL if defined?(::Rake::DSL)
|
34
32
|
|
35
|
-
class InProcessCucumberRunner
|
33
|
+
class InProcessCucumberRunner # :nodoc:
|
36
34
|
include ::Rake::DSL if defined?(::Rake::DSL)
|
37
35
|
|
38
36
|
attr_reader :args
|
39
37
|
|
40
38
|
def initialize(libs, cucumber_opts, feature_files)
|
41
|
-
raise 'libs must be an Array when running in-process' unless Array
|
42
|
-
|
39
|
+
raise 'libs must be an Array when running in-process' unless libs.instance_of? Array
|
40
|
+
|
41
|
+
libs.reverse_each { |lib| $LOAD_PATH.unshift(lib) }
|
43
42
|
@args = (
|
44
43
|
cucumber_opts +
|
45
44
|
feature_files
|
@@ -53,7 +52,7 @@ module Cucumber
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
|
56
|
-
class ForkedCucumberRunner
|
55
|
+
class ForkedCucumberRunner # :nodoc:
|
57
56
|
include ::Rake::DSL if defined?(::Rake::DSL)
|
58
57
|
|
59
58
|
def initialize(libs, cucumber_bin, cucumber_opts, bundler, feature_files)
|
@@ -65,11 +64,11 @@ module Cucumber
|
|
65
64
|
end
|
66
65
|
|
67
66
|
def load_path
|
68
|
-
[format('"
|
67
|
+
[format('"%<path>s"', path: @libs.join(File::PATH_SEPARATOR))]
|
69
68
|
end
|
70
69
|
|
71
70
|
def quoted_binary(cucumber_bin)
|
72
|
-
[format('"
|
71
|
+
[format('"%<path>s"', path: cucumber_bin)]
|
73
72
|
end
|
74
73
|
|
75
74
|
def use_bundler
|
@@ -98,9 +97,7 @@ module Cucumber
|
|
98
97
|
|
99
98
|
def run
|
100
99
|
sh cmd.join(' ') do |ok, res|
|
101
|
-
|
102
|
-
exit res.exitstatus
|
103
|
-
end
|
100
|
+
exit res.exitstatus unless ok
|
104
101
|
end
|
105
102
|
end
|
106
103
|
end
|
@@ -113,9 +110,18 @@ module Cucumber
|
|
113
110
|
|
114
111
|
# Extra options to pass to the cucumber binary. Can be overridden by the CUCUMBER_OPTS environment variable.
|
115
112
|
# It's recommended to pass an Array, but if it's a String it will be #split by ' '.
|
116
|
-
|
117
|
-
|
118
|
-
|
113
|
+
attr_reader :cucumber_opts
|
114
|
+
|
115
|
+
def cucumber_opts=(opts) # :nodoc:
|
116
|
+
unless opts.instance_of? String
|
117
|
+
@cucumber_opts = opts
|
118
|
+
return
|
119
|
+
end
|
120
|
+
|
121
|
+
@cucumber_opts = opts.split(' ')
|
122
|
+
return if @cucumber_opts.length <= 1
|
123
|
+
|
124
|
+
$stderr.puts 'WARNING: consider using an array rather than a space-delimited string with cucumber_opts to avoid undesired behavior.'
|
119
125
|
end
|
120
126
|
|
121
127
|
# Whether or not to fork a new ruby interpreter. Defaults to true. You may gain
|
@@ -134,38 +140,41 @@ module Cucumber
|
|
134
140
|
# Note that this attribute has no effect if you don't run in forked mode.
|
135
141
|
attr_accessor :bundler
|
136
142
|
|
143
|
+
# Name of the running task
|
144
|
+
attr_reader :task_name
|
145
|
+
|
137
146
|
# Define Cucumber Rake task
|
138
147
|
def initialize(task_name = 'cucumber', desc = 'Run Cucumber features')
|
139
|
-
@task_name
|
148
|
+
@task_name = task_name
|
149
|
+
@desc = desc
|
140
150
|
@fork = true
|
141
151
|
@libs = ['lib']
|
142
|
-
@rcov_opts = %w
|
152
|
+
@rcov_opts = %w[--rails --exclude osx\/objc,gems\/]
|
143
153
|
yield self if block_given?
|
144
154
|
@binary = binary.nil? ? Cucumber::BINARY : File.expand_path(binary)
|
145
155
|
define_task
|
146
156
|
end
|
147
157
|
|
148
|
-
def define_task
|
158
|
+
def define_task # :nodoc:
|
149
159
|
desc @desc
|
150
160
|
task @task_name do
|
151
161
|
runner.run
|
152
162
|
end
|
153
163
|
end
|
154
164
|
|
155
|
-
def runner(_task_args = nil)
|
165
|
+
def runner(_task_args = nil) # :nodoc:
|
156
166
|
cucumber_opts = [(ENV['CUCUMBER_OPTS'] ? ENV['CUCUMBER_OPTS'].split(/\s+/) : nil) || cucumber_opts_with_profile]
|
157
|
-
if
|
158
|
-
|
159
|
-
end
|
167
|
+
return ForkedCucumberRunner.new(libs, binary, cucumber_opts, bundler, feature_files) if fork
|
168
|
+
|
160
169
|
InProcessCucumberRunner.new(libs, cucumber_opts, feature_files)
|
161
170
|
end
|
162
171
|
|
163
|
-
def cucumber_opts_with_profile
|
164
|
-
Array(cucumber_opts).concat
|
172
|
+
def cucumber_opts_with_profile # :nodoc:
|
173
|
+
Array(cucumber_opts).concat(Array(@profile).flat_map { |p| ['--profile', p] })
|
165
174
|
end
|
166
175
|
|
167
|
-
def feature_files
|
168
|
-
make_command_line_safe(FileList[
|
176
|
+
def feature_files # :nodoc:
|
177
|
+
make_command_line_safe(FileList[ENV['FEATURE'] || []])
|
169
178
|
end
|
170
179
|
|
171
180
|
def make_command_line_safe(list)
|
@@ -2,23 +2,27 @@
|
|
2
2
|
|
3
3
|
require 'optparse'
|
4
4
|
|
5
|
-
module Spec
|
6
|
-
module Runner
|
5
|
+
module Spec # :nodoc:
|
6
|
+
module Runner # :nodoc:
|
7
7
|
# Neuters RSpec's option parser.
|
8
8
|
# (RSpec's option parser tries to parse ARGV, which
|
9
9
|
# will fail when running cucumber)
|
10
|
-
class OptionParser < ::OptionParser
|
10
|
+
class OptionParser < ::OptionParser # :nodoc:
|
11
11
|
NEUTERED_RSPEC = Object.new
|
12
|
-
def NEUTERED_RSPEC.method_missing(
|
12
|
+
def NEUTERED_RSPEC.method_missing(_method, *_args) # rubocop:disable Style/MissingRespondToMissing
|
13
|
+
self || super
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.method_added(method)
|
17
|
+
return if @__neutering_rspec
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
define_method(m) do |*a|
|
18
|
-
NEUTERED_RSPEC
|
19
|
-
end
|
20
|
-
@__neutering_rspec = false
|
19
|
+
@__neutering_rspec = true
|
20
|
+
define_method(method) do |*_a|
|
21
|
+
NEUTERED_RSPEC
|
21
22
|
end
|
23
|
+
@__neutering_rspec = false
|
24
|
+
|
25
|
+
super
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -15,45 +15,12 @@ module Cucumber
|
|
15
15
|
# the passed / failed / undefined / skipped status of
|
16
16
|
# the test case.
|
17
17
|
#
|
18
|
-
# The test case might come from a regular Scenario or
|
19
|
-
# a Scenario outline. You can call the `#outline?`
|
20
|
-
# predicate to find out. If it's from an outline,
|
21
|
-
# you get a couple of extra methods.
|
22
18
|
module RunningTestCase
|
23
19
|
def self.new(test_case)
|
24
|
-
|
20
|
+
TestCase.new(test_case)
|
25
21
|
end
|
26
22
|
|
27
|
-
class
|
28
|
-
def initialize(test_case)
|
29
|
-
@test_case = test_case
|
30
|
-
test_case.describe_source_to(self)
|
31
|
-
end
|
32
|
-
|
33
|
-
def feature(feature)
|
34
|
-
end
|
35
|
-
|
36
|
-
def scenario(_scenario)
|
37
|
-
@factory = Scenario
|
38
|
-
end
|
39
|
-
|
40
|
-
def scenario_outline(_scenario)
|
41
|
-
@factory = ScenarioOutlineExample
|
42
|
-
end
|
43
|
-
|
44
|
-
def examples_table(examples_table)
|
45
|
-
end
|
46
|
-
|
47
|
-
def examples_table_row(row)
|
48
|
-
end
|
49
|
-
|
50
|
-
def running_test_case
|
51
|
-
@factory.new(@test_case)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
private_constant :Builder
|
55
|
-
|
56
|
-
class Scenario < SimpleDelegator
|
23
|
+
class TestCase < SimpleDelegator
|
57
24
|
def initialize(test_case, result = Core::Test::Result::Unknown.new)
|
58
25
|
@test_case = test_case
|
59
26
|
@result = result
|
@@ -66,6 +33,7 @@ module Cucumber
|
|
66
33
|
|
67
34
|
def exception
|
68
35
|
return unless @result.failed?
|
36
|
+
|
69
37
|
@result.exception
|
70
38
|
end
|
71
39
|
|
@@ -85,27 +53,9 @@ module Cucumber
|
|
85
53
|
tags.map &:name
|
86
54
|
end
|
87
55
|
|
88
|
-
def outline?
|
89
|
-
false
|
90
|
-
end
|
91
|
-
|
92
56
|
def with_result(result)
|
93
57
|
self.class.new(@test_case, result)
|
94
58
|
end
|
95
59
|
end
|
96
|
-
|
97
|
-
class ScenarioOutlineExample < Scenario
|
98
|
-
def outline?
|
99
|
-
true
|
100
|
-
end
|
101
|
-
|
102
|
-
def scenario_outline
|
103
|
-
self
|
104
|
-
end
|
105
|
-
|
106
|
-
def cell_values
|
107
|
-
source.last.values
|
108
|
-
end
|
109
|
-
end
|
110
60
|
end
|
111
61
|
end
|
@@ -3,23 +3,27 @@
|
|
3
3
|
module Cucumber
|
4
4
|
class Runtime
|
5
5
|
class AfterHooks
|
6
|
-
def initialize(hooks, scenario)
|
6
|
+
def initialize(id_generator, hooks, scenario, event_bus)
|
7
7
|
@hooks = hooks
|
8
8
|
@scenario = scenario
|
9
|
+
@id_generator = id_generator
|
10
|
+
@event_bus = event_bus
|
9
11
|
end
|
10
12
|
|
11
13
|
def apply_to(test_case)
|
12
14
|
test_case.with_steps(
|
13
|
-
test_case.test_steps + after_hooks
|
15
|
+
test_case.test_steps + after_hooks.reverse
|
14
16
|
)
|
15
17
|
end
|
16
18
|
|
17
19
|
private
|
18
20
|
|
19
|
-
def after_hooks
|
21
|
+
def after_hooks
|
20
22
|
@hooks.map do |hook|
|
21
23
|
action = ->(result) { hook.invoke('After', @scenario.with_result(result)) }
|
22
|
-
Hooks.after_hook(
|
24
|
+
hook_step = Hooks.after_hook(@id_generator.new_id, hook.location, &action)
|
25
|
+
@event_bus.hook_test_step_created(hook_step, hook)
|
26
|
+
hook_step
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -5,23 +5,27 @@ require 'cucumber/hooks'
|
|
5
5
|
module Cucumber
|
6
6
|
class Runtime
|
7
7
|
class BeforeHooks
|
8
|
-
def initialize(hooks, scenario)
|
8
|
+
def initialize(id_generator, hooks, scenario, event_bus)
|
9
9
|
@hooks = hooks
|
10
10
|
@scenario = scenario
|
11
|
+
@id_generator = id_generator
|
12
|
+
@event_bus = event_bus
|
11
13
|
end
|
12
14
|
|
13
15
|
def apply_to(test_case)
|
14
16
|
test_case.with_steps(
|
15
|
-
before_hooks
|
17
|
+
before_hooks + test_case.test_steps
|
16
18
|
)
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
22
|
|
21
|
-
def before_hooks
|
23
|
+
def before_hooks
|
22
24
|
@hooks.map do |hook|
|
23
25
|
action_block = ->(result) { hook.invoke('Before', @scenario.with_result(result)) }
|
24
|
-
Hooks.before_hook(
|
26
|
+
hook_step = Hooks.before_hook(@id_generator.new_id, hook.location, &action_block)
|
27
|
+
@event_bus.hook_test_step_created(hook_step, hook)
|
28
|
+
hook_step
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'forwardable'
|
4
|
-
require 'cucumber/core/
|
4
|
+
require 'cucumber/core/test/doc_string'
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
class Runtime
|
@@ -15,11 +15,13 @@ module Cucumber
|
|
15
15
|
attr_reader :support_code
|
16
16
|
|
17
17
|
def initialize(support_code, user_interface)
|
18
|
-
@support_code
|
18
|
+
@support_code = support_code
|
19
|
+
@user_interface = user_interface
|
19
20
|
end
|
20
21
|
|
21
22
|
def_delegators :@user_interface,
|
22
23
|
:embed,
|
24
|
+
:attach,
|
23
25
|
:ask,
|
24
26
|
:puts,
|
25
27
|
:features_paths,
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'cucumber/messages'
|
2
|
+
require 'cucumber/ci_environment'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
class Runtime
|
6
|
+
# Builder to instanciate a Cucumber::Messages::Meta message filled-in with
|
7
|
+
# the runtime meta-data:
|
8
|
+
# - protocol version: the version of the Cucumber::Messages protocol
|
9
|
+
# - implementation: the name and version of the implementation (e.g. cucumber-ruby 8.0.0)
|
10
|
+
# - runtime: the name and version of the runtime (e.g. ruby 3.0.1)
|
11
|
+
# - os: the name and version of the operating system (e.g. linux 3.13.0-45-generic)
|
12
|
+
# - cpu: the name of the CPU (e.g. x86_64)
|
13
|
+
# - ci: informtion about the CI environment if any, including:
|
14
|
+
# - name: the name of the CI environment (e.g. Jenkins)
|
15
|
+
# - url: the URL of the CI environment (e.g. https://ci.example.com)
|
16
|
+
# - build_number: the build number of the CI environment (e.g. 123)
|
17
|
+
# - git: the git information of the CI environment if any
|
18
|
+
# - remote: the remote of the git repository (e.g. git@github.com:cucumber/cucumber-ruby.git)
|
19
|
+
# - revision: the revision of the git repository (e.g. abcdef)
|
20
|
+
# - branch: the name of the git branch (e.g. main)
|
21
|
+
# - tag: the name of the git tag (e.g. v1.0.0)
|
22
|
+
class MetaMessageBuilder
|
23
|
+
class << self
|
24
|
+
# Builds a Cucumber::Messages::Meta filled-in with the runtime meta-data
|
25
|
+
#
|
26
|
+
# @param [env] environment data from which the CI information will be
|
27
|
+
# retrieved (default ENV). Can be used to mock the environment for
|
28
|
+
# testing purpose.
|
29
|
+
#
|
30
|
+
# @return [Cucumber::Messages::Meta] the meta message
|
31
|
+
#
|
32
|
+
# @see Cucumber::Runtime::MetaMessageBuilder
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# Cucumber::Runtime::MetaMessageBuilder.build_meta_message
|
36
|
+
#
|
37
|
+
def build_meta_message(env = ENV)
|
38
|
+
Cucumber::Messages::Meta.new(
|
39
|
+
protocol_version: protocol_version,
|
40
|
+
implementation: implementation,
|
41
|
+
runtime: runtime,
|
42
|
+
os: os,
|
43
|
+
cpu: cpu,
|
44
|
+
ci: ci(env)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def protocol_version
|
51
|
+
Cucumber::Messages::VERSION
|
52
|
+
end
|
53
|
+
|
54
|
+
def implementation
|
55
|
+
Cucumber::Messages::Product.new(
|
56
|
+
name: 'cucumber-ruby',
|
57
|
+
version: Cucumber::VERSION
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def runtime
|
62
|
+
Cucumber::Messages::Product.new(
|
63
|
+
name: RUBY_ENGINE,
|
64
|
+
version: RUBY_VERSION
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def os
|
69
|
+
Cucumber::Messages::Product.new(
|
70
|
+
name: RbConfig::CONFIG['target_os'],
|
71
|
+
version: Sys::Uname.uname.version
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def cpu
|
76
|
+
Cucumber::Messages::Product.new(
|
77
|
+
name: RbConfig::CONFIG['target_cpu']
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ci(env)
|
82
|
+
ci_data = Cucumber::CiEnvironment.detect_ci_environment(env)
|
83
|
+
return nil unless ci_data
|
84
|
+
|
85
|
+
Cucumber::Messages::Ci.new(
|
86
|
+
name: ci_data[:name],
|
87
|
+
url: ci_data[:url],
|
88
|
+
build_number: ci_data[:buildNumber],
|
89
|
+
git: git_info(ci_data)
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
def git_info(ci_data)
|
94
|
+
return nil unless ci_data[:git]
|
95
|
+
|
96
|
+
Cucumber::Messages::Git.new(
|
97
|
+
remote: ci_data[:git][:remote],
|
98
|
+
revision: ci_data[:git][:revision],
|
99
|
+
branch: ci_data[:git][:branch],
|
100
|
+
tag: ci_data[:git][:tag]
|
101
|
+
)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module Cucumber
|
4
4
|
class Runtime
|
5
5
|
class StepHooks
|
6
|
-
def initialize(hooks)
|
6
|
+
def initialize(id_generator, hooks, event_bus)
|
7
7
|
@hooks = hooks
|
8
|
+
@id_generator = id_generator
|
9
|
+
@event_bus = event_bus
|
8
10
|
end
|
9
11
|
|
10
12
|
def apply(test_steps)
|
@@ -18,7 +20,9 @@ module Cucumber
|
|
18
20
|
def after_step_hooks(test_step)
|
19
21
|
@hooks.map do |hook|
|
20
22
|
action = ->(*args) { hook.invoke('AfterStep', [args, test_step]) }
|
21
|
-
Hooks.after_step_hook(
|
23
|
+
hook_step = Hooks.after_step_hook(@id_generator.new_id, test_step, hook.location, &action)
|
24
|
+
@event_bus.hook_test_step_created(hook_step, hook)
|
25
|
+
hook_step
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -22,19 +22,15 @@ module Cucumber
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def step(step)
|
25
|
-
location = Core::
|
25
|
+
location = Core::Test::Location.of_caller
|
26
26
|
@support_code.invoke_dynamic_step(step[:text], multiline_arg(step, location))
|
27
27
|
end
|
28
28
|
|
29
29
|
def multiline_arg(step, location)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
MultilineArgument.from(argument[:content], location, argument[:content_type])
|
35
|
-
else
|
36
|
-
MultilineArgument::DataTable.from(argument[:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
|
37
|
-
end
|
30
|
+
if !step[:doc_string].nil?
|
31
|
+
MultilineArgument.from(step[:doc_string][:content], location, step[:doc_string][:content_type])
|
32
|
+
elsif !step[:data_table].nil?
|
33
|
+
MultilineArgument::DataTable.from(step[:data_table][:rows].map { |row| row[:cells].map { |cell| cell[:value] } })
|
38
34
|
else
|
39
35
|
MultilineArgument.from(nil)
|
40
36
|
end
|
@@ -62,8 +58,8 @@ module Cucumber
|
|
62
58
|
# Given I have 8 cukes in my belly
|
63
59
|
# Then I should not be thirsty
|
64
60
|
# })
|
65
|
-
def invoke_dynamic_steps(steps_text,
|
66
|
-
parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self),
|
61
|
+
def invoke_dynamic_steps(steps_text, iso_code, _location)
|
62
|
+
parser = Cucumber::Gherkin::StepsParser.new(StepInvoker.new(self), iso_code)
|
67
63
|
parser.parse(steps_text)
|
68
64
|
end
|
69
65
|
|
@@ -76,6 +72,7 @@ module Cucumber
|
|
76
72
|
def invoke_dynamic_step(step_name, multiline_argument, _location = nil)
|
77
73
|
matches = step_matches(step_name)
|
78
74
|
raise UndefinedDynamicStep, step_name if matches.empty?
|
75
|
+
|
79
76
|
matches.first.invoke(multiline_argument)
|
80
77
|
end
|
81
78
|
|
@@ -108,26 +105,30 @@ module Cucumber
|
|
108
105
|
def find_after_step_hooks(test_case)
|
109
106
|
scenario = RunningTestCase.new(test_case)
|
110
107
|
hooks = registry.hooks_for(:after_step, scenario)
|
111
|
-
StepHooks.new hooks
|
108
|
+
StepHooks.new(@configuration.id_generator, hooks, @configuration.event_bus)
|
112
109
|
end
|
113
110
|
|
114
111
|
def apply_before_hooks(test_case)
|
112
|
+
return test_case if test_case.test_steps.empty?
|
113
|
+
|
115
114
|
scenario = RunningTestCase.new(test_case)
|
116
115
|
hooks = registry.hooks_for(:before, scenario)
|
117
|
-
BeforeHooks.new(hooks, scenario).apply_to(test_case)
|
116
|
+
BeforeHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
|
118
117
|
end
|
119
118
|
|
120
119
|
def apply_after_hooks(test_case)
|
120
|
+
return test_case if test_case.test_steps.empty?
|
121
|
+
|
121
122
|
scenario = RunningTestCase.new(test_case)
|
122
123
|
hooks = registry.hooks_for(:after, scenario)
|
123
|
-
AfterHooks.new(hooks, scenario).apply_to(test_case)
|
124
|
+
AfterHooks.new(@configuration.id_generator, hooks, scenario, @configuration.event_bus).apply_to(test_case)
|
124
125
|
end
|
125
126
|
|
126
127
|
def find_around_hooks(test_case)
|
127
128
|
scenario = RunningTestCase.new(test_case)
|
128
129
|
|
129
130
|
registry.hooks_for(:around, scenario).map do |hook|
|
130
|
-
Hooks.around_hook
|
131
|
+
Hooks.around_hook do |run_scenario|
|
131
132
|
hook.invoke('Around', scenario, &run_scenario)
|
132
133
|
end
|
133
134
|
end
|
@@ -7,14 +7,6 @@ module Cucumber
|
|
7
7
|
module UserInterface
|
8
8
|
attr_writer :visitor
|
9
9
|
|
10
|
-
# Output +messages+ alongside the formatted output.
|
11
|
-
# This is an alternative to using Kernel#puts - it will display
|
12
|
-
# nicer, and in all outputs (in case you use several formatters)
|
13
|
-
#
|
14
|
-
def puts(*messages)
|
15
|
-
@visitor.puts(*messages)
|
16
|
-
end
|
17
|
-
|
18
10
|
# Suspends execution and prompts +question+ to the console (STDOUT).
|
19
11
|
# An operator (manual tester) can then enter a line of text and hit
|
20
12
|
# <ENTER>. The entered text is returned, and both +question+ and
|
@@ -29,8 +21,8 @@ module Cucumber
|
|
29
21
|
# that makes a sound before invoking #ask.
|
30
22
|
#
|
31
23
|
def ask(question, timeout_seconds)
|
32
|
-
|
33
|
-
|
24
|
+
$stdout.puts(question)
|
25
|
+
$stdout.flush
|
34
26
|
puts(question)
|
35
27
|
|
36
28
|
answer = if Cucumber::JRUBY
|
@@ -40,6 +32,7 @@ module Cucumber
|
|
40
32
|
end
|
41
33
|
|
42
34
|
raise("Waited for input for #{timeout_seconds} seconds, then timed out.") unless answer
|
35
|
+
|
43
36
|
puts(answer)
|
44
37
|
answer
|
45
38
|
end
|
@@ -48,26 +41,24 @@ module Cucumber
|
|
48
41
|
# be a path to a file, or if it's an image it may also be a Base64 encoded image.
|
49
42
|
# The embedded data may or may not be ignored, depending on what kind of formatter(s) are active.
|
50
43
|
#
|
51
|
-
def
|
52
|
-
@visitor.
|
44
|
+
def attach(src, media_type)
|
45
|
+
@visitor.attach(src, media_type)
|
53
46
|
end
|
54
47
|
|
55
48
|
private
|
56
49
|
|
57
50
|
def mri_gets(timeout_seconds)
|
58
|
-
|
59
|
-
|
60
|
-
STDIN.gets
|
61
|
-
end
|
62
|
-
rescue Timeout::Error
|
63
|
-
nil
|
51
|
+
Timeout.timeout(timeout_seconds) do
|
52
|
+
$stdin.gets
|
64
53
|
end
|
54
|
+
rescue Timeout::Error
|
55
|
+
nil
|
65
56
|
end
|
66
57
|
|
67
58
|
def jruby_gets(timeout_seconds)
|
68
59
|
answer = nil
|
69
60
|
t = java.lang.Thread.new do
|
70
|
-
answer =
|
61
|
+
answer = $stdin.gets
|
71
62
|
end
|
72
63
|
t.start
|
73
64
|
t.join(timeout_seconds * 1000)
|