cucumber 4.0.1 → 5.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c37c07474eae1f9984186ac8f920b7440a5865fb8581d56fe9299d794d6b6c2
4
- data.tar.gz: 234b2ccdba26251b7017dab7f73eceb310057ab9e68c64686aee94d8e33fc818
3
+ metadata.gz: 598a3fa7056ad50b328b396a020ed24474ff407d94b32a5114802172c3c843cf
4
+ data.tar.gz: d878d4b8b001459334db9c986a8baf8e81eb9fce3df3e40940f7ebaca6623e11
5
5
  SHA512:
6
- metadata.gz: 7aefc0d27a3f54413f8c2f0e4810c32f96374925af78710caca6488617b699c190682eaf7da78fe77fc2060dae77d6ab15871d12025b3520dbed7ce8eb7232a6
7
- data.tar.gz: 35a3d9a9ed8b5cb1e958a1c14e5bf4050743357382e2a9682645f90e0866c6285f23849217c15bdd71915f122307aabe15dc5dee2c6028abf195289583da522e
6
+ metadata.gz: b68a1ed62878cb122ed3acb8cae0eee8c582392e7e8ed1c5ef4bf5fd10e5785a7c87da57f1fc447c035e3015e7d8f09e70142c2260706715d46b67d7f7603cfc
7
+ data.tar.gz: a3e74329a7f23150cbaaae08c17fc339e86065447fc861ef7826725c98bf447e5e6144143cc4954d2ceb2835f0a41edd09d3ec44929d70101235084a065d9d9e
@@ -10,6 +10,102 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
10
10
 
11
11
  ----
12
12
 
13
+ ## [In GIT](https://github.com/cucumber/cucumber-ruby/compare/v5.1.2...master)
14
+
15
+ ### Added
16
+
17
+ ### Changed
18
+
19
+ ### Removed
20
+
21
+ ### Deprecated
22
+
23
+ ### Fixed
24
+
25
+ ### Security fixes
26
+
27
+ ## [5.1.2](https://github.com/cucumber/cucumber-ruby/compare/v5.1.1...v5.1.2)
28
+
29
+ ### Fixed
30
+
31
+ * Do not send headers after following redirection [#1475](https://github.com/cucumber/cucumber-ruby/pull/1475)
32
+
33
+ ## [5.1.1](https://github.com/cucumber/cucumber-ruby/compare/v5.1.0...v5.1.1)
34
+
35
+ ### Security fixes
36
+
37
+ * Update `cucumber-create-meta` to 2.0.2
38
+
39
+ ## [5.1.0](https://github.com/cucumber/cucumber-ruby/compare/v5.0.0...5.1.0)
40
+
41
+ ### Added
42
+
43
+ * `-X GET` in an `--out` URL will now issue a `GET` request *without* a body. If the response is `202 Accepted` *and*
44
+ the `Location` header is present, a new `PUT` request will be sent *with* the body.
45
+
46
+ The main reason for this added behaviour is to allow request bodies larger than 6Mb to be sent while using `--publish`.
47
+ This also improves performance since the request body is only sent once (previously it would be sent twice).
48
+
49
+ ### Changed
50
+
51
+ * Set banner border color to green when publishing reports
52
+ * Postpone removal of `--format=json`, `embed` and `puts` to version 6.0.0 in deprecation messages
53
+
54
+ ### Fixed
55
+
56
+ * Display banner on stderr when publishing reports [#1462](https://github.com/cucumber/cucumber-ruby/issues/1462)
57
+
58
+ ## [5.0.0](https://github.com/cucumber/cucumber-ruby/compare/v4.1.0...5.0.0)
59
+
60
+ ### Added
61
+
62
+ * `--publish` automatically publishes reports to [reports.cucumber.io](https://reports.cucumber.io)
63
+ * `--publish-quiet` does not print information banner about [reports.cucumber.io](https://reports.cucumber.io)
64
+
65
+ ### Changed
66
+
67
+ * `-q, --quiet` will also imply `--publish-quiet` in addition to `--no-snippets --no-source --no-duration`
68
+
69
+ ### Removed
70
+
71
+ * Dropped support for Ruby [2.3](https://www.ruby-lang.org/en/news/2019/03/31/support-of-ruby-2-3-has-ended/)
72
+ and [2.4](https://www.ruby-lang.org/en/news/2020/04/05/support-of-ruby-2-4-has-ended/)
73
+
74
+ ### Fixed
75
+
76
+ * Update code to be compatible with `diff-lcs` versions 1.3 and 1.4
77
+ * Defer registration of `at_exit` hook that flushes and closes formatter streams
78
+ ([#1458](https://github.com/cucumber/cucumber-ruby/pull/1458))
79
+ * Updated gems (see git diff for details)
80
+ * `cucumber-expressions`
81
+ * `cucumber-gherkin`
82
+ * `cucumber-create-meta`
83
+ * `cucumber-messages`
84
+ * Fix issue with timestamp nanos [#1438](https://github.com/cucumber/cucumber-ruby/issues/1438)
85
+ * `cucumber-html-formatter`
86
+ * Add filtering capabilities [#1444](https://github.com/cucumber/cucumber-ruby/issues/1444)
87
+ * Fix Interceptor that was raising exception when calling `puts` on the wrapped stream ([#1445](https://github.com/cucumber/cucumber-ruby/issues/1445))
88
+
89
+ ## [4.1.0](https://github.com/cucumber/cucumber-ruby/compare/v4.0.1...v4.1.0)
90
+
91
+ ### Changed
92
+
93
+ * Use [`cucumber-create-meta`](https://rubygems.org/gems/cucumber-create-meta) to produce the `Meta` message before the run.
94
+
95
+ * Updated gems:
96
+ * `cucumber-wire` ~> 3.1.0
97
+ * `cucumber-core` ~> 7.1.0
98
+ * `cucumber-gherkin` ~> 14.0.1
99
+ * Fix issue with empty feature files [#1427](https://github.com/cucumber/cucumber-ruby/issues/1427)
100
+ * `cucumber-messages` ~> 12.2.0
101
+ * `cucumber-html-formatter` ~> 7.0.0
102
+ * Fix issue with Hook attachments [#1420](https://github.com/cucumber/cucumber-ruby/issues/1420)
103
+
104
+ ### Fixed
105
+
106
+ * `AfterStep` hook do not cause issue when running `message` formatter. [#1433](https://github.com/cucumber/cucumber-ruby/issues/1433) - [#1434](https://github.com/cucumber/cucumber-ruby/pull/1434)
107
+
108
+
13
109
  ## [4.0.1](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0...v4.0.1)
14
110
 
15
111
  ### Fixed
@@ -59,13 +59,15 @@ help us to correct style violations reported here:
59
59
 
60
60
  ## Release Process
61
61
 
62
- * Bump the version number in `lib/cucumber/version`.
63
- * Make sure `CHANGELOG.md` is updated with the upcoming version number, and has entries for all fixes.
64
-
65
- Now release it
66
-
67
- bundle update
68
- bundle exec rake
69
- git commit -m "Release X.Y.Z"
70
- # Make sure you run gem signin as the cukebot@cucumber.io user before running the following step. Credentials can be found in 1Password
71
- rake release
62
+ * Upgrade gems with `scripts/update-gemspec`
63
+ * Bump the version number in `lib/cucumber/version`
64
+ * Update `CHANGELOG.md` with the upcoming version number and create a new `In Git` section
65
+ * Remove empty sections from `CHANGELOG.md`
66
+ * Now release it:
67
+
68
+ ```
69
+ git commit -am "Release X.Y.Z"
70
+ make release
71
+ ```
72
+
73
+ * Finally, update the cucumber-ruby version in the [documentation project](https://cucumber.io/docs/installation/) in [versions.yaml](https://github.com/cucumber/docs.cucumber.io/blob/master/data/versions.yaml) file.
@@ -24,23 +24,21 @@ module Autotest::CucumberMixin
24
24
  add_sigint_handler
25
25
 
26
26
  loop do # ^c handler
27
- begin
28
- get_to_green
29
- if tainted
30
- rerun_all_tests
31
- rerun_all_features if all_good
32
- else
33
- hook :all_good
34
- end
35
- wait_for_changes
36
- # Once tests and features are green, reset features every
37
- # time a file is changed to see if anything breaks.
38
- reset_features
39
- rescue Interrupt
40
- break if wants_to_quit
41
- reset
42
- reset_features
27
+ get_to_green
28
+ if tainted
29
+ rerun_all_tests
30
+ rerun_all_features if all_good
31
+ else
32
+ hook :all_good
43
33
  end
34
+ wait_for_changes
35
+ # Once tests and features are green, reset features every
36
+ # time a file is changed to see if anything breaks.
37
+ reset_features
38
+ rescue Interrupt
39
+ break if wants_to_quit
40
+ reset
41
+ reset_features
44
42
  end
45
43
  hook :quit
46
44
  end
@@ -9,6 +9,7 @@ require 'cucumber/core/test/result'
9
9
  module Cucumber
10
10
  module Cli
11
11
  class Options
12
+ CUCUMBER_PUBLISH_URL = ENV['CUCUMBER_PUBLISH_URL'] || 'https://messages.cucumber.io/api/reports -X GET'
12
13
  INDENT = ' ' * 53
13
14
  BUILTIN_FORMATS = {
14
15
  'pretty' => ['Cucumber::Formatter::Pretty', 'Prints the feature as is - in colours.'],
@@ -93,6 +94,10 @@ module Cucumber
93
94
 
94
95
  @args.options do |opts| # rubocop:disable Metrics/BlockLength
95
96
  opts.banner = banner
97
+ opts.on('--publish', 'Publish a report to https://reports.cucumber.io') do
98
+ set_option :publish_enabled, true
99
+ end
100
+ opts.on('--publish-quiet', 'Don\'t print information banner about publishing reports') { set_option :publish_quiet }
96
101
  opts.on('-r LIBRARY|DIR', '--require LIBRARY|DIR', *require_files_msg) { |lib| require_files(lib) }
97
102
 
98
103
  opts.on('-j DIR', '--jars DIR', 'Load all the jars under DIR') { |jars| load_jars(jars) } if Cucumber::JRUBY
@@ -117,7 +122,7 @@ module Cucumber
117
122
  opts.on('-s', '--no-source', "Don't print the file and line of the step definition with the steps.") { set_option :source, false }
118
123
  opts.on('-i', '--no-snippets', "Don't print snippets for pending steps.") { set_option :snippets, false }
119
124
  opts.on('-I', '--snippet-type TYPE', *snippet_type_msg) { |v| set_option :snippet_type, v.to_sym }
120
- opts.on('-q', '--quiet', 'Alias for --no-snippets --no-source.') { shut_up }
125
+ opts.on('-q', '--quiet', 'Alias for --no-snippets --no-source --no-duration --publish-quiet.') { shut_up }
121
126
  opts.on('--no-duration', "Don't print the duration at the end of the summary") { set_option :duration, false }
122
127
  opts.on('-b', '--backtrace', 'Show full backtrace for all errors.') { Cucumber.use_full_backtrace = true }
123
128
  opts.on('-S', '--[no-]strict', *strict_msg) { |setting| set_strict(setting) }
@@ -145,6 +150,8 @@ Specify SEED to reproduce the shuffling from a previous run.
145
150
  opts.on_tail('-h', '--help', "You're looking at it.") { exit_ok(opts.help) }
146
151
  end.parse!
147
152
 
153
+ process_publish_options
154
+
148
155
  @args.map! { |a| "#{a}:#{@options[:lines]}" } if @options[:lines]
149
156
 
150
157
  extract_environment_variables
@@ -182,6 +189,18 @@ Specify SEED to reproduce the shuffling from a previous run.
182
189
 
183
190
  private
184
191
 
192
+ def process_publish_options
193
+ @options[:publish_enabled] = true if truthy_string?(ENV['CUCUMBER_PUBLISH_ENABLED']) || ENV['CUCUMBER_PUBLISH_TOKEN']
194
+ @options[:formats] << publisher if @options[:publish_enabled]
195
+
196
+ @options[:publish_quiet] = true if truthy_string?(ENV['CUCUMBER_PUBLISH_QUIET'])
197
+ end
198
+
199
+ def truthy_string?(str)
200
+ return false if str.nil?
201
+ str !~ /^(false|no|0)$/i
202
+ end
203
+
185
204
  def color_msg
186
205
  [
187
206
  'Whether or not to use ANSI color in the output. Cucumber decides',
@@ -348,7 +367,13 @@ Specify SEED to reproduce the shuffling from a previous run.
348
367
  end
349
368
 
350
369
  def require_jars(jars)
351
- Dir["#{jars}/**/*.jar"].each { |jar| require jar }
370
+ Dir["#{jars}/**/*.jar"].sort.each { |jar| require jar }
371
+ end
372
+
373
+ def publisher
374
+ url = CUCUMBER_PUBLISH_URL
375
+ url += %( -H "Authorization: Bearer #{ENV['CUCUMBER_PUBLISH_TOKEN']}") if ENV['CUCUMBER_PUBLISH_TOKEN']
376
+ ['message', {}, url]
352
377
  end
353
378
 
354
379
  def language(lang)
@@ -415,6 +440,7 @@ Specify SEED to reproduce the shuffling from a previous run.
415
440
  end
416
441
 
417
442
  def shut_up
443
+ @options[:publish_quiet] = true
418
444
  @options[:snippets] = false
419
445
  @options[:source] = false
420
446
  @options[:duration] = false
@@ -62,6 +62,14 @@ module Cucumber
62
62
  @options[:dry_run]
63
63
  end
64
64
 
65
+ def publish_enabled?
66
+ @options[:publish_enabled]
67
+ end
68
+
69
+ def publish_quiet?
70
+ @options[:publish_quiet]
71
+ end
72
+
65
73
  def fail_fast?
66
74
  @options[:fail_fast]
67
75
  end
@@ -197,14 +205,12 @@ module Cucumber
197
205
 
198
206
  def formatter_factories
199
207
  formats.map do |format, formatter_options, path_or_io|
200
- begin
201
- factory = formatter_class(format)
202
- yield factory,
203
- formatter_options,
204
- path_or_io
205
- rescue Exception => e # rubocop:disable Lint/RescueException
206
- raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
207
- end
208
+ factory = formatter_class(format)
209
+ yield factory,
210
+ formatter_options,
211
+ path_or_io
212
+ rescue Exception => e # rubocop:disable Lint/RescueException
213
+ raise e, "#{e.message}\nError creating formatter: #{format}", e.backtrace
208
214
  end
209
215
  end
210
216
 
@@ -256,6 +262,7 @@ module Cucumber
256
262
  strict: Cucumber::Core::Test::Result::StrictConfiguration.new,
257
263
  require: [],
258
264
  dry_run: false,
265
+ publish_quiet: false,
259
266
  fail_fast: false,
260
267
  formats: [],
261
268
  excludes: [],
@@ -41,7 +41,7 @@ module Cucumber
41
41
 
42
42
  module ForDevelopers
43
43
  def self.call(_message, _method, remove_after_version)
44
- raise "This method is due for removal after version #{remove_after_version}" if Cucumber::VERSION > remove_after_version
44
+ raise "This method is due for removal after version #{remove_after_version}" if Cucumber::VERSION >= remove_after_version
45
45
  end
46
46
  end
47
47
 
@@ -11,7 +11,7 @@ module Cucumber
11
11
  begin
12
12
  raise new(with_prefix(step_name)) # rubocop:disable Style/RaiseArgs
13
13
  rescue StandardError => e
14
- return e
14
+ e
15
15
  end
16
16
  end
17
17
 
@@ -136,7 +136,6 @@ module Cucumber
136
136
 
137
137
  private
138
138
 
139
- # rubocop:disable Metrics/PerceivedComplexity
140
139
  def process_scenario_container(container, original_previous_node)
141
140
  container.children.each do |child|
142
141
  previous_node = original_previous_node
@@ -158,7 +157,6 @@ module Cucumber
158
157
  end
159
158
  end
160
159
  end
161
- # rubocop:enable Metrics/PerceivedComplexity
162
160
  end
163
161
  end
164
162
  end
@@ -6,10 +6,12 @@ module Cucumber
6
6
  class HTTPIO
7
7
  class << self
8
8
  # Returns an IO that will write to a HTTP request's body
9
- def open(url, https_verify_mode = nil)
9
+ # https_verify_mode can be set to OpenSSL::SSL::VERIFY_NONE
10
+ # to ignore unsigned certificate - setting to nil will verify the certificate
11
+ def open(url, https_verify_mode = nil, reporter = nil)
10
12
  @https_verify_mode = https_verify_mode
11
13
  uri, method, headers = CurlOptionParser.parse(url)
12
- IOHTTPBuffer.new(uri, method, headers, https_verify_mode)
14
+ IOHTTPBuffer.new(uri, method, headers, https_verify_mode, reporter)
13
15
  end
14
16
  end
15
17
  end
@@ -64,16 +66,19 @@ module Cucumber
64
66
  class IOHTTPBuffer
65
67
  attr_reader :uri, :method, :headers
66
68
 
67
- def initialize(uri, method, headers = {}, https_verify_mode = nil)
69
+ def initialize(uri, method, headers = {}, https_verify_mode = nil, reporter = nil)
68
70
  @uri = URI(uri)
69
71
  @method = method
70
72
  @headers = headers
71
73
  @write_io = Tempfile.new('cucumber', encoding: 'UTF-8')
72
74
  @https_verify_mode = https_verify_mode
75
+ @reporter = reporter || NoReporter.new
73
76
  end
74
77
 
75
78
  def close
76
- post_content(@uri, @method, @headers)
79
+ resource_uri = send_content(@uri, @method, @headers)
80
+
81
+ @reporter.report(resource_uri)
77
82
  @write_io.close
78
83
  end
79
84
 
@@ -91,8 +96,8 @@ module Cucumber
91
96
 
92
97
  private
93
98
 
94
- def post_content(uri, method, headers, attempt = 10)
95
- content = @write_io
99
+ def send_content(uri, method, headers, attempt = 10)
100
+ content = (method == 'GET' ? StringIO.new : @write_io)
96
101
  http = build_client(uri, @https_verify_mode)
97
102
 
98
103
  raise StandardError, "request to #{uri} failed (too many redirections)" if attempt <= 0
@@ -115,10 +120,14 @@ module Cucumber
115
120
  end
116
121
 
117
122
  case response
123
+ when Net::HTTPAccepted
124
+ return uri unless response['Location']
125
+
126
+ send_content(URI(response['Location']), 'PUT', {}, attempt - 1)
118
127
  when Net::HTTPSuccess
119
- response
128
+ uri
120
129
  when Net::HTTPRedirection
121
- post_content(URI(response['Location']), method, headers, attempt - 1)
130
+ send_content(URI(response['Location']), method, headers, attempt - 1)
122
131
  else
123
132
  raise StandardError, "request to #{uri} failed with status #{response.code}"
124
133
  end
@@ -5,6 +5,7 @@ module Cucumber
5
5
  module Interceptor
6
6
  class Pipe
7
7
  attr_reader :pipe
8
+
8
9
  def initialize(pipe)
9
10
  @pipe = pipe
10
11
  @buffer = StringIO.new
@@ -31,7 +32,7 @@ module Cucumber
31
32
  end
32
33
 
33
34
  def method_missing(method, *args, &blk)
34
- @pipe.send(method, *args, &blk) || super
35
+ @pipe.respond_to?(method) ? @pipe.send(method, *args, &blk) : super
35
36
  end
36
37
 
37
38
  def respond_to_missing?(method, include_private = false)
@@ -62,10 +63,10 @@ module Cucumber
62
63
  case pipe
63
64
  when :stderr
64
65
  $stderr = new($stderr)
65
- return $stderr
66
+ $stderr
66
67
  when :stdout
67
68
  $stdout = new($stdout)
68
- return $stdout
69
+ $stdout
69
70
  end
70
71
  end
71
72
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'cucumber/formatter/http_io'
4
+ require 'cucumber/formatter/url_reporter'
5
+ require 'cucumber/cli/options'
4
6
 
5
7
  module Cucumber
6
8
  module Formatter
@@ -9,19 +11,53 @@ module Cucumber
9
11
 
10
12
  def ensure_io(path_or_url_or_io)
11
13
  return nil if path_or_url_or_io.nil?
12
- return path_or_url_or_io if path_or_url_or_io.respond_to?(:write)
13
- io = if path_or_url_or_io.match(%r{^https?://})
14
- HTTPIO.open(path_or_url_or_io)
14
+ return path_or_url_or_io if io?(path_or_url_or_io)
15
+
16
+ io = if url?(path_or_url_or_io)
17
+ url = path_or_url_or_io
18
+ reporter = url.start_with?(Cucumber::Cli::Options::CUCUMBER_PUBLISH_URL) ? URLReporter.new($stderr) : NoReporter.new
19
+ HTTPIO.open(url, nil, reporter)
15
20
  else
16
21
  File.open(path_or_url_or_io, Cucumber.file_mode('w'))
17
22
  end
18
- at_exit do
19
- unless io.closed?
20
- io.flush
21
- io.close
23
+ @io_objects_to_close ||= []
24
+ @io_objects_to_close.push(io)
25
+ io
26
+ end
27
+
28
+ module ClassMethods
29
+ def new(*args, &block)
30
+ instance = super
31
+
32
+ config = args[0]
33
+ if config.respond_to? :on_event
34
+ config.on_event :test_run_finished do
35
+ ios = instance.instance_variable_get(:@io_objects_to_close) || []
36
+ ios.each do |io|
37
+ at_exit do
38
+ unless io.closed?
39
+ io.flush
40
+ io.close
41
+ end
42
+ end
43
+ end
44
+ end
22
45
  end
46
+
47
+ instance
23
48
  end
24
- io
49
+ end
50
+
51
+ def self.included(formatter_class)
52
+ formatter_class.extend(ClassMethods)
53
+ end
54
+
55
+ def io?(path_or_url_or_io)
56
+ path_or_url_or_io.respond_to?(:write)
57
+ end
58
+
59
+ def url?(path_or_url_or_io)
60
+ path_or_url_or_io.match(%r{^https?://})
25
61
  end
26
62
 
27
63
  def ensure_file(path, name)