cucumber 7.1.0 → 9.2.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 -27
- data/VERSION +1 -0
- data/lib/cucumber/cli/configuration.rb +4 -1
- data/lib/cucumber/cli/main.rb +5 -4
- data/lib/cucumber/cli/options.rb +73 -67
- data/lib/cucumber/cli/profile_loader.rb +6 -10
- data/lib/cucumber/cli/rerun_file.rb +1 -1
- data/lib/cucumber/configuration.rb +12 -6
- data/lib/cucumber/constantize.rb +1 -1
- data/lib/cucumber/deprecate.rb +6 -46
- data/lib/cucumber/errors.rb +3 -2
- data/lib/cucumber/events/envelope.rb +2 -0
- data/lib/cucumber/events/gherkin_source_parsed.rb +2 -0
- data/lib/cucumber/events/gherkin_source_read.rb +2 -0
- 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_case_finished.rb +2 -0
- data/lib/cucumber/events/test_case_started.rb +2 -0
- data/lib/cucumber/events/test_run_finished.rb +2 -1
- data/lib/cucumber/events/test_step_created.rb +1 -2
- data/lib/cucumber/events/test_step_finished.rb +2 -0
- data/lib/cucumber/events/test_step_started.rb +2 -0
- data/lib/cucumber/events/undefined_parameter_type.rb +3 -2
- data/lib/cucumber/events.rb +1 -1
- data/lib/cucumber/file_specs.rb +2 -1
- data/lib/cucumber/filters/activate_steps.rb +1 -0
- data/lib/cucumber/filters/retry.rb +20 -1
- 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 +70 -78
- data/lib/cucumber/formatter/ast_lookup.rb +16 -8
- data/lib/cucumber/formatter/backtrace_filter.rb +2 -1
- data/lib/cucumber/formatter/console.rb +26 -16
- data/lib/cucumber/formatter/console_counts.rb +3 -1
- data/lib/cucumber/formatter/console_issues.rb +10 -3
- data/lib/cucumber/formatter/curl_option_parser.rb +49 -0
- data/lib/cucumber/formatter/duration_extractor.rb +1 -0
- data/lib/cucumber/formatter/errors.rb +3 -0
- data/lib/cucumber/formatter/fail_fast.rb +1 -1
- data/lib/cucumber/formatter/fanout.rb +1 -1
- data/lib/cucumber/formatter/html.rb +2 -0
- data/lib/cucumber/formatter/http_io.rb +10 -137
- data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
- data/lib/cucumber/formatter/io.rb +5 -3
- data/lib/cucumber/formatter/io_http_buffer.rb +88 -0
- data/lib/cucumber/formatter/json.rb +10 -12
- data/lib/cucumber/formatter/junit.rb +10 -7
- data/lib/cucumber/formatter/message_builder.rb +24 -8
- data/lib/cucumber/formatter/pretty.rb +24 -10
- data/lib/cucumber/formatter/progress.rb +1 -0
- data/lib/cucumber/formatter/publish_banner_printer.rb +0 -2
- data/lib/cucumber/formatter/query/hook_by_test_step.rb +3 -0
- data/lib/cucumber/formatter/query/pickle_by_test.rb +2 -0
- data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +2 -0
- data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +2 -0
- data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +4 -0
- data/lib/cucumber/formatter/rerun.rb +5 -3
- data/lib/cucumber/formatter/summary.rb +1 -0
- data/lib/cucumber/formatter/unicode.rb +7 -7
- data/lib/cucumber/formatter/url_reporter.rb +3 -1
- 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 +25 -27
- data/lib/cucumber/glue/dsl.rb +20 -25
- data/lib/cucumber/glue/hook.rb +6 -3
- data/lib/cucumber/glue/invoke_in_world.rb +5 -5
- data/lib/cucumber/glue/proto_world.rb +30 -34
- data/lib/cucumber/glue/registry_and_more.rb +15 -25
- data/lib/cucumber/glue/snippet.rb +4 -2
- data/lib/cucumber/glue/step_definition.rb +6 -3
- data/lib/cucumber/glue/world_factory.rb +2 -0
- data/lib/cucumber/hooks.rb +1 -0
- data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +4 -1
- data/lib/cucumber/multiline_argument/data_table.rb +68 -80
- data/lib/cucumber/platform.rb +11 -16
- data/lib/cucumber/rake/task.rb +22 -15
- data/lib/cucumber/rspec/disable_option_parser.rb +6 -3
- data/lib/cucumber/running_test_case.rb +2 -1
- data/lib/cucumber/runtime/for_programming_languages.rb +1 -2
- data/lib/cucumber/runtime/meta_message_builder.rb +108 -0
- data/lib/cucumber/runtime/support_code.rb +3 -0
- data/lib/cucumber/runtime/user_interface.rb +7 -6
- data/lib/cucumber/runtime.rb +22 -38
- data/lib/cucumber/step_match.rb +6 -4
- data/lib/cucumber/step_match_search.rb +3 -2
- data/lib/cucumber/term/ansicolor.rb +74 -50
- data/lib/cucumber/term/banner.rb +3 -0
- data/lib/cucumber.rb +2 -1
- data/lib/simplecov_setup.rb +1 -1
- metadata +95 -244
- data/CHANGELOG.md +0 -3131
- data/CONTRIBUTING.md +0 -250
- data/lib/autotest/cucumber.rb +0 -8
- data/lib/autotest/cucumber_mixin.rb +0 -130
- data/lib/autotest/cucumber_rails.rb +0 -8
- data/lib/autotest/cucumber_rails_rspec.rb +0 -8
- data/lib/autotest/cucumber_rails_rspec2.rb +0 -8
- data/lib/autotest/cucumber_rspec.rb +0 -8
- data/lib/autotest/cucumber_rspec2.rb +0 -8
- data/lib/autotest/discover.rb +0 -13
- data/lib/cucumber/version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f6b3938bfcfa22aba558e5ea44825ed2ee19e9c7d26c0a5613f7998095d5c287
|
4
|
+
data.tar.gz: edc19d118e96175085722756b873b48c2ec319663edeedd81de027a48ac7d66c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1338b46610ebd6fff711400c0160294f451e3c98558ca155712d07040a06f9a55fcb99c6e9cd00e5df248a415928b2a7c70da76a7badcc461b832ec464b66a8
|
7
|
+
data.tar.gz: b1c00b91c1055daf161482ba19b4cfa60089140af3212f9a1d71ef9a692d4dabd43fdb5fa3fa0bfcbcce018053f0ebc5460f1449bfaa32fa6afb0f532156c9d1
|
data/README.md
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
<
|
2
|
-
<img src="./.github/img/cucumber-open-logo.png" alt="Cucumber Open - Supported by Smartbear" width="428" />
|
3
|
-
</p>
|
1
|
+
<img src="docs/img/cucumber-open-logo.png" alt="Cucumber Open - Supported by Smartbear" width="428" />
|
4
2
|
|
5
3
|
# Cucumber
|
6
4
|
|
5
|
+
[](https://vshymanskyy.github.io/StandWithUkraine)
|
7
6
|
[](https://opencollective.com/cucumber)
|
8
7
|
[](https://opencollective.com/cucumber)
|
9
|
-
[](https://oselvar.com/github/cucumber/oselvar-github-metrics/main/cucumber/cucumber-ruby)
|
11
|
-
[](https://github.com/cucumber/cucumber-ruby/actions/workflows/cucumber-ruby.yml)
|
8
|
+
[](https://github.com/cucumber/cucumber-ruby/actions/workflows/test.yaml)
|
12
9
|
[](https://codeclimate.com/github/cucumber/cucumber-ruby)
|
13
10
|
[](https://coveralls.io/r/cucumber/cucumber-ruby?branch=main)
|
14
11
|
|
@@ -17,9 +14,7 @@ written in plain language, they can be read by anyone on your team. Because they
|
|
17
14
|
read by anyone, you can use them to help improve communication, collaboration and trust on
|
18
15
|
your team.
|
19
16
|
|
20
|
-
<
|
21
|
-
<img src="./.github/img/gherkin-example.png" alt="Cucumber Gherkin Example" width="728" />
|
22
|
-
</p>
|
17
|
+
<img src="docs/img/gherkin-example.png" alt="Cucumber Gherkin Example" width="728" />
|
23
18
|
|
24
19
|
This is the Ruby implementation of Cucumber. Cucumber is also available for [JavaScript](https://github.com/cucumber/cucumber-js),
|
25
20
|
[Java](https://github.com/cucumber/cucumber-jvm), and a lot of other languages. You can find a list of implementations here: https://cucumber.io/docs/installation/.
|
@@ -50,21 +45,16 @@ Later in this document, bundler is considered being used so all commands are usi
|
|
50
45
|
|
51
46
|
### Supported platforms
|
52
47
|
|
48
|
+
- Ruby 3.2
|
49
|
+
- Ruby 3.1
|
53
50
|
- Ruby 3.0
|
54
51
|
- Ruby 2.7
|
55
|
-
-
|
56
|
-
-
|
57
|
-
- Ruby 2.4
|
58
|
-
- Ruby 2.3
|
59
|
-
- JRuby 9.2 (with [some limitations](https://github.com/cucumber/cucumber-ruby/blob/main/docs/jruby-limitations.md))
|
60
|
-
|
61
|
-
JRuby 9.3 is not supported yet due to a known issue. More info can
|
62
|
-
be found in the [PR#1571](https://github.com/cucumber/cucumber-ruby/pull/1571).
|
52
|
+
- TruffleRuby 22.0.0+
|
53
|
+
- JRuby 9.4+ (with [some limitations](https://github.com/cucumber/cucumber-ruby/blob/main/docs/jruby-limitations.md))
|
63
54
|
|
64
55
|
### Ruby on Rails
|
65
56
|
|
66
|
-
Using Ruby on Rails? You can use [cucumber-rails](https://github.com/cucumber/cucumber-rails)
|
67
|
-
to bring Cucumber into your Rails project.
|
57
|
+
Using Ruby on Rails? You can use [cucumber-rails](https://github.com/cucumber/cucumber-rails) to bring Cucumber into your Rails project.
|
68
58
|
|
69
59
|
## Usage
|
70
60
|
|
@@ -111,19 +101,20 @@ And a file named `steps.rb` in `features/step_definitions` with:
|
|
111
101
|
```ruby
|
112
102
|
# features/step_definitions/steps.rb
|
113
103
|
|
114
|
-
Given(
|
104
|
+
Given('this will pass') do
|
115
105
|
@this_will_pass = true
|
116
106
|
end
|
117
107
|
|
118
|
-
Given(
|
108
|
+
Given('this will fail') do
|
119
109
|
@this_will_pass = false
|
120
110
|
end
|
121
111
|
|
122
|
-
When(
|
112
|
+
When('I do an action') do
|
113
|
+
:no_op
|
123
114
|
end
|
124
115
|
|
125
116
|
Then("some results should be there") do
|
126
|
-
expect(@this_will_pass)
|
117
|
+
expect(@this_will_pass).to be true
|
127
118
|
end
|
128
119
|
```
|
129
120
|
|
@@ -137,9 +128,9 @@ To execute a single feature file:
|
|
137
128
|
|
138
129
|
To execute a single example, indicates the line of the name of the example:
|
139
130
|
|
140
|
-
$ bundle exec cucumber features/rule.feature:
|
131
|
+
$ bundle exec cucumber features/rule.feature:5
|
141
132
|
|
142
|
-
To summarize the results on the standard output, and
|
133
|
+
To summarize the results on the standard output, and generate a HTML report on disk:
|
143
134
|
|
144
135
|
$ bundle exec cucumber --format summary --format html --out report.html
|
145
136
|
|
@@ -147,8 +138,7 @@ For more command line options
|
|
147
138
|
|
148
139
|
$ bundle exec cucumber --help
|
149
140
|
|
150
|
-
You can also find documentation on the command line possibilities in
|
151
|
-
[features/docs/cli](features/docs/cli).
|
141
|
+
You can also find documentation on the command line possibilities in [features/docs/cli](features/docs/cli).
|
152
142
|
|
153
143
|
## Documentation and support
|
154
144
|
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
9.2.1
|
@@ -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)
|
@@ -49,7 +49,7 @@ module Cucumber
|
|
49
49
|
rescue Errno::EACCES, Errno::ENOENT => e
|
50
50
|
@err.puts("#{e.message} (#{e.class})")
|
51
51
|
exit_unable_to_finish
|
52
|
-
rescue Exception => e
|
52
|
+
rescue Exception => e
|
53
53
|
@err.puts("#{e.message} (#{e.class})")
|
54
54
|
@err.puts(e.backtrace.join("\n"))
|
55
55
|
exit_unable_to_finish
|
@@ -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
@@ -12,26 +12,26 @@ module Cucumber
|
|
12
12
|
CUCUMBER_PUBLISH_URL = ENV['CUCUMBER_PUBLISH_URL'] || 'https://messages.cucumber.io/api/reports -X GET'
|
13
13
|
INDENT = ' ' * 53
|
14
14
|
BUILTIN_FORMATS = {
|
15
|
-
'pretty'
|
16
|
-
'progress'
|
17
|
-
'rerun'
|
18
|
-
'usage'
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
'stepdefs'
|
24
|
-
|
25
|
-
'junit'
|
26
|
-
|
27
|
-
'json'
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
'message'
|
33
|
-
'html'
|
34
|
-
'summary'
|
15
|
+
'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
|
16
|
+
'progress' => ['Cucumber::Formatter::Progress', 'Prints one character per scenario.'],
|
17
|
+
'rerun' => ['Cucumber::Formatter::Rerun', 'Prints failing files with line numbers.'],
|
18
|
+
'usage' => ['Cucumber::Formatter::Usage', "Prints where step definitions are used.\n" \
|
19
|
+
"#{INDENT}The slowest step definitions (with duration) are\n" \
|
20
|
+
"#{INDENT}listed first. If --dry-run is used the duration\n" \
|
21
|
+
"#{INDENT}is not shown, and step definitions are sorted by\n" \
|
22
|
+
"#{INDENT}filename instead."],
|
23
|
+
'stepdefs' => ['Cucumber::Formatter::Stepdefs', "Prints All step definitions with their locations. Same as\n" \
|
24
|
+
"#{INDENT}the usage formatter, except that steps are not printed."],
|
25
|
+
'junit' => ['Cucumber::Formatter::Junit', "Generates a report similar to Ant+JUnit. Use\n" \
|
26
|
+
"#{INDENT}junit,fileattribute=true to include a file attribute."],
|
27
|
+
'json' => ['Cucumber::Formatter::Json', "Prints the feature as JSON.\n" \
|
28
|
+
"#{INDENT}The JSON format is in maintenance mode.\n" \
|
29
|
+
"#{INDENT}Please consider using the message formatter\n"\
|
30
|
+
"#{INDENT}with the standalone json-formatter\n" \
|
31
|
+
"#{INDENT}(https://github.com/cucumber/cucumber/tree/master/json-formatter)."],
|
32
|
+
'message' => ['Cucumber::Formatter::Message', 'Prints each message in NDJSON form, which can then be consumed by other tools.'],
|
33
|
+
'html' => ['Cucumber::Formatter::HTML', 'Outputs HTML report'],
|
34
|
+
'summary' => ['Cucumber::Formatter::Summary', 'Summary output of feature and scenarios']
|
35
35
|
}.freeze
|
36
36
|
max = BUILTIN_FORMATS.keys.map(&:length).max
|
37
37
|
FORMAT_HELP_MSG = [
|
@@ -50,26 +50,27 @@ module Cucumber
|
|
50
50
|
FORMAT_HELP = (BUILTIN_FORMATS.keys.sort.map do |key|
|
51
51
|
" #{key}#{' ' * (max - key.length)} : #{BUILTIN_FORMATS[key][1]}"
|
52
52
|
end) + FORMAT_HELP_MSG
|
53
|
-
PROFILE_SHORT_FLAG = '-p'
|
54
|
-
NO_PROFILE_SHORT_FLAG = '-P'
|
55
|
-
PROFILE_LONG_FLAG = '--profile'
|
56
|
-
NO_PROFILE_LONG_FLAG = '--no-profile'
|
57
|
-
FAIL_FAST_FLAG = '--fail-fast'
|
58
|
-
RETRY_FLAG = '--retry'
|
53
|
+
PROFILE_SHORT_FLAG = '-p'
|
54
|
+
NO_PROFILE_SHORT_FLAG = '-P'
|
55
|
+
PROFILE_LONG_FLAG = '--profile'
|
56
|
+
NO_PROFILE_LONG_FLAG = '--no-profile'
|
57
|
+
FAIL_FAST_FLAG = '--fail-fast'
|
58
|
+
RETRY_FLAG = '--retry'
|
59
|
+
RETRY_TOTAL_FLAG = '--retry-total'
|
59
60
|
OPTIONS_WITH_ARGS = [
|
60
61
|
'-r', '--require', '--i18n-keywords', '-f', '--format', '-o',
|
61
62
|
'--out', '-t', '--tags', '-n', '--name', '-e', '--exclude',
|
62
|
-
PROFILE_SHORT_FLAG, PROFILE_LONG_FLAG, RETRY_FLAG,
|
63
|
-
'--lines', '--port', '-I', '--snippet-type'
|
63
|
+
PROFILE_SHORT_FLAG, PROFILE_LONG_FLAG, RETRY_FLAG, RETRY_TOTAL_FLAG,
|
64
|
+
'-l', '--lines', '--port', '-I', '--snippet-type'
|
64
65
|
].freeze
|
65
66
|
ORDER_TYPES = %w[defined random].freeze
|
66
|
-
TAG_LIMIT_MATCHER = /(?<tag_name
|
67
|
+
TAG_LIMIT_MATCHER = /(?<tag_name>@\w+):(?<limit>\d+)/x.freeze
|
67
68
|
|
68
69
|
def self.parse(args, out_stream, error_stream, options = {})
|
69
70
|
new(out_stream, error_stream, options).parse!(args)
|
70
71
|
end
|
71
72
|
|
72
|
-
def initialize(out_stream =
|
73
|
+
def initialize(out_stream = $stdout, error_stream = $stderr, options = {})
|
73
74
|
@out_stream = out_stream
|
74
75
|
@error_stream = error_stream
|
75
76
|
|
@@ -91,13 +92,13 @@ module Cucumber
|
|
91
92
|
@options[key] = value
|
92
93
|
end
|
93
94
|
|
94
|
-
def parse!(args)
|
95
|
+
def parse!(args)
|
95
96
|
@args = args
|
96
97
|
@expanded_args = @args.dup
|
97
98
|
|
98
99
|
@args.extend(::OptionParser::Arguable)
|
99
100
|
|
100
|
-
@args.options do |opts|
|
101
|
+
@args.options do |opts|
|
101
102
|
opts.banner = banner
|
102
103
|
opts.on('--publish', 'Publish a report to https://reports.cucumber.io') do
|
103
104
|
set_option :publish_enabled, true
|
@@ -108,16 +109,17 @@ module Cucumber
|
|
108
109
|
opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) } if Cucumber::JRUBY
|
109
110
|
|
110
111
|
opts.on("#{RETRY_FLAG} ATTEMPTS", *retry_msg) { |v| set_option :retry, v.to_i }
|
112
|
+
opts.on("#{RETRY_TOTAL_FLAG} TESTS", *retry_total_msg) { |v| set_option :retry_total, v.to_i }
|
111
113
|
opts.on('--i18n-languages', *i18n_languages_msg) { list_languages_and_exit }
|
112
114
|
opts.on('--i18n-keywords LANG', *i18n_keywords_msg) { |lang| language lang }
|
113
115
|
opts.on(FAIL_FAST_FLAG, 'Exit immediately following the first failing scenario') { set_option :fail_fast }
|
114
116
|
opts.on('-f FORMAT', '--format FORMAT', *format_msg, *FORMAT_HELP) do |v|
|
115
117
|
add_option :formats, [*parse_formats(v), @out_stream]
|
116
118
|
end
|
117
|
-
opts.on('--init', *init_msg) {
|
119
|
+
opts.on('--init', *init_msg) { initialize_project }
|
118
120
|
opts.on('-o', '--out [FILE|DIR|URL]', *out_msg) { |v| out_stream v }
|
119
|
-
opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag
|
120
|
-
opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option
|
121
|
+
opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag(v) }
|
122
|
+
opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option(:name_regexps, /#{v}/) }
|
121
123
|
opts.on('-e', '--exclude PATTERN', *exclude_msg) { |v| add_option :excludes, Regexp.new(v) }
|
122
124
|
opts.on(PROFILE_SHORT_FLAG, "#{PROFILE_LONG_FLAG} PROFILE", *profile_short_flag_msg) { |v| add_profile v }
|
123
125
|
opts.on(NO_PROFILE_SHORT_FLAG, NO_PROFILE_LONG_FLAG, *no_profile_short_flag_msg) { |_v| disable_profile_loading }
|
@@ -141,11 +143,11 @@ module Cucumber
|
|
141
143
|
opts.on('-x', '--expand', 'Expand Scenario Outline Tables in output.') { set_option :expand }
|
142
144
|
|
143
145
|
opts.on('--order TYPE[:SEED]', 'Run examples in the specified order. Available types:',
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
Specify SEED to reproduce the shuffling from a previous run.
|
148
|
-
|
146
|
+
*<<~TEXT.split("\n")) do |order|
|
147
|
+
[defined] Run scenarios in the order they were defined (default).
|
148
|
+
[random] Shuffle scenarios before running.
|
149
|
+
Specify SEED to reproduce the shuffling from a previous run.
|
150
|
+
e.g. --order random:5738
|
149
151
|
TEXT
|
150
152
|
@options[:order], @options[:seed] = *order.split(':')
|
151
153
|
raise "'#{@options[:order]}' is not a recognised order type. Please use one of #{ORDER_TYPES.join(', ')}." unless ORDER_TYPES.include?(@options[:order])
|
@@ -180,6 +182,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
180
182
|
def check_formatter_stream_conflicts
|
181
183
|
streams = @options[:formats].uniq.map { |(_, _, stream)| stream }
|
182
184
|
return if streams == streams.uniq
|
185
|
+
|
183
186
|
raise 'All but one formatter must use --out, only one can print to each stream (or STDOUT)'
|
184
187
|
end
|
185
188
|
|
@@ -203,6 +206,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
203
206
|
|
204
207
|
def truthy_string?(str)
|
205
208
|
return false if str.nil?
|
209
|
+
|
206
210
|
str !~ /^(false|no|0)$/i
|
207
211
|
end
|
208
212
|
|
@@ -269,6 +273,13 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
269
273
|
['Specify the number of times to retry failing tests (default: 0)']
|
270
274
|
end
|
271
275
|
|
276
|
+
def retry_total_msg
|
277
|
+
[
|
278
|
+
'The total number of failing test after which retrying of tests is suspended.',
|
279
|
+
'Example: --retry-total 10 -> Will stop retrying tests after 10 failing tests.'
|
280
|
+
]
|
281
|
+
end
|
282
|
+
|
272
283
|
def name_msg
|
273
284
|
[
|
274
285
|
'Only execute the feature elements which match part of the given name.',
|
@@ -284,15 +295,15 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
284
295
|
]
|
285
296
|
end
|
286
297
|
|
287
|
-
def parse_formats(
|
288
|
-
formatter, *formatter_options =
|
289
|
-
options_hash = Hash[formatter_options.map { |
|
298
|
+
def parse_formats(value)
|
299
|
+
formatter, *formatter_options = value.split(',')
|
300
|
+
options_hash = Hash[formatter_options.map { |string| string.split('=') }]
|
290
301
|
[formatter, options_hash]
|
291
302
|
end
|
292
303
|
|
293
|
-
def out_stream(
|
304
|
+
def out_stream(value)
|
294
305
|
@options[:formats] << ['pretty', {}, nil] if @options[:formats].empty?
|
295
|
-
@options[:formats][-1][2] =
|
306
|
+
@options[:formats][-1][2] = value
|
296
307
|
end
|
297
308
|
|
298
309
|
def tags_msg
|
@@ -364,11 +375,12 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
364
375
|
].join("\n")
|
365
376
|
end
|
366
377
|
|
367
|
-
def require_files(
|
368
|
-
@options[:require] <<
|
369
|
-
return unless Cucumber::JRUBY && File.directory?(
|
378
|
+
def require_files(filenames)
|
379
|
+
@options[:require] << filenames
|
380
|
+
return unless Cucumber::JRUBY && File.directory?(filenames)
|
381
|
+
|
370
382
|
require 'java'
|
371
|
-
$CLASSPATH <<
|
383
|
+
$CLASSPATH << filenames
|
372
384
|
end
|
373
385
|
|
374
386
|
def require_jars(jars)
|
@@ -385,6 +397,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
385
397
|
require 'gherkin/dialect'
|
386
398
|
|
387
399
|
return indicate_invalid_language_and_exit(lang) unless ::Gherkin::DIALECTS.key?(lang)
|
400
|
+
|
388
401
|
list_keywords_and_exit(lang)
|
389
402
|
end
|
390
403
|
|
@@ -403,6 +416,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
403
416
|
def add_tag(value)
|
404
417
|
raise("Found tags option '#{value}'. '~@tag' is no longer supported, use 'not @tag' instead.") if value.include?('~')
|
405
418
|
raise("Found tags option '#{value}'. '@tag1,@tag2' is no longer supported, use '@tag or @tag2' instead.") if value.include?(',')
|
419
|
+
|
406
420
|
@options[:tag_expressions] << value.gsub(/(@\w+)(:\d+)?/, '\1')
|
407
421
|
add_tag_limits(value)
|
408
422
|
end
|
@@ -415,6 +429,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
415
429
|
|
416
430
|
def add_tag_limit(tag_limits, tag_name, limit)
|
417
431
|
raise "Inconsistent tag limits for #{tag_name}: #{tag_limits[tag_name]} and #{limit}" if tag_limits[tag_name] && tag_limits[tag_name] != limit
|
432
|
+
|
418
433
|
tag_limits[tag_name] = limit
|
419
434
|
end
|
420
435
|
|
@@ -426,8 +441,8 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
426
441
|
ProjectInitializer.new.run && Kernel.exit(0)
|
427
442
|
end
|
428
443
|
|
429
|
-
def add_profile(
|
430
|
-
@profiles <<
|
444
|
+
def add_profile(profile)
|
445
|
+
@profiles << profile
|
431
446
|
end
|
432
447
|
|
433
448
|
def set_option(option, value = nil)
|
@@ -440,7 +455,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
440
455
|
end
|
441
456
|
|
442
457
|
def exit_ok(text)
|
443
|
-
@out_stream.puts
|
458
|
+
@out_stream.puts(text)
|
444
459
|
Kernel.exit(0)
|
445
460
|
end
|
446
461
|
|
@@ -468,22 +483,11 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
468
483
|
end
|
469
484
|
end
|
470
485
|
|
471
|
-
def disable_profile_loading?
|
472
|
-
@disable_profile_loading
|
473
|
-
end
|
474
|
-
|
475
486
|
def merge_profiles
|
476
|
-
if @disable_profile_loading
|
477
|
-
@out_stream.puts 'Disabling profiles...'
|
478
|
-
return
|
479
|
-
end
|
487
|
+
return @out_stream.puts 'Disabling profiles...' if @disable_profile_loading
|
480
488
|
|
481
489
|
@profiles << @default_profile if default_profile_should_be_used?
|
482
|
-
|
483
|
-
@profiles.each do |profile|
|
484
|
-
merge_with_profile(profile)
|
485
|
-
end
|
486
|
-
|
490
|
+
@profiles.each { |profile| merge_with_profile(profile) }
|
487
491
|
@options[:profiles] = @profiles
|
488
492
|
end
|
489
493
|
|
@@ -507,7 +511,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
507
511
|
@profile_loader ||= ProfileLoader.new
|
508
512
|
end
|
509
513
|
|
510
|
-
def reverse_merge(other_options)
|
514
|
+
def reverse_merge(other_options)
|
511
515
|
@options = other_options.options.merge(@options)
|
512
516
|
@options[:require] += other_options[:require]
|
513
517
|
@options[:excludes] += other_options[:excludes]
|
@@ -537,6 +541,7 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
537
541
|
end
|
538
542
|
|
539
543
|
@options[:retry] = other_options[:retry] if @options[:retry].zero?
|
544
|
+
@options[:retry_total] = other_options[:retry_total] if @options[:retry_total].infinite?
|
540
545
|
|
541
546
|
self
|
542
547
|
end
|
@@ -610,7 +615,8 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
610
615
|
snippets: true,
|
611
616
|
source: true,
|
612
617
|
duration: true,
|
613
|
-
retry: 0
|
618
|
+
retry: 0,
|
619
|
+
retry_total: Float::INFINITY
|
614
620
|
}
|
615
621
|
end
|
616
622
|
end
|
@@ -11,11 +11,11 @@ module Cucumber
|
|
11
11
|
|
12
12
|
def args_from(profile)
|
13
13
|
unless cucumber_yml.key?(profile)
|
14
|
-
raise(ProfileNotFound,
|
15
|
-
Could not find profile: '#{profile}'
|
14
|
+
raise(ProfileNotFound, <<~END_OF_ERROR)
|
15
|
+
Could not find profile: '#{profile}'
|
16
16
|
|
17
|
-
Defined profiles in cucumber.yml:
|
18
|
-
|
17
|
+
Defined profiles in cucumber.yml:
|
18
|
+
* #{cucumber_yml.keys.sort.join("\n * ")}
|
19
19
|
END_OF_ERROR
|
20
20
|
end
|
21
21
|
|
@@ -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
|
@@ -88,7 +84,7 @@ Defined profiles in cucumber.yml:
|
|
88
84
|
def load_configuration
|
89
85
|
require 'yaml'
|
90
86
|
begin
|
91
|
-
@cucumber_yml = YAML.load(@cucumber_erb)
|
87
|
+
@cucumber_yml = YAML.load(@cucumber_erb)
|
92
88
|
rescue StandardError
|
93
89
|
raise(YmlLoadError, "cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
|
94
90
|
end
|
@@ -78,6 +78,10 @@ module Cucumber
|
|
78
78
|
@options[:retry]
|
79
79
|
end
|
80
80
|
|
81
|
+
def retry_total_tests
|
82
|
+
@options[:retry_total]
|
83
|
+
end
|
84
|
+
|
81
85
|
def guess?
|
82
86
|
@options[:guess]
|
83
87
|
end
|
@@ -176,12 +180,12 @@ module Cucumber
|
|
176
180
|
end
|
177
181
|
|
178
182
|
def support_to_load
|
179
|
-
support_files = all_files_to_load.select { |f| f =~
|
183
|
+
support_files = all_files_to_load.select { |f| f =~ /\/support\// }
|
180
184
|
|
181
185
|
# env_files are separated from other_files so we can ensure env files
|
182
186
|
# load first.
|
183
187
|
#
|
184
|
-
env_files = support_files.select { |f| f =~
|
188
|
+
env_files = support_files.select { |f| f =~ /\/support\/env\..*/ }
|
185
189
|
other_files = support_files - env_files
|
186
190
|
env_files.reverse + other_files.reverse
|
187
191
|
end
|
@@ -189,7 +193,7 @@ module Cucumber
|
|
189
193
|
def all_files_to_load
|
190
194
|
files = require_dirs.map do |path|
|
191
195
|
path = path.tr('\\', '/') # In case we're on windows. Globs don't work with backslashes.
|
192
|
-
path = path.gsub(/\/$/, '') # Strip trailing slash.
|
196
|
+
path = path.gsub(/\/$/, '') # Strip trailing slash.
|
193
197
|
File.directory?(path) ? Dir["#{path}/**/*"] : path
|
194
198
|
end.flatten.uniq
|
195
199
|
remove_excluded_files_from(files)
|
@@ -200,7 +204,7 @@ module Cucumber
|
|
200
204
|
end
|
201
205
|
|
202
206
|
def step_defs_to_load
|
203
|
-
all_files_to_load.reject { |f| f =~
|
207
|
+
all_files_to_load.reject { |f| f =~ /\/support\// }
|
204
208
|
end
|
205
209
|
|
206
210
|
def formatter_factories
|
@@ -209,7 +213,7 @@ module Cucumber
|
|
209
213
|
yield factory,
|
210
214
|
formatter_options,
|
211
215
|
path_or_io
|
212
|
-
rescue Exception => e
|
216
|
+
rescue Exception => e
|
213
217
|
raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
|
214
218
|
end
|
215
219
|
end
|
@@ -273,7 +277,8 @@ module Cucumber
|
|
273
277
|
snippets: true,
|
274
278
|
source: true,
|
275
279
|
duration: true,
|
276
|
-
event_bus: Cucumber::Events.make_event_bus
|
280
|
+
event_bus: Cucumber::Events.make_event_bus,
|
281
|
+
retry_total: Float::INFINITY
|
277
282
|
}
|
278
283
|
end
|
279
284
|
|
@@ -283,6 +288,7 @@ module Cucumber
|
|
283
288
|
|
284
289
|
def with_default_features_path(paths)
|
285
290
|
return default_features_paths if paths.empty?
|
291
|
+
|
286
292
|
paths
|
287
293
|
end
|
288
294
|
|