cucumber 4.0.0.rc.4 → 4.1.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 +77 -2
- data/README.md +2 -2
- data/lib/cucumber/cli/options.rb +8 -3
- data/lib/cucumber/errors.rb +0 -3
- data/lib/cucumber/events.rb +2 -1
- data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
- data/lib/cucumber/formatter/console.rb +30 -2
- data/lib/cucumber/formatter/html.rb +24 -0
- data/lib/cucumber/formatter/http_io.rb +146 -0
- data/lib/cucumber/formatter/interceptor.rb +3 -8
- data/lib/cucumber/formatter/io.rb +14 -8
- data/lib/cucumber/formatter/json.rb +2 -2
- data/lib/cucumber/formatter/message.rb +3 -227
- data/lib/cucumber/formatter/message_builder.rb +255 -0
- data/lib/cucumber/formatter/pretty.rb +7 -0
- data/lib/cucumber/formatter/progress.rb +2 -0
- data/lib/cucumber/glue/proto_world.rb +2 -3
- data/lib/cucumber/glue/registry_and_more.rb +2 -6
- data/lib/cucumber/glue/snippet.rb +1 -1
- data/lib/cucumber/glue/step_definition.rb +3 -3
- data/lib/cucumber/platform.rb +1 -1
- data/lib/cucumber/rake/task.rb +1 -1
- data/lib/cucumber/runtime.rb +7 -1
- data/lib/cucumber/runtime/step_hooks.rb +5 -2
- data/lib/cucumber/runtime/support_code.rb +1 -1
- data/lib/cucumber/version +1 -1
- metadata +115 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1f051aade812ee4bb28ab3670734b189ade8bc0cd0150a686e21874594ae62f
|
4
|
+
data.tar.gz: 80c272791953dc442492c0571acffc628cb7b1f37a28a00adeef413bc7f76e1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5026e105060af702f3b0adf50f3925ce04fdee7de79c2482093831cab838e2a605d69c056733d7820b6592c7229ee93e1ce64b80ae373ac7acd29f11d113d3a8
|
7
|
+
data.tar.gz: c66fe1effa60270eb430bc2c381252e5c3da5dec524e49c58a7e508febaeb0b1398791f75eba5542395672b2431dafcfb820da2870410a52474ebc157bfbe333
|
data/CHANGELOG.md
CHANGED
@@ -10,8 +10,83 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
|
|
10
10
|
|
11
11
|
----
|
12
12
|
|
13
|
-
## [4.
|
13
|
+
## [4.1.0](https://github.com/cucumber/cucumber-ruby/compare/v4.0.1...v4.1.0)
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
* Use [`cucumber-create-meta`](https://rubygems.org/gems/cucumber-create-meta) to produce the `Meta` message before the run.
|
18
|
+
|
19
|
+
* Updated gems:
|
20
|
+
* `cucumber-wire` ~> 3.1.0
|
21
|
+
* `cucumber-core` ~> 7.1.0
|
22
|
+
* `cucumber-gherkin` ~> 14.0.1
|
23
|
+
* Fix issue with empty feature files [#1427](https://github.com/cucumber/cucumber-ruby/issues/1427)
|
24
|
+
* `cucumber-messages` ~> 12.2.0
|
25
|
+
* `cucumber-html-formatter` ~> 7.0.0
|
26
|
+
* Fix issue with Hook attachments [#1420](https://github.com/cucumber/cucumber-ruby/issues/1420)
|
27
|
+
|
28
|
+
### Fixed
|
29
|
+
|
30
|
+
* `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)
|
31
|
+
|
32
|
+
|
33
|
+
## [4.0.1](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0...v4.0.1)
|
34
|
+
|
35
|
+
### Fixed
|
36
|
+
|
37
|
+
* force reference to `diff-lcs` to 1.3 as 1.4 introduced breaking changes.
|
38
|
+
|
39
|
+
## [4.0.0](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.5...v4.0.0)
|
40
|
+
|
41
|
+
### Changed
|
42
|
+
|
43
|
+
* `log` method can now be called with non-string objects and will run `.to_s` on them. [#1410](https://github.com/cucumber/cucumber-ruby/issues/1410)
|
44
|
+
|
45
|
+
### Improved
|
14
46
|
|
47
|
+
* Display snippet when using undefined parameter type [#1411](https://github.com/cucumber/cucumber-ruby/issues/1411)
|
48
|
+
|
49
|
+
## [4.0.0.rc.6](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.5...4.0.0.rc.6)
|
50
|
+
|
51
|
+
### Changed
|
52
|
+
|
53
|
+
* Code snippet for an undefined step with a Doc String will ouput `doc_string` instead of `string` in block params
|
54
|
+
([#1401](https://github.com/cucumber/cucumber-ruby/issues/1401)
|
55
|
+
[#1402](https://github.com/cucumber/cucumber-ruby/pull/1402)
|
56
|
+
[karamosky](https://github.com/karamosky))
|
57
|
+
|
58
|
+
* Updated monorepo libraries:
|
59
|
+
- cucumber-gherkin ~> 13
|
60
|
+
- cucumber-html-formatter ~> 6
|
61
|
+
- cucumber-cucumber-expressions ~> 10
|
62
|
+
|
63
|
+
* Use `cucumber-ruby-core` 7.0.0
|
64
|
+
|
65
|
+
* Use `cucumber-ruby-wire` 3.0.0
|
66
|
+
|
67
|
+
* Use `body` field of attachments
|
68
|
+
|
69
|
+
### Improved
|
70
|
+
|
71
|
+
* `--out url` updates:
|
72
|
+
* supports redirects
|
73
|
+
* use `PUT` method by default
|
74
|
+
* use a cURL like options (for example: `cucumber --out 'http://example.com -X POST -H Content-Type: json`)
|
75
|
+
|
76
|
+
## [4.0.0.rc.5](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.4...4.0.0.rc.5)
|
77
|
+
|
78
|
+
### Added
|
79
|
+
|
80
|
+
* New html formatter enabled by option `--format html --out report.html`.
|
81
|
+
|
82
|
+
* Accept `--out URL` to POST results to a web server
|
83
|
+
If a URL is used as output, the output will be sent with a POST request.
|
84
|
+
This can be overridden by specifying e.g. `http-method=PUT` as a query parameter.
|
85
|
+
Other `http-` prefixed query parameters will be converted to request headers
|
86
|
+
(with the `http-` prefix stripped off).
|
87
|
+
|
88
|
+
|
89
|
+
## [4.0.0.rc.4](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.3...4.0.0.rc.4)
|
15
90
|
|
16
91
|
### Added
|
17
92
|
|
@@ -42,7 +117,7 @@ Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blo
|
|
42
117
|
* If you wish to alter this, then you can set a top level config option: `Cucumber.use_legacy_autoloader`
|
43
118
|
* Like most config options, setting this inside a `spec_helper.rb` or `env.rb` file is advised
|
44
119
|
* For more information on this change, including why it was made. Please read this
|
45
|
-
[Blog Post](
|
120
|
+
[Blog Post](https://cucumber.io/blog/open-source/tweaking-cucumber-rubys-auto-loader/)
|
46
121
|
([#1349](https://github.com/cucumber/cucumber-ruby/pull/1349),
|
47
122
|
[#1043](https://github.com/cucumber/cucumber-ruby/issues/1043)
|
48
123
|
[luke-hill](https://github.com/luke-hill))
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ your team.
|
|
15
15
|
|
16
16
|
Where to get more info:
|
17
17
|
|
18
|
-
* The main website: https://cucumber.io/
|
18
|
+
* The main website: https://cucumber.io/
|
19
19
|
* Documentation: https://cucumber.io/docs
|
20
20
|
* Ruby API Documentation: http://www.rubydoc.info/github/cucumber/cucumber-ruby/
|
21
21
|
* Support forum: https://groups.google.com/group/cukes
|
@@ -28,7 +28,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for info on contributing to Cucumber.
|
|
28
28
|
* Ruby 2.5
|
29
29
|
* Ruby 2.4
|
30
30
|
* Ruby 2.3
|
31
|
-
* JRuby 9.
|
31
|
+
* JRuby 9.2 (with [some limitations](https://github.com/cucumber/cucumber-ruby/blob/master/docs/jruby-limitations.md))
|
32
32
|
|
33
33
|
## Code of Conduct
|
34
34
|
|
data/lib/cucumber/cli/options.rb
CHANGED
@@ -24,6 +24,7 @@ module Cucumber
|
|
24
24
|
'junit' => ['Cucumber::Formatter::Junit', 'Generates a report similar to Ant+JUnit.'],
|
25
25
|
'json' => ['Cucumber::Formatter::Json', '[DEPRECATED] Prints the feature as JSON'],
|
26
26
|
'message' => ['Cucumber::Formatter::Message', 'Outputs protobuf messages'],
|
27
|
+
'html' => ['Cucumber::Formatter::HTML', 'Outputs HTML report'],
|
27
28
|
'summary' => ['Cucumber::Formatter::Summary', 'Summary output of feature and scenarios']
|
28
29
|
}.freeze
|
29
30
|
max = BUILTIN_FORMATS.keys.map(&:length).max
|
@@ -104,7 +105,7 @@ module Cucumber
|
|
104
105
|
add_option :formats, [*parse_formats(v), @out_stream]
|
105
106
|
end
|
106
107
|
opts.on('--init', *init_msg) { |_v| initialize_project }
|
107
|
-
opts.on('-o', '--out [FILE|DIR]', *out_msg) { |v| out_stream v }
|
108
|
+
opts.on('-o', '--out [FILE|DIR|URL]', *out_msg) { |v| out_stream v }
|
108
109
|
opts.on('-t TAG_EXPRESSION', '--tags TAG_EXPRESSION', *tags_msg) { |v| add_tag v }
|
109
110
|
opts.on('-n NAME', '--name NAME', *name_msg) { |v| add_option :name_regexps, /#{v}/ }
|
110
111
|
opts.on('-e', '--exclude PATTERN', *exclude_msg) { |v| add_option :excludes, Regexp.new(v) }
|
@@ -295,10 +296,14 @@ Specify SEED to reproduce the shuffling from a previous run.
|
|
295
296
|
|
296
297
|
def out_msg
|
297
298
|
[
|
298
|
-
'Write output to a file/directory instead of STDOUT. This option',
|
299
|
+
'Write output to a file/directory/URL instead of STDOUT. This option',
|
299
300
|
'applies to the previously specified --format, or the',
|
300
301
|
'default format if no format is specified. Check the specific',
|
301
|
-
"formatter's docs to see whether to pass a file or
|
302
|
+
"formatter's docs to see whether to pass a file, dir or URL.",
|
303
|
+
"\n",
|
304
|
+
'When using a URL, the output of the formatter will be sent as the HTTP request body.',
|
305
|
+
'HTTP headers and request method can be set with cURL like options.',
|
306
|
+
'Example: --out "http://example.com -X POST -H Content-Type:text/json"'
|
302
307
|
]
|
303
308
|
end
|
304
309
|
|
data/lib/cucumber/errors.rb
CHANGED
data/lib/cucumber/events.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# rubocop:disable Metrics/ModuleLength
|
4
|
+
|
3
5
|
require 'cucumber/formatter/ansicolor'
|
4
6
|
require 'cucumber/formatter/duration'
|
5
7
|
require 'cucumber/gherkin/i18n'
|
@@ -116,14 +118,21 @@ module Cucumber
|
|
116
118
|
@snippets_input << Console::SnippetData.new(keyword, test_step)
|
117
119
|
end
|
118
120
|
|
121
|
+
def collect_undefined_parameter_type_names(undefined_parameter_type)
|
122
|
+
@undefined_parameter_types << undefined_parameter_type.type_name
|
123
|
+
end
|
124
|
+
|
119
125
|
def print_snippets(options)
|
120
126
|
return unless options[:snippets]
|
121
|
-
return if @snippets_input.empty?
|
122
127
|
|
123
128
|
snippet_text_proc = lambda do |step_keyword, step_name, multiline_arg|
|
124
129
|
snippet_text(step_keyword, step_name, multiline_arg)
|
125
130
|
end
|
126
|
-
do_print_snippets(snippet_text_proc)
|
131
|
+
do_print_snippets(snippet_text_proc) unless @snippets_input.empty?
|
132
|
+
|
133
|
+
@undefined_parameter_types.map do |type_name|
|
134
|
+
do_print_undefined_parameter_type_snippet(type_name)
|
135
|
+
end
|
127
136
|
end
|
128
137
|
|
129
138
|
def do_print_snippets(snippet_text_proc)
|
@@ -181,6 +190,24 @@ module Cucumber
|
|
181
190
|
@io.puts "Using the #{profiles_sentence} profile#{'s' if profiles.size > 1}..."
|
182
191
|
end
|
183
192
|
|
193
|
+
def do_print_undefined_parameter_type_snippet(type_name)
|
194
|
+
camelized = type_name.split(/_|-/).collect(&:capitalize).join
|
195
|
+
|
196
|
+
@io.puts [
|
197
|
+
"The parameter #{type_name} is not defined. You can define a new one with:",
|
198
|
+
'',
|
199
|
+
'ParameterType(',
|
200
|
+
" name: '#{type_name}',",
|
201
|
+
' regexp: /some regexp here/,',
|
202
|
+
" type: #{camelized},",
|
203
|
+
' # The transformer takes as many arguments as there are capture groups in the regexp,',
|
204
|
+
' # or just one if there are none.',
|
205
|
+
" transformer: ->(s) { #{camelized}.new(s) }",
|
206
|
+
')',
|
207
|
+
''
|
208
|
+
].join("\n")
|
209
|
+
end
|
210
|
+
|
184
211
|
private
|
185
212
|
|
186
213
|
FORMATS = Hash.new { |hash, format| hash[format] = method(format).to_proc }
|
@@ -219,3 +246,4 @@ module Cucumber
|
|
219
246
|
end
|
220
247
|
end
|
221
248
|
end
|
249
|
+
# rubocop:enable Metrics/ModuleLength
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cucumber/formatter/io'
|
2
|
+
require 'cucumber/html_formatter'
|
3
|
+
require 'cucumber/formatter/message_builder'
|
4
|
+
|
5
|
+
module Cucumber
|
6
|
+
module Formatter
|
7
|
+
class HTML < MessageBuilder
|
8
|
+
include Io
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
@io = ensure_io(config.out_stream)
|
12
|
+
@html_formatter = Cucumber::HTMLFormatter::Formatter.new(@io)
|
13
|
+
@html_formatter.write_pre_message
|
14
|
+
|
15
|
+
super(config)
|
16
|
+
end
|
17
|
+
|
18
|
+
def output_envelope(envelope)
|
19
|
+
@html_formatter.write_message(envelope)
|
20
|
+
@html_formatter.write_post_message if envelope.test_run_finished
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Formatter
|
6
|
+
class HTTPIO
|
7
|
+
class << self
|
8
|
+
# Returns an IO that will write to a HTTP request's body
|
9
|
+
def open(url, https_verify_mode = nil)
|
10
|
+
@https_verify_mode = https_verify_mode
|
11
|
+
uri, method, headers = CurlOptionParser.parse(url)
|
12
|
+
IOHTTPBuffer.new(uri, method, headers, https_verify_mode)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class CurlOptionParser
|
18
|
+
def self.parse(options)
|
19
|
+
chunks = options.split(/\s/).compact
|
20
|
+
http_method = 'PUT'
|
21
|
+
url = chunks[0]
|
22
|
+
headers = ''
|
23
|
+
|
24
|
+
last_flag = nil
|
25
|
+
chunks.each do |chunk|
|
26
|
+
if ['-X', '--request'].include?(chunk)
|
27
|
+
last_flag = '-X'
|
28
|
+
next
|
29
|
+
end
|
30
|
+
|
31
|
+
if chunk == '-H'
|
32
|
+
last_flag = '-H'
|
33
|
+
next
|
34
|
+
end
|
35
|
+
|
36
|
+
if last_flag == '-X'
|
37
|
+
http_method = chunk
|
38
|
+
last_flag = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
headers += chunk if last_flag == '-H'
|
42
|
+
end
|
43
|
+
|
44
|
+
[
|
45
|
+
url,
|
46
|
+
http_method,
|
47
|
+
make_headers(headers)
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.make_headers(headers)
|
52
|
+
hash_headers = {}
|
53
|
+
str_scanner = /("(?<key>[^":]+)\s*:\s*(?<value>[^":]+)")|('(?<key1>[^':]+)\s*:\s*(?<value1>[^':]+)')/
|
54
|
+
|
55
|
+
headers.scan(str_scanner) do |header|
|
56
|
+
header = header.compact!
|
57
|
+
hash_headers[header[0]] = header[1]&.strip
|
58
|
+
end
|
59
|
+
|
60
|
+
hash_headers
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class IOHTTPBuffer
|
65
|
+
attr_reader :uri, :method, :headers
|
66
|
+
|
67
|
+
def initialize(uri, method, headers = {}, https_verify_mode = nil)
|
68
|
+
@uri = URI(uri)
|
69
|
+
@method = method
|
70
|
+
@headers = headers
|
71
|
+
@write_io = Tempfile.new('cucumber', encoding: 'UTF-8')
|
72
|
+
@https_verify_mode = https_verify_mode
|
73
|
+
end
|
74
|
+
|
75
|
+
def close
|
76
|
+
post_content(@uri, @method, @headers)
|
77
|
+
@write_io.close
|
78
|
+
end
|
79
|
+
|
80
|
+
def write(data)
|
81
|
+
@write_io.write(data)
|
82
|
+
end
|
83
|
+
|
84
|
+
def flush
|
85
|
+
@write_io.flush
|
86
|
+
end
|
87
|
+
|
88
|
+
def closed?
|
89
|
+
@write_io.closed?
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def post_content(uri, method, headers, attempt = 10)
|
95
|
+
content = @write_io
|
96
|
+
http = build_client(uri, @https_verify_mode)
|
97
|
+
|
98
|
+
raise StandardError, "request to #{uri} failed (too many redirections)" if attempt <= 0
|
99
|
+
req = build_request(
|
100
|
+
uri,
|
101
|
+
method,
|
102
|
+
headers.merge(
|
103
|
+
'Content-Length' => content.size.to_s
|
104
|
+
)
|
105
|
+
)
|
106
|
+
|
107
|
+
content.rewind
|
108
|
+
req.body_stream = content
|
109
|
+
|
110
|
+
begin
|
111
|
+
response = http.request(req)
|
112
|
+
rescue SystemCallError
|
113
|
+
# We may get the redirect response before pushing the file.
|
114
|
+
response = http.request(build_request(uri, method, headers))
|
115
|
+
end
|
116
|
+
|
117
|
+
case response
|
118
|
+
when Net::HTTPSuccess
|
119
|
+
response
|
120
|
+
when Net::HTTPRedirection
|
121
|
+
post_content(URI(response['Location']), method, headers, attempt - 1)
|
122
|
+
else
|
123
|
+
raise StandardError, "request to #{uri} failed with status #{response.code}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def build_request(uri, method, headers)
|
128
|
+
method_class_name = "#{method[0].upcase}#{method[1..-1].downcase}"
|
129
|
+
req = Net::HTTP.const_get(method_class_name).new(uri)
|
130
|
+
headers.each do |header, value|
|
131
|
+
req[header] = value
|
132
|
+
end
|
133
|
+
req
|
134
|
+
end
|
135
|
+
|
136
|
+
def build_client(uri, https_verify_mode)
|
137
|
+
http = Net::HTTP.new(uri.hostname, uri.port)
|
138
|
+
if uri.scheme == 'https'
|
139
|
+
http.use_ssl = true
|
140
|
+
http.verify_mode = https_verify_mode if https_verify_mode
|
141
|
+
end
|
142
|
+
http
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -9,17 +9,18 @@ module Cucumber
|
|
9
9
|
@pipe = pipe
|
10
10
|
@buffer = StringIO.new
|
11
11
|
@wrapped = true
|
12
|
+
@lock = Mutex.new
|
12
13
|
end
|
13
14
|
|
14
15
|
def write(str)
|
15
|
-
lock.synchronize do
|
16
|
+
@lock.synchronize do
|
16
17
|
@buffer << str if @wrapped
|
17
18
|
return @pipe.write(str)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
22
|
def buffer_string
|
22
|
-
lock.synchronize do
|
23
|
+
@lock.synchronize do
|
23
24
|
return @buffer.string.dup
|
24
25
|
end
|
25
26
|
end
|
@@ -67,12 +68,6 @@ module Cucumber
|
|
67
68
|
return $stdout
|
68
69
|
end
|
69
70
|
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def lock
|
74
|
-
@lock ||= Mutex.new
|
75
|
-
end
|
76
71
|
end
|
77
72
|
end
|
78
73
|
end
|