cucumber 4.0.0.rc.4 → 4.0.0.rc.5

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: 3cf95e63d73ffec417fa0dfc1f13e208355e78783a9f092d8e143dc5ca26d636
4
- data.tar.gz: 869fe72a5dd449be55d00e2e72d8f78c236961141bf1cc85a7919bca426ec299
3
+ metadata.gz: 388c05be14607a5aaa4acaef66d2bb5f6dab1258bc3e785e71a077fae3d366a7
4
+ data.tar.gz: 2546749fa602b12b756e0dee45ff756fc89507329504b94f633b39cd5692464e
5
5
  SHA512:
6
- metadata.gz: 37c240a47d8127723e75c33051ff4e546a7e5a084a22400bb55e6d00d6d578ab7d5d7daf905259cba6625a512986fcacd4076810202e6f63dbffea16b366e9f5
7
- data.tar.gz: 4556b216164535c0c2b39a1f2116b511f0cb1cccfee41cddb513073d0d887014edb38a632978347d1c127e228f1bd683317fbc62588bd4b497cdd51e10a3c550
6
+ metadata.gz: ed762cc475552e7698cf9ebae51b00366f88f000fcbbbd9697bfa1056a2ec7a7a9d49bb946e0f785d8c1d435da443bd2cca834a2309a11403836dc11f93de169
7
+ data.tar.gz: 112fb462eb9a3bdb1056c3ad32670ad1160ad0f40a6b804bc09b5e948443073df55a8b6c2818c0cb8f7794623b8e71f04d913a1559bb0b69536cc7bf7634873c
@@ -9,9 +9,20 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
9
9
  Please visit [cucumber/CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CONTRIBUTING.md) for more info on how to contribute to Cucumber.
10
10
 
11
11
  ----
12
+ ## [4.0.0.rc.5](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.4...4.0.0.rc.5)
12
13
 
13
- ## [4.0.0.rc.4](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.3...4.0.0.rc.4)
14
+ ### Added
15
+
16
+ * New html formatter enabled by option `--format html --out report.html`.
14
17
 
18
+ * Accept `--out URL` to POST results to a web server
19
+ If a URL is used as output, the output will be sent with a POST request.
20
+ This can be overridden by specifying e.g. `http-method=PUT` as a query parameter.
21
+ Other `http-` prefixed query parameters will be converted to request headers
22
+ (with the `http-` prefix stripped off).
23
+
24
+
25
+ ## [4.0.0.rc.4](https://github.com/cucumber/cucumber-ruby/compare/v4.0.0.rc.3...4.0.0.rc.4)
15
26
 
16
27
  ### Added
17
28
 
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.1
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
 
@@ -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,15 @@ 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 a dir."
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 http- prefixed query parameters,',
306
+ 'for example ?http-content-type=application/json&http-method=PUT.',
307
+ 'All http- prefixed query parameters will be removed from the sent query parameters.'
302
308
  ]
303
309
  end
304
310
 
@@ -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,93 @@
1
+ require 'net/http'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ class HTTPIO
6
+ class << self
7
+ # Returns an IO that will write to a HTTP request's body
8
+ def open(url, https_verify_mode = nil)
9
+ @https_verify_mode = https_verify_mode
10
+ uri, method, headers = build_uri_method_headers(url)
11
+
12
+ @req = build_request(uri, method, headers)
13
+ @http = build_client(uri, https_verify_mode)
14
+
15
+ read_io, write_io = IO.pipe
16
+ @req.body_stream = read_io
17
+
18
+ class << write_io
19
+ attr_writer :request_thread
20
+
21
+ def start_request(http, req)
22
+ @req_thread = Thread.new do
23
+ begin
24
+ res = http.request(req)
25
+ raise StandardError, "request to #{req.uri} failed with status #{res.code}" if res.code.to_i >= 400
26
+ rescue StandardError => e
27
+ @http_error = e
28
+ end
29
+ end
30
+ end
31
+
32
+ def close
33
+ super
34
+ begin
35
+ @req_thread.join
36
+ rescue StandardError
37
+ nil
38
+ end
39
+ raise @http_error unless @http_error.nil?
40
+ end
41
+ end
42
+ write_io.start_request(@http, @req)
43
+
44
+ write_io
45
+ end
46
+
47
+ def build_uri_method_headers(url)
48
+ uri = URI(url)
49
+ query_pairs = uri.query ? URI.decode_www_form(uri.query) : []
50
+
51
+ # Build headers from query parameters prefixed with http- and extract HTTP method
52
+ http_query_pairs = query_pairs.select { |pair| pair[0] =~ /^http-/ }
53
+ http_query_hash_without_prefix = Hash[http_query_pairs.map do |pair|
54
+ [
55
+ pair[0][5..-1].downcase, # remove http- prefix
56
+ pair[1]
57
+ ]
58
+ end]
59
+ method = http_query_hash_without_prefix.delete('method') || 'POST'
60
+ headers = {
61
+ 'transfer-encoding' => 'chunked'
62
+ }.merge(http_query_hash_without_prefix)
63
+
64
+ # Update the query with the http-* parameters removed
65
+ remaining_query_pairs = query_pairs - http_query_pairs
66
+ new_query_hash = Hash[remaining_query_pairs]
67
+ uri.query = URI.encode_www_form(new_query_hash) unless new_query_hash.empty?
68
+ [uri, method, headers]
69
+ end
70
+
71
+ private
72
+
73
+ def build_request(uri, method, headers)
74
+ method_class_name = "#{method[0].upcase}#{method[1..-1].downcase}"
75
+ req = Net::HTTP.const_get(method_class_name).new(uri)
76
+ headers.each do |header, value|
77
+ req[header] = value
78
+ end
79
+ req
80
+ end
81
+
82
+ def build_client(uri, https_verify_mode)
83
+ http = Net::HTTP.new(uri.hostname, uri.port)
84
+ if uri.scheme == 'https'
85
+ http.use_ssl = true
86
+ http.verify_mode = https_verify_mode if https_verify_mode
87
+ end
88
+ http
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,21 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'cucumber/formatter/http_io'
4
+
3
5
  module Cucumber
4
6
  module Formatter
5
7
  module Io
6
8
  module_function
7
9
 
8
- def ensure_io(path_or_io)
9
- return nil if path_or_io.nil?
10
- return path_or_io if path_or_io.respond_to?(:write)
11
- file = File.open(path_or_io, Cucumber.file_mode('w'))
10
+ def ensure_io(path_or_url_or_io)
11
+ 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)
15
+ else
16
+ File.open(path_or_url_or_io, Cucumber.file_mode('w'))
17
+ end
12
18
  at_exit do
13
- unless file.closed?
14
- file.flush
15
- file.close
19
+ unless io.closed?
20
+ io.flush
21
+ io.close
16
22
  end
17
23
  end
18
- file
24
+ io
19
25
  end
20
26
 
21
27
  def ensure_file(path, name)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_json'
3
+ require 'json'
4
4
  require 'base64'
5
5
  require 'cucumber/formatter/backtrace_filter'
6
6
  require 'cucumber/formatter/io'
@@ -86,7 +86,7 @@ module Cucumber
86
86
  end
87
87
 
88
88
  def on_test_run_finished(_event)
89
- @io.write(MultiJson.dump(@feature_hashes, pretty: true))
89
+ @io.write(JSON.generate(@feature_hashes, pretty: true))
90
90
  end
91
91
 
92
92
  def attach(src, mime_type)
@@ -1,246 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'base64'
4
3
  require 'cucumber/formatter/io'
5
- require 'cucumber/formatter/backtrace_filter'
6
- require 'cucumber/formatter/query/hook_by_test_step'
7
- require 'cucumber/formatter/query/pickle_by_test'
8
- require 'cucumber/formatter/query/pickle_step_by_test_step'
9
- require 'cucumber/formatter/query/step_definitions_by_test_step'
10
- require 'cucumber/formatter/query/test_case_started_by_test_case'
4
+ require 'cucumber/formatter/message_builder'
11
5
 
12
6
  module Cucumber
13
7
  module Formatter
14
8
  # The formatter used for <tt>--format message</tt>
15
- class Message
9
+ class Message < MessageBuilder
16
10
  include Io
17
- include Cucumber::Messages::TimeConversion
18
11
 
19
12
  def initialize(config)
20
- @config = config
21
- @hook_by_test_step = Query::HookByTestStep.new(config)
22
- @pickle_by_test = Query::PickleByTest.new(config)
23
- @pickle_step_by_test_step = Query::PickleStepByTestStep.new(config)
24
- @step_definitions_by_test_step = Query::StepDefinitionsByTestStep.new(config)
25
- @test_case_started_by_test_case = Query::TestCaseStartedByTestCase.new(config)
26
-
27
13
  @io = ensure_io(config.out_stream)
28
- config.on_event :envelope, &method(:on_envelope)
29
- config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
30
- config.on_event :test_case_ready, &method(:on_test_case_ready)
31
- config.on_event :test_run_started, &method(:on_test_run_started)
32
- config.on_event :test_case_started, &method(:on_test_case_started)
33
- config.on_event :test_step_started, &method(:on_test_step_started)
34
- config.on_event :test_step_finished, &method(:on_test_step_finished)
35
- config.on_event :test_case_finished, &method(:on_test_case_finished)
36
- config.on_event :test_run_finished, &method(:on_test_run_finished)
37
-
38
- @test_case_by_step_id = {}
39
- @current_test_case_started_id = nil
40
- @current_test_step_id = nil
41
- end
42
-
43
- def attach(src, media_type)
44
- attachment_data = {
45
- test_step_id: @current_test_step_id,
46
- test_case_started_id: @current_test_case_started_id,
47
- media_type: media_type
48
- }
49
-
50
- if media_type.start_with?('text/')
51
- attachment_data[:text] = src
52
- elsif src.respond_to? :read
53
- attachment_data[:binary] = Base64.encode64(src.read)
54
- else
55
- attachment_data[:binary] = Base64.encode64(src)
56
- end
57
-
58
- message = Cucumber::Messages::Envelope.new(
59
- attachment: Cucumber::Messages::Attachment.new(**attachment_data)
60
- )
61
-
62
- output_envelope(message)
14
+ super(config)
63
15
  end
64
16
 
65
- private
66
-
67
17
  def output_envelope(envelope)
68
18
  envelope.write_ndjson_to(@io)
69
19
  end
70
-
71
- def on_envelope(event)
72
- output_envelope(event.envelope)
73
- end
74
-
75
- def on_gherkin_source_read(event)
76
- message = Cucumber::Messages::Envelope.new(
77
- source: Cucumber::Messages::Source.new(
78
- uri: event.path,
79
- data: event.body,
80
- media_type: 'text/x.cucumber.gherkin+plain'
81
- )
82
- )
83
-
84
- output_envelope(message)
85
- end
86
-
87
- def on_test_case_ready(event)
88
- event.test_case.test_steps.each do |step|
89
- @test_case_by_step_id[step.id] = event.test_case
90
- end
91
-
92
- message = Cucumber::Messages::Envelope.new(
93
- test_case: Cucumber::Messages::TestCase.new(
94
- id: event.test_case.id,
95
- pickle_id: @pickle_by_test.pickle_id(event.test_case),
96
- test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) }
97
- )
98
- )
99
-
100
- output_envelope(message)
101
- end
102
-
103
- def test_step_to_message(step)
104
- return hook_step_to_message(step) if step.hook?
105
-
106
- Cucumber::Messages::TestCase::TestStep.new(
107
- id: step.id,
108
- pickle_step_id: @pickle_step_by_test_step.pickle_step_id(step),
109
- step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
110
- step_match_arguments_lists: step_match_arguments_lists(step)
111
- )
112
- end
113
-
114
- def hook_step_to_message(step)
115
- Cucumber::Messages::TestCase::TestStep.new(
116
- id: step.id,
117
- hook_id: @hook_by_test_step.hook_id(step)
118
- )
119
- end
120
-
121
- def step_match_arguments_lists(step)
122
- match_arguments = step_match_arguments(step)
123
- [Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList.new(
124
- step_match_arguments: match_arguments
125
- )]
126
- rescue Cucumber::Formatter::TestStepUnknownError
127
- []
128
- end
129
-
130
- def step_match_arguments(step)
131
- @step_definitions_by_test_step.step_match_arguments(step).map do |argument|
132
- Cucumber::Messages::StepMatchArgument.new(
133
- group: argument_group_to_message(argument.group),
134
- parameter_type_name: argument.parameter_type.name
135
- )
136
- end
137
- end
138
-
139
- def argument_group_to_message(group)
140
- Cucumber::Messages::StepMatchArgument::Group.new(
141
- start: group.start,
142
- value: group.value,
143
- children: group.children.map { |child| argument_group_to_message(child) }
144
- )
145
- end
146
-
147
- def on_test_run_started(*)
148
- message = Cucumber::Messages::Envelope.new(
149
- test_run_started: Cucumber::Messages::TestRunStarted.new(
150
- timestamp: time_to_timestamp(Time.now)
151
- )
152
- )
153
-
154
- output_envelope(message)
155
- end
156
-
157
- def on_test_case_started(event)
158
- @current_test_case_started_id = test_case_started_id(event.test_case)
159
-
160
- message = Cucumber::Messages::Envelope.new(
161
- test_case_started: Cucumber::Messages::TestCaseStarted.new(
162
- id: test_case_started_id(event.test_case),
163
- test_case_id: event.test_case.id,
164
- timestamp: time_to_timestamp(Time.now),
165
- attempt: @test_case_started_by_test_case.attempt_by_test_case(event.test_case)
166
- )
167
- )
168
-
169
- output_envelope(message)
170
- end
171
-
172
- def on_test_step_started(event)
173
- @current_test_step_id = event.test_step.id
174
- test_case = @test_case_by_step_id[event.test_step.id]
175
-
176
- message = Cucumber::Messages::Envelope.new(
177
- test_step_started: Cucumber::Messages::TestStepStarted.new(
178
- test_step_id: event.test_step.id,
179
- test_case_started_id: test_case_started_id(test_case),
180
- timestamp: time_to_timestamp(Time.now)
181
- )
182
- )
183
-
184
- output_envelope(message)
185
- end
186
-
187
- def on_test_step_finished(event)
188
- test_case = @test_case_by_step_id[event.test_step.id]
189
- result = event
190
- .result
191
- .with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
192
-
193
- result_message = result.to_message
194
- if result.failed? || result.pending?
195
- result_message = Cucumber::Messages::TestStepResult.new(
196
- status: result_message.status,
197
- duration: result_message.duration,
198
- message: create_error_message(result)
199
- )
200
- end
201
-
202
- message = Cucumber::Messages::Envelope.new(
203
- test_step_finished: Cucumber::Messages::TestStepFinished.new(
204
- test_step_id: event.test_step.id,
205
- test_case_started_id: test_case_started_id(test_case),
206
- test_step_result: result_message,
207
- timestamp: time_to_timestamp(Time.now)
208
- )
209
- )
210
-
211
- output_envelope(message)
212
- end
213
-
214
- def create_error_message(result)
215
- message_element = result.failed? ? result.exception : result
216
- message = "#{message_element.message} (#{message_element.class})"
217
- ([message] + message_element.backtrace).join("\n")
218
- end
219
-
220
- def on_test_case_finished(event)
221
- message = Cucumber::Messages::Envelope.new(
222
- test_case_finished: Cucumber::Messages::TestCaseFinished.new(
223
- test_case_started_id: test_case_started_id(event.test_case),
224
- timestamp: time_to_timestamp(Time.now)
225
- )
226
- )
227
-
228
- output_envelope(message)
229
- end
230
-
231
- def on_test_run_finished(*)
232
- message = Cucumber::Messages::Envelope.new(
233
- test_run_finished: Cucumber::Messages::TestRunFinished.new(
234
- timestamp: time_to_timestamp(Time.now)
235
- )
236
- )
237
-
238
- output_envelope(message)
239
- end
240
-
241
- def test_case_started_id(test_case)
242
- @test_case_started_by_test_case.test_case_started_id_by_test_case(test_case)
243
- end
244
20
  end
245
21
  end
246
22
  end
@@ -0,0 +1,241 @@
1
+ require 'base64'
2
+ require 'cucumber/formatter/backtrace_filter'
3
+ require 'cucumber/formatter/query/hook_by_test_step'
4
+ require 'cucumber/formatter/query/pickle_by_test'
5
+ require 'cucumber/formatter/query/pickle_step_by_test_step'
6
+ require 'cucumber/formatter/query/step_definitions_by_test_step'
7
+ require 'cucumber/formatter/query/test_case_started_by_test_case'
8
+
9
+ module Cucumber
10
+ module Formatter
11
+ class MessageBuilder
12
+ include Cucumber::Messages::TimeConversion
13
+
14
+ def initialize(config)
15
+ @config = config
16
+
17
+ @hook_by_test_step = Query::HookByTestStep.new(config)
18
+ @pickle_by_test = Query::PickleByTest.new(config)
19
+ @pickle_step_by_test_step = Query::PickleStepByTestStep.new(config)
20
+ @step_definitions_by_test_step = Query::StepDefinitionsByTestStep.new(config)
21
+ @test_case_started_by_test_case = Query::TestCaseStartedByTestCase.new(config)
22
+
23
+ config.on_event :envelope, &method(:on_envelope)
24
+ config.on_event :gherkin_source_read, &method(:on_gherkin_source_read)
25
+ config.on_event :test_case_ready, &method(:on_test_case_ready)
26
+ config.on_event :test_run_started, &method(:on_test_run_started)
27
+ config.on_event :test_case_started, &method(:on_test_case_started)
28
+ config.on_event :test_step_started, &method(:on_test_step_started)
29
+ config.on_event :test_step_finished, &method(:on_test_step_finished)
30
+ config.on_event :test_case_finished, &method(:on_test_case_finished)
31
+ config.on_event :test_run_finished, &method(:on_test_run_finished)
32
+
33
+ @test_case_by_step_id = {}
34
+ @current_test_case_started_id = nil
35
+ @current_test_step_id = nil
36
+ end
37
+
38
+ def output_message
39
+ raise 'To be implemented'
40
+ end
41
+
42
+ def attach(src, media_type)
43
+ attachment_data = {
44
+ test_step_id: @current_test_step_id,
45
+ test_case_started_id: @current_test_case_started_id,
46
+ media_type: media_type
47
+ }
48
+
49
+ if media_type.start_with?('text/')
50
+ attachment_data[:text] = src
51
+ elsif src.respond_to? :read
52
+ attachment_data[:binary] = Base64.encode64(src.read)
53
+ else
54
+ attachment_data[:binary] = Base64.encode64(src)
55
+ end
56
+
57
+ message = Cucumber::Messages::Envelope.new(
58
+ attachment: Cucumber::Messages::Attachment.new(**attachment_data)
59
+ )
60
+
61
+ output_envelope(message)
62
+ end
63
+
64
+ private
65
+
66
+ def on_envelope(event)
67
+ output_envelope(event.envelope)
68
+ end
69
+
70
+ def on_gherkin_source_read(event)
71
+ message = Cucumber::Messages::Envelope.new(
72
+ source: Cucumber::Messages::Source.new(
73
+ uri: event.path,
74
+ data: event.body,
75
+ media_type: 'text/x.cucumber.gherkin+plain'
76
+ )
77
+ )
78
+
79
+ output_envelope(message)
80
+ end
81
+
82
+ def on_test_case_ready(event)
83
+ event.test_case.test_steps.each do |step|
84
+ @test_case_by_step_id[step.id] = event.test_case
85
+ end
86
+
87
+ message = Cucumber::Messages::Envelope.new(
88
+ test_case: Cucumber::Messages::TestCase.new(
89
+ id: event.test_case.id,
90
+ pickle_id: @pickle_by_test.pickle_id(event.test_case),
91
+ test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) }
92
+ )
93
+ )
94
+
95
+ output_envelope(message)
96
+ end
97
+
98
+ def test_step_to_message(step)
99
+ return hook_step_to_message(step) if step.hook?
100
+
101
+ Cucumber::Messages::TestCase::TestStep.new(
102
+ id: step.id,
103
+ pickle_step_id: @pickle_step_by_test_step.pickle_step_id(step),
104
+ step_definition_ids: @step_definitions_by_test_step.step_definition_ids(step),
105
+ step_match_arguments_lists: step_match_arguments_lists(step)
106
+ )
107
+ end
108
+
109
+ def hook_step_to_message(step)
110
+ Cucumber::Messages::TestCase::TestStep.new(
111
+ id: step.id,
112
+ hook_id: @hook_by_test_step.hook_id(step)
113
+ )
114
+ end
115
+
116
+ def step_match_arguments_lists(step)
117
+ match_arguments = step_match_arguments(step)
118
+ [Cucumber::Messages::TestCase::TestStep::StepMatchArgumentsList.new(
119
+ step_match_arguments: match_arguments
120
+ )]
121
+ rescue Cucumber::Formatter::TestStepUnknownError
122
+ []
123
+ end
124
+
125
+ def step_match_arguments(step)
126
+ @step_definitions_by_test_step.step_match_arguments(step).map do |argument|
127
+ Cucumber::Messages::StepMatchArgument.new(
128
+ group: argument_group_to_message(argument.group),
129
+ parameter_type_name: argument.parameter_type.name
130
+ )
131
+ end
132
+ end
133
+
134
+ def argument_group_to_message(group)
135
+ Cucumber::Messages::StepMatchArgument::Group.new(
136
+ start: group.start,
137
+ value: group.value,
138
+ children: group.children.map { |child| argument_group_to_message(child) }
139
+ )
140
+ end
141
+
142
+ def on_test_run_started(*)
143
+ message = Cucumber::Messages::Envelope.new(
144
+ test_run_started: Cucumber::Messages::TestRunStarted.new(
145
+ timestamp: time_to_timestamp(Time.now)
146
+ )
147
+ )
148
+
149
+ output_envelope(message)
150
+ end
151
+
152
+ def on_test_case_started(event)
153
+ @current_test_case_started_id = test_case_started_id(event.test_case)
154
+
155
+ message = Cucumber::Messages::Envelope.new(
156
+ test_case_started: Cucumber::Messages::TestCaseStarted.new(
157
+ id: test_case_started_id(event.test_case),
158
+ test_case_id: event.test_case.id,
159
+ timestamp: time_to_timestamp(Time.now),
160
+ attempt: @test_case_started_by_test_case.attempt_by_test_case(event.test_case)
161
+ )
162
+ )
163
+
164
+ output_envelope(message)
165
+ end
166
+
167
+ def on_test_step_started(event)
168
+ @current_test_step_id = event.test_step.id
169
+ test_case = @test_case_by_step_id[event.test_step.id]
170
+
171
+ message = Cucumber::Messages::Envelope.new(
172
+ test_step_started: Cucumber::Messages::TestStepStarted.new(
173
+ test_step_id: event.test_step.id,
174
+ test_case_started_id: test_case_started_id(test_case),
175
+ timestamp: time_to_timestamp(Time.now)
176
+ )
177
+ )
178
+
179
+ output_envelope(message)
180
+ end
181
+
182
+ def on_test_step_finished(event)
183
+ test_case = @test_case_by_step_id[event.test_step.id]
184
+ result = event
185
+ .result
186
+ .with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter)
187
+
188
+ result_message = result.to_message
189
+ if result.failed? || result.pending?
190
+ result_message = Cucumber::Messages::TestStepResult.new(
191
+ status: result_message.status,
192
+ duration: result_message.duration,
193
+ message: create_error_message(result)
194
+ )
195
+ end
196
+
197
+ message = Cucumber::Messages::Envelope.new(
198
+ test_step_finished: Cucumber::Messages::TestStepFinished.new(
199
+ test_step_id: event.test_step.id,
200
+ test_case_started_id: test_case_started_id(test_case),
201
+ test_step_result: result_message,
202
+ timestamp: time_to_timestamp(Time.now)
203
+ )
204
+ )
205
+
206
+ output_envelope(message)
207
+ end
208
+
209
+ def create_error_message(result)
210
+ message_element = result.failed? ? result.exception : result
211
+ message = "#{message_element.message} (#{message_element.class})"
212
+ ([message] + message_element.backtrace).join("\n")
213
+ end
214
+
215
+ def on_test_case_finished(event)
216
+ message = Cucumber::Messages::Envelope.new(
217
+ test_case_finished: Cucumber::Messages::TestCaseFinished.new(
218
+ test_case_started_id: test_case_started_id(event.test_case),
219
+ timestamp: time_to_timestamp(Time.now)
220
+ )
221
+ )
222
+
223
+ output_envelope(message)
224
+ end
225
+
226
+ def on_test_run_finished(*)
227
+ message = Cucumber::Messages::Envelope.new(
228
+ test_run_finished: Cucumber::Messages::TestRunFinished.new(
229
+ timestamp: time_to_timestamp(Time.now)
230
+ )
231
+ )
232
+
233
+ output_envelope(message)
234
+ end
235
+
236
+ def test_case_started_id(test_case)
237
+ @test_case_started_by_test_case.test_case_started_id_by_test_case(test_case)
238
+ end
239
+ end
240
+ end
241
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
- require 'multi_json'
5
4
  require 'cucumber/configuration'
6
5
  require 'cucumber/load_path'
7
6
  require 'cucumber/formatter/duration'
@@ -1 +1 @@
1
- 4.0.0.rc.4
1
+ 4.0.0.rc.5
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.rc.4
4
+ version: 4.0.0.rc.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aslak Hellesøy
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-02-24 00:00:00.000000000 Z
13
+ date: 2020-03-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: builder
@@ -93,65 +93,65 @@ dependencies:
93
93
  - !ruby/object:Gem::Version
94
94
  version: '10.0'
95
95
  - !ruby/object:Gem::Dependency
96
- name: cucumber-wire
96
+ name: cucumber-html-formatter
97
97
  requirement: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - ">="
100
100
  - !ruby/object:Gem::Version
101
- version: 2.0.0
101
+ version: 4.3.0
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '2.0'
104
+ version: '4.3'
105
105
  type: :runtime
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: 2.0.0
111
+ version: 4.3.0
112
112
  - - "~>"
113
113
  - !ruby/object:Gem::Version
114
- version: '2.0'
114
+ version: '4.3'
115
115
  - !ruby/object:Gem::Dependency
116
- name: diff-lcs
116
+ name: cucumber-wire
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - ">="
120
120
  - !ruby/object:Gem::Version
121
- version: '1.3'
121
+ version: 2.0.0
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '1.3'
124
+ version: '2.0'
125
125
  type: :runtime
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
130
130
  - !ruby/object:Gem::Version
131
- version: '1.3'
131
+ version: 2.0.0
132
132
  - - "~>"
133
133
  - !ruby/object:Gem::Version
134
- version: '1.3'
134
+ version: '2.0'
135
135
  - !ruby/object:Gem::Dependency
136
- name: multi_json
136
+ name: diff-lcs
137
137
  requirement: !ruby/object:Gem::Requirement
138
138
  requirements:
139
- - - "~>"
140
- - !ruby/object:Gem::Version
141
- version: '1.13'
142
139
  - - ">="
143
140
  - !ruby/object:Gem::Version
144
- version: 1.13.1
141
+ version: '1.3'
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '1.3'
145
145
  type: :runtime
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '1.13'
152
149
  - - ">="
153
150
  - !ruby/object:Gem::Version
154
- version: 1.13.1
151
+ version: '1.3'
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: '1.3'
155
155
  - !ruby/object:Gem::Dependency
156
156
  name: multi_test
157
157
  requirement: !ruby/object:Gem::Requirement
@@ -176,42 +176,22 @@ dependencies:
176
176
  name: aruba
177
177
  requirement: !ruby/object:Gem::Requirement
178
178
  requirements:
179
- - - "~>"
180
- - !ruby/object:Gem::Version
181
- version: '0.14'
182
179
  - - ">="
183
180
  - !ruby/object:Gem::Version
184
- version: 0.14.11
185
- type: :development
186
- prerelease: false
187
- version_requirements: !ruby/object:Gem::Requirement
188
- requirements:
181
+ version: 1.0.0
189
182
  - - "~>"
190
183
  - !ruby/object:Gem::Version
191
- version: '0.14'
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: 0.14.11
195
- - !ruby/object:Gem::Dependency
196
- name: json
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ">="
200
- - !ruby/object:Gem::Version
201
- version: 2.2.0
202
- - - "~>"
203
- - !ruby/object:Gem::Version
204
- version: '2.2'
184
+ version: '1.0'
205
185
  type: :development
206
186
  prerelease: false
207
187
  version_requirements: !ruby/object:Gem::Requirement
208
188
  requirements:
209
189
  - - ">="
210
190
  - !ruby/object:Gem::Version
211
- version: 2.2.0
191
+ version: 1.0.0
212
192
  - - "~>"
213
193
  - !ruby/object:Gem::Version
214
- version: '2.2'
194
+ version: '1.0'
215
195
  - !ruby/object:Gem::Dependency
216
196
  name: nokogiri
217
197
  requirement: !ruby/object:Gem::Requirement
@@ -292,26 +272,6 @@ dependencies:
292
272
  - - "~>"
293
273
  - !ruby/object:Gem::Version
294
274
  version: '3.8'
295
- - !ruby/object:Gem::Dependency
296
- name: rubocop
297
- requirement: !ruby/object:Gem::Requirement
298
- requirements:
299
- - - "~>"
300
- - !ruby/object:Gem::Version
301
- version: '0.75'
302
- - - '='
303
- - !ruby/object:Gem::Version
304
- version: 0.75.1
305
- type: :development
306
- prerelease: false
307
- version_requirements: !ruby/object:Gem::Requirement
308
- requirements:
309
- - - "~>"
310
- - !ruby/object:Gem::Version
311
- version: '0.75'
312
- - - '='
313
- - !ruby/object:Gem::Version
314
- version: 0.75.1
315
275
  - !ruby/object:Gem::Dependency
316
276
  name: simplecov
317
277
  requirement: !ruby/object:Gem::Requirement
@@ -372,6 +332,26 @@ dependencies:
372
332
  - - ">="
373
333
  - !ruby/object:Gem::Version
374
334
  version: 1.2.3
335
+ - !ruby/object:Gem::Dependency
336
+ name: webrick
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ">="
340
+ - !ruby/object:Gem::Version
341
+ version: 1.6.0
342
+ - - "~>"
343
+ - !ruby/object:Gem::Version
344
+ version: '1.6'
345
+ type: :development
346
+ prerelease: false
347
+ version_requirements: !ruby/object:Gem::Requirement
348
+ requirements:
349
+ - - ">="
350
+ - !ruby/object:Gem::Version
351
+ version: 1.6.0
352
+ - - "~>"
353
+ - !ruby/object:Gem::Version
354
+ version: '1.6'
375
355
  - !ruby/object:Gem::Dependency
376
356
  name: octokit
377
357
  requirement: !ruby/object:Gem::Requirement
@@ -522,12 +502,15 @@ files:
522
502
  - lib/cucumber/formatter/errors.rb
523
503
  - lib/cucumber/formatter/fail_fast.rb
524
504
  - lib/cucumber/formatter/fanout.rb
505
+ - lib/cucumber/formatter/html.rb
506
+ - lib/cucumber/formatter/http_io.rb
525
507
  - lib/cucumber/formatter/ignore_missing_messages.rb
526
508
  - lib/cucumber/formatter/interceptor.rb
527
509
  - lib/cucumber/formatter/io.rb
528
510
  - lib/cucumber/formatter/json.rb
529
511
  - lib/cucumber/formatter/junit.rb
530
512
  - lib/cucumber/formatter/message.rb
513
+ - lib/cucumber/formatter/message_builder.rb
531
514
  - lib/cucumber/formatter/pretty.rb
532
515
  - lib/cucumber/formatter/progress.rb
533
516
  - lib/cucumber/formatter/query/hook_by_test_step.rb
@@ -609,5 +592,5 @@ requirements: []
609
592
  rubygems_version: 3.0.6
610
593
  signing_key:
611
594
  specification_version: 4
612
- summary: cucumber-4.0.0.rc.4
595
+ summary: cucumber-4.0.0.rc.5
613
596
  test_files: []