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

Sign up to get free protection for your applications and to get access to all the features.
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: []