cucumber 7.0.0 → 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 +4 -4
- data/CHANGELOG.md +329 -170
- data/CONTRIBUTING.md +2 -6
- data/README.md +7 -5
- 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 +8 -2
- 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 -63
- data/lib/cucumber/formatter/ast_lookup.rb +2 -2
- data/lib/cucumber/formatter/backtrace_filter.rb +2 -1
- data/lib/cucumber/formatter/console.rb +10 -2
- 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 +5 -3
- data/lib/cucumber/formatter/json.rb +8 -6
- data/lib/cucumber/formatter/junit.rb +6 -3
- data/lib/cucumber/formatter/message_builder.rb +3 -2
- data/lib/cucumber/formatter/pretty.rb +15 -5
- data/lib/cucumber/formatter/progress.rb +1 -0
- 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/summary.rb +1 -0
- data/lib/cucumber/formatter/unicode.rb +4 -4
- data/lib/cucumber/formatter/usage.rb +3 -3
- data/lib/cucumber/gherkin/data_table_parser.rb +1 -0
- data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +2 -2
- data/lib/cucumber/glue/dsl.rb +29 -15
- data/lib/cucumber/glue/hook.rb +6 -3
- data/lib/cucumber/glue/invoke_in_world.rb +4 -4
- data/lib/cucumber/glue/proto_world.rb +10 -9
- data/lib/cucumber/glue/registry_and_more.rb +22 -7
- data/lib/cucumber/glue/registry_wrapper.rb +31 -0
- data/lib/cucumber/glue/step_definition.rb +6 -3
- 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 +20 -9
- 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 +36 -22
- data/lib/cucumber/step_match.rb +5 -3
- 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 +96 -88
data/CONTRIBUTING.md
CHANGED
@@ -83,11 +83,8 @@ with a lot of libraries. You will find there what is related to:
|
|
83
83
|
step definition
|
84
84
|
- everyting related to the HTML formatter
|
85
85
|
|
86
|
-
`cucumber-ruby` is also composed of:
|
87
|
-
|
88
|
-
- [cucumber-ruby-core]: this is the engine that will execute the test cases
|
89
|
-
computed from a parsed Gherkin document
|
90
|
-
- [cucumber-ruby-wire]: everything related to the Cucumber's wire protocol
|
86
|
+
`cucumber-ruby` is also composed of [cucumber-ruby-core]: this is the engine that
|
87
|
+
will execute the test cases computed from a parsed Gherkin document
|
91
88
|
|
92
89
|
Last but not least, there is also a repository for [cucumber-rails], the gem
|
93
90
|
that brings Cucumber to Rails 5.x and 6.x.
|
@@ -236,7 +233,6 @@ You can find additional documentation in the [docs](./docs) directory such as
|
|
236
233
|
[cucumber-docs]: https://cucumber.io/docs/cucumber
|
237
234
|
[cucumber/common]: https://github.com/cucumber/common
|
238
235
|
[cucumber-ruby-core]: https://github.com/cucumber/cucumber-ruby-core
|
239
|
-
[cucumber-ruby-wire]: https://github.com/cucumber/cucumber-ruby-wire
|
240
236
|
[cucumber-rails]: https://github.com/cucumber/cucumber-rails
|
241
237
|
[cucumber-ruby-issues]: https://github.com/cucumber/cucumber-ruby/search?q=is%3Aissue
|
242
238
|
[cucumber/common-issues]: https://github.com/cucumber/common/search?q=is%3Aissue
|
data/README.md
CHANGED
@@ -4,11 +4,12 @@
|
|
4
4
|
|
5
5
|
# Cucumber
|
6
6
|
|
7
|
+
[](https://vshymanskyy.github.io/StandWithUkraine)
|
7
8
|
[](https://opencollective.com/cucumber)
|
8
9
|
[](https://opencollective.com/cucumber)
|
9
10
|
[](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-ruby)
|
10
11
|
[](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-ruby)
|
11
|
-
[](https://github.com/cucumber/cucumber-ruby/actions/workflows/cucumber-ruby.yml)
|
12
13
|
[](https://codeclimate.com/github/cucumber/cucumber-ruby)
|
13
14
|
[](https://coveralls.io/r/cucumber/cucumber-ruby?branch=main)
|
14
15
|
|
@@ -50,13 +51,14 @@ Later in this document, bundler is considered being used so all commands are usi
|
|
50
51
|
|
51
52
|
### Supported platforms
|
52
53
|
|
54
|
+
- Ruby 3.1
|
53
55
|
- Ruby 3.0
|
54
56
|
- Ruby 2.7
|
55
57
|
- Ruby 2.6
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
|
58
|
+
- TruffleRuby 22.0.0+
|
59
|
+
- JRuby (with [some limitations](https://github.com/cucumber/cucumber-ruby/blob/main/docs/jruby-limitations.md))
|
60
|
+
- 9.3 >= 9.3.1 (there is a known issue with JRuby 9.3.0. More info can
|
61
|
+
be found in the [PR#1571](https://github.com/cucumber/cucumber-ruby/pull/1571).)
|
60
62
|
|
61
63
|
### Ruby on Rails
|
62
64
|
|
@@ -24,7 +24,7 @@ module Autotest::CucumberMixin
|
|
24
24
|
add_sigint_handler
|
25
25
|
|
26
26
|
loop do # ^c handler
|
27
|
-
|
27
|
+
wait_for_green
|
28
28
|
if tainted
|
29
29
|
rerun_all_tests
|
30
30
|
rerun_all_features if all_good
|
@@ -37,6 +37,7 @@ module Autotest::CucumberMixin
|
|
37
37
|
reset_features
|
38
38
|
rescue Interrupt
|
39
39
|
break if wants_to_quit
|
40
|
+
|
40
41
|
reset
|
41
42
|
reset_features
|
42
43
|
end
|
@@ -47,7 +48,7 @@ module Autotest::CucumberMixin
|
|
47
48
|
features_to_run == ''
|
48
49
|
end
|
49
50
|
|
50
|
-
def
|
51
|
+
def wait_for_green
|
51
52
|
loop do
|
52
53
|
super
|
53
54
|
run_features
|
@@ -70,6 +71,7 @@ module Autotest::CucumberMixin
|
|
70
71
|
Tempfile.open('autotest-cucumber') do |dirty_features_file|
|
71
72
|
cmd = make_cucumber_cmd(features_to_run, dirty_features_file.path)
|
72
73
|
break if cmd.empty?
|
74
|
+
|
73
75
|
old_sync = $stdout.sync
|
74
76
|
$stdout.sync = true
|
75
77
|
self.results = []
|
@@ -81,6 +83,7 @@ module Autotest::CucumberMixin
|
|
81
83
|
print(c)
|
82
84
|
line << c
|
83
85
|
next unless c == "\n"
|
86
|
+
|
84
87
|
results << line.join
|
85
88
|
line.clear
|
86
89
|
end
|
data/lib/autotest/discover.rb
CHANGED
@@ -2,9 +2,10 @@
|
|
2
2
|
|
3
3
|
Autotest.add_discovery do
|
4
4
|
if File.directory?('features')
|
5
|
-
|
5
|
+
case ENV['AUTOFEATURE']
|
6
|
+
when /true/i
|
6
7
|
'cucumber'
|
7
|
-
|
8
|
+
when /false/i
|
8
9
|
# noop
|
9
10
|
else
|
10
11
|
puts '(Not running features. To run features in autotest, set AUTOFEATURE=true.)'
|
@@ -9,7 +9,9 @@ require 'cucumber'
|
|
9
9
|
module Cucumber
|
10
10
|
module Cli
|
11
11
|
class YmlLoadError < StandardError; end
|
12
|
+
|
12
13
|
class ProfilesNotDefinedError < YmlLoadError; end
|
14
|
+
|
13
15
|
class ProfileNotFound < StandardError; end
|
14
16
|
|
15
17
|
class Configuration
|
@@ -17,7 +19,7 @@ module Cucumber
|
|
17
19
|
|
18
20
|
attr_reader :out_stream
|
19
21
|
|
20
|
-
def initialize(out_stream =
|
22
|
+
def initialize(out_stream = $stdout, error_stream = $stderr)
|
21
23
|
@out_stream = out_stream
|
22
24
|
@error_stream = error_stream
|
23
25
|
@options = Options.new(@out_stream, @error_stream, default_profile: 'default')
|
@@ -28,6 +30,7 @@ module Cucumber
|
|
28
30
|
@options.parse!(args)
|
29
31
|
arrange_formats
|
30
32
|
raise("You can't use both --strict and --wip") if strict.strict? && wip?
|
33
|
+
|
31
34
|
set_environment_variables
|
32
35
|
end
|
33
36
|
|
data/lib/cucumber/cli/main.rb
CHANGED
@@ -14,7 +14,7 @@ module Cucumber
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def initialize(args,
|
17
|
+
def initialize(args, out = $stdout, err = $stderr, kernel = Kernel)
|
18
18
|
@args = args
|
19
19
|
@out = out
|
20
20
|
@err = err
|
@@ -41,7 +41,7 @@ module Cucumber
|
|
41
41
|
@err.puts("Couldn't open #{e.path}")
|
42
42
|
exit_unable_to_finish
|
43
43
|
rescue FeatureFolderNotFoundException => e
|
44
|
-
@err.puts(e.message
|
44
|
+
@err.puts("#{e.message}. You can use `cucumber --init` to get started.")
|
45
45
|
exit_unable_to_finish
|
46
46
|
rescue ProfilesNotDefinedError, YmlLoadError, ProfileNotFound => e
|
47
47
|
@err.puts(e.message)
|
@@ -85,13 +85,14 @@ module Cucumber
|
|
85
85
|
trap('INT') do
|
86
86
|
exit_unable_to_finish! if Cucumber.wants_to_quit
|
87
87
|
Cucumber.wants_to_quit = true
|
88
|
-
|
88
|
+
$stderr.puts "\nExiting... Interrupt again to exit immediately."
|
89
89
|
exit_unable_to_finish
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
93
|
def runtime(existing_runtime)
|
94
94
|
return Runtime.new(configuration) unless existing_runtime
|
95
|
+
|
95
96
|
existing_runtime.configure(configuration)
|
96
97
|
existing_runtime
|
97
98
|
end
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -63,13 +63,13 @@ module Cucumber
|
|
63
63
|
'--lines', '--port', '-I', '--snippet-type'
|
64
64
|
].freeze
|
65
65
|
ORDER_TYPES = %w[defined random].freeze
|
66
|
-
TAG_LIMIT_MATCHER = /(?<tag_name
|
66
|
+
TAG_LIMIT_MATCHER = /(?<tag_name>@\w+):(?<limit>\d+)/x
|
67
67
|
|
68
68
|
def self.parse(args, out_stream, error_stream, options = {})
|
69
69
|
new(out_stream, error_stream, options).parse!(args)
|
70
70
|
end
|
71
71
|
|
72
|
-
def initialize(out_stream =
|
72
|
+
def initialize(out_stream = $stdout, error_stream = $stderr, options = {})
|
73
73
|
@out_stream = out_stream
|
74
74
|
@error_stream = error_stream
|
75
75
|
|
@@ -180,6 +180,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
180
180
|
def check_formatter_stream_conflicts
|
181
181
|
streams = @options[:formats].uniq.map { |(_, _, stream)| stream }
|
182
182
|
return if streams == streams.uniq
|
183
|
+
|
183
184
|
raise 'All but one formatter must use --out, only one can print to each stream (or STDOUT)'
|
184
185
|
end
|
185
186
|
|
@@ -203,6 +204,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
203
204
|
|
204
205
|
def truthy_string?(str)
|
205
206
|
return false if str.nil?
|
207
|
+
|
206
208
|
str !~ /^(false|no|0)$/i
|
207
209
|
end
|
208
210
|
|
@@ -367,6 +369,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
367
369
|
def require_files(v)
|
368
370
|
@options[:require] << v
|
369
371
|
return unless Cucumber::JRUBY && File.directory?(v)
|
372
|
+
|
370
373
|
require 'java'
|
371
374
|
$CLASSPATH << v
|
372
375
|
end
|
@@ -385,6 +388,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
385
388
|
require 'gherkin/dialect'
|
386
389
|
|
387
390
|
return indicate_invalid_language_and_exit(lang) unless ::Gherkin::DIALECTS.key?(lang)
|
391
|
+
|
388
392
|
list_keywords_and_exit(lang)
|
389
393
|
end
|
390
394
|
|
@@ -403,6 +407,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
403
407
|
def add_tag(value)
|
404
408
|
raise("Found tags option '#{value}'. '~@tag' is no longer supported, use 'not @tag' instead.") if value.include?('~')
|
405
409
|
raise("Found tags option '#{value}'. '@tag1,@tag2' is no longer supported, use '@tag or @tag2' instead.") if value.include?(',')
|
410
|
+
|
406
411
|
@options[:tag_expressions] << value.gsub(/(@\w+)(:\d+)?/, '\1')
|
407
412
|
add_tag_limits(value)
|
408
413
|
end
|
@@ -415,6 +420,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
415
420
|
|
416
421
|
def add_tag_limit(tag_limits, tag_name, limit)
|
417
422
|
raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}" if tag_limits[tag_name] && tag_limits[tag_name] != limit
|
423
|
+
|
418
424
|
tag_limits[tag_name] = limit
|
419
425
|
end
|
420
426
|
|
@@ -75,11 +75,7 @@ Defined profiles in cucumber.yml:
|
|
75
75
|
def process_configuration_file_with_erb
|
76
76
|
require 'erb'
|
77
77
|
begin
|
78
|
-
@cucumber_erb =
|
79
|
-
ERB.new(IO.read(cucumber_file), trim_mode: '%').result(binding)
|
80
|
-
else
|
81
|
-
ERB.new(IO.read(cucumber_file), nil, '%').result(binding)
|
82
|
-
end
|
78
|
+
@cucumber_erb = ERB.new(IO.read(cucumber_file), trim_mode: '%').result(binding)
|
83
79
|
rescue StandardError
|
84
80
|
raise(YmlLoadError, "cucumber.yml was found, but could not be parsed with ERB. Please refer to cucumber's documentation on correct profile usage.\n#{$ERROR_INFO.inspect}")
|
85
81
|
end
|
@@ -176,12 +176,12 @@ module Cucumber
|
|
176
176
|
end
|
177
177
|
|
178
178
|
def support_to_load
|
179
|
-
support_files = all_files_to_load.select { |f| f =~
|
179
|
+
support_files = all_files_to_load.select { |f| f =~ /\/support\// }
|
180
180
|
|
181
181
|
# env_files are separated from other_files so we can ensure env files
|
182
182
|
# load first.
|
183
183
|
#
|
184
|
-
env_files = support_files.select { |f| f =~
|
184
|
+
env_files = support_files.select { |f| f =~ /\/support\/env\..*/ }
|
185
185
|
other_files = support_files - env_files
|
186
186
|
env_files.reverse + other_files.reverse
|
187
187
|
end
|
@@ -189,7 +189,7 @@ module Cucumber
|
|
189
189
|
def all_files_to_load
|
190
190
|
files = require_dirs.map do |path|
|
191
191
|
path = path.tr('\\', '/') # In case we're on windows. Globs don't work with backslashes.
|
192
|
-
path = path.gsub(/\/$/, '') # Strip trailing slash.
|
192
|
+
path = path.gsub(/\/$/, '') # Strip trailing slash.
|
193
193
|
File.directory?(path) ? Dir["#{path}/**/*"] : path
|
194
194
|
end.flatten.uniq
|
195
195
|
remove_excluded_files_from(files)
|
@@ -200,7 +200,7 @@ module Cucumber
|
|
200
200
|
end
|
201
201
|
|
202
202
|
def step_defs_to_load
|
203
|
-
all_files_to_load.reject { |f| f =~
|
203
|
+
all_files_to_load.reject { |f| f =~ /\/support\// }
|
204
204
|
end
|
205
205
|
|
206
206
|
def formatter_factories
|
@@ -283,6 +283,7 @@ module Cucumber
|
|
283
283
|
|
284
284
|
def with_default_features_path(paths)
|
285
285
|
return default_features_paths if paths.empty?
|
286
|
+
|
286
287
|
paths
|
287
288
|
end
|
288
289
|
|
data/lib/cucumber/constantize.rb
CHANGED
data/lib/cucumber/deprecate.rb
CHANGED
@@ -20,6 +20,7 @@ module Cucumber
|
|
20
20
|
class CliOption
|
21
21
|
def self.deprecate(stream, option, message, remove_after_version)
|
22
22
|
return if stream.nil?
|
23
|
+
|
23
24
|
stream.puts(
|
24
25
|
AnsiString.failure_message(
|
25
26
|
"\nWARNING: #{option} is deprecated" \
|
@@ -31,7 +32,7 @@ module Cucumber
|
|
31
32
|
|
32
33
|
module ForUsers
|
33
34
|
def self.call(message, method, remove_after_version)
|
34
|
-
|
35
|
+
$stderr.puts AnsiString.failure_message(
|
35
36
|
"\nWARNING: ##{method} is deprecated" \
|
36
37
|
" and will be removed after version #{remove_after_version}. #{message}.\n" \
|
37
38
|
"(Called from #{caller(3..3).first})"
|
data/lib/cucumber/errors.rb
CHANGED
@@ -6,8 +6,7 @@ module Cucumber
|
|
6
6
|
module Events
|
7
7
|
# Event fired when a TestStep is created from a PickleStep
|
8
8
|
class TestStepCreated < Core::Event.new(:test_step, :pickle_step)
|
9
|
-
attr_reader :test_step
|
10
|
-
attr_reader :pickle_step
|
9
|
+
attr_reader :test_step, :pickle_step
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
data/lib/cucumber/events.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
Dir[File.dirname(__FILE__)
|
3
|
+
Dir["#{File.dirname(__FILE__)}/events/*.rb"].map(&method(:require))
|
4
4
|
|
5
5
|
module Cucumber
|
6
6
|
# Events tell you what's happening while Cucumber runs your features.
|
@@ -11,7 +11,7 @@ module Cucumber
|
|
11
11
|
# To subscribe to an event, use {Cucumber::Configuration#on_event}
|
12
12
|
#
|
13
13
|
# @example
|
14
|
-
#
|
14
|
+
# InstallPlugin do |config|
|
15
15
|
# config.on_event :test_case_finished do |event|
|
16
16
|
# puts event.result
|
17
17
|
# end
|
data/lib/cucumber/file_specs.rb
CHANGED
@@ -5,7 +5,7 @@ require 'cucumber/core/test/location'
|
|
5
5
|
|
6
6
|
module Cucumber
|
7
7
|
class FileSpecs
|
8
|
-
FILE_COLON_LINE_PATTERN = /^([\w\W]*?)(?::([\d:]+))?$/
|
8
|
+
FILE_COLON_LINE_PATTERN = /^([\w\W]*?)(?::([\d:]+))?$/ # :nodoc:
|
9
9
|
|
10
10
|
def initialize(file_specs)
|
11
11
|
Cucumber.logger.debug("Features:\n")
|
@@ -32,6 +32,7 @@ module Cucumber
|
|
32
32
|
|
33
33
|
def locations
|
34
34
|
return [Core::Test::Location.new(@file)] if @lines.empty?
|
35
|
+
|
35
36
|
@lines.map { |line| Core::Test::Location.new(@file, line) }
|
36
37
|
end
|
37
38
|
end
|