allure-ruby-commons 2.28.0 → 2.32.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 533f85dbee5b72bf9be4050285a6aff7e9fc5dfecd9554276baf60cda7f818dc
4
- data.tar.gz: 245337c54947f7e8a324e22246b6c7b563e168a97e293af86bd0fae8ebb6434a
3
+ metadata.gz: 158481dc0f3a21a190859fa2ed209bc93dc94185393c9c6767a83481c01e1dac
4
+ data.tar.gz: 94f52c299af1494c6e6c372f562a196ba7c9000cb489f9b7effea335c2f8e9e7
5
5
  SHA512:
6
- metadata.gz: 2a3f39061b901d5c9af4e191d8dd5e6fd2ec4f7fe057d8a404acc541de548b555cc6ab0dc38e2636ced1a44de28be64fedb7e0a1a9652271d41dac053c66fc25
7
- data.tar.gz: f2e7f57499e365993a9e6a052a34910e24d387d8dc31a5ac85b26e0647097a3312f55ce4fcaaa73a639f672f045c77025bf45496d846ff01ddb035ee7d8e091b
6
+ metadata.gz: db735212d318744aa39642149273e407104a7cb3d881590fbf12cc478431053ede8eb9ff5e56e01560ade8bf9d585a953d188aa39a7bdb2453b89f00340e50b5
7
+ data.tar.gz: 3d80679f0439e64299f62948621db0931ddbc34125e59c47722d2891468ca4810c00f58df0422772857d0a9a13acbe8dd2bb72cadd70aa118a591ff2495b921a
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # Allure Ruby Adaptor API
1
+ # Allure Ruby adapter API
2
2
 
3
3
  [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/allure-ruby-commons)
4
4
 
5
- This is a helper library containing the basics for any ruby-based Allure adaptor.
6
- Using it you can easily implement the adaptor for your favorite ruby testing library or
5
+ This is a helper library containing the basics for any ruby-based Allure adapter.
6
+ Using it you can easily implement the adapter for your favorite ruby testing library or
7
7
  you can just create the report of any other kind using the basic Allure terms.
8
8
 
9
9
  ## Setup
@@ -26,6 +26,12 @@ Following configuration options are supported:
26
26
  config.logger = Logger.new($stdout, Logger::DEBUG)
27
27
  config.environment = "staging"
28
28
 
29
+ # labels added to every test result
30
+ config.global_labels = [
31
+ { name: "owner", value: "qa" },
32
+ { name: "tag", value: "global" }
33
+ ]
34
+
29
35
  # these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
30
36
  config.link_tms_pattern = "http://www.jira.com/browse/{}"
31
37
  config.link_issue_pattern = "http://www.jira.com/browse/{}"
@@ -40,6 +46,9 @@ Following configuration options are supported:
40
46
  end
41
47
  ```
42
48
 
49
+ `global_labels` defaults to `[]`. Each entry is a hash with symbol keys `:name` and `:value`.
50
+ Labels are prepended to every completed test's labels without replacing test-specific labels, including those with the same name.
51
+
43
52
  Getting the configuration object:
44
53
 
45
54
  ```ruby
@@ -2,11 +2,12 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "require_all"
5
+ require "digest"
5
6
  require "securerandom"
6
7
 
7
8
  require_rel "allure_ruby_commons/**/*rb"
8
9
 
9
- # Namespace for classes that handle allure report generation and different framework adaptors
10
+ # Namespace for classes that handle allure report generation and different framework adapters
10
11
  module Allure
11
12
  # Set lifecycle object
12
13
  # @param [AllureLifecycle] lifecycle
@@ -161,6 +162,27 @@ module Allure
161
162
  lifecycle.add_attachment(name: name, source: source, type: type, test_case: test_case)
162
163
  end
163
164
 
165
+ # Add run-level attachment not bound to a test or fixture
166
+ # @param [String] name Attachment name
167
+ # @param [File, String] source File or string to save as attachment
168
+ # @param [String] type attachment type defined in {ContentType} or any other valid mime type
169
+ # @return [void]
170
+ def add_global_attachment(name:, source:, type:)
171
+ lifecycle.add_global_attachment(name: name, source: source, type: type)
172
+ end
173
+
174
+ # Add run-level error not bound to a test or fixture
175
+ # @param [Hash] details
176
+ # @option details [Boolean] :known
177
+ # @option details [Boolean] :muted
178
+ # @option details [Boolean] :flaky
179
+ # @option details [String] :message
180
+ # @option details [String] :trace
181
+ # @return [void]
182
+ def add_global_error(**details)
183
+ lifecycle.add_global_error(**details)
184
+ end
185
+
164
186
  # Manually create environment.properties file
165
187
  # if this method is called before test run started and
166
188
  # option clean_results_directory is enabled, the file will be deleted
@@ -14,6 +14,7 @@ module Allure
14
14
  def initialize(config = Config.instance)
15
15
  @test_context = []
16
16
  @step_context = []
17
+ @globals = Globals.new
17
18
  @config = config
18
19
  @logger = config.logger
19
20
  end
@@ -102,6 +103,7 @@ module Allure
102
103
  logger.debug { "Stopping test case: #{@current_test_case.name}" }
103
104
  @current_test_case.stop = ResultUtils.timestamp
104
105
  @current_test_case.stage = Stage::FINISHED
106
+ @current_test_case.labels.unshift(*global_labels)
105
107
  file_writer.write_test_result(@current_test_case)
106
108
  clear_current_test_case
107
109
  clear_step_context
@@ -220,6 +222,35 @@ module Allure
220
222
  write_attachment(source, attachment)
221
223
  end
222
224
 
225
+ # Add run-level attachment
226
+ # @param [String] name Attachment name
227
+ # @param [File, String] source File or string to save as attachment
228
+ # @param [String] type attachment type defined in {Allure::ContentType} or any other valid mime type
229
+ # @return [void]
230
+ def add_global_attachment(name:, source:, type:)
231
+ attachment = ResultUtils.prepare_global_attachment(name, type, timestamp: ResultUtils.timestamp)
232
+ return logger.error { "Can't add global attachment, unrecognized mime type: #{type}" } unless attachment
233
+
234
+ logger.debug { "Adding global attachment '#{name}'" }
235
+ write_attachment(source, attachment)
236
+ @globals.add_attachment(attachment)
237
+ end
238
+
239
+ # Add run-level error
240
+ # @param [Hash] details
241
+ # @option details [Boolean] :known
242
+ # @option details [Boolean] :muted
243
+ # @option details [Boolean] :flaky
244
+ # @option details [String] :message
245
+ # @option details [String] :trace
246
+ # @return [void]
247
+ def add_global_error(**details)
248
+ error = ResultUtils.prepare_global_error(timestamp: ResultUtils.timestamp, **details)
249
+
250
+ logger.debug { "Adding global error '#{error.message}'" }
251
+ @globals.add_error(error)
252
+ end
253
+
223
254
  # Add environment.properties file
224
255
  #
225
256
  # @param [Hash, Proc] env
@@ -241,6 +272,12 @@ module Allure
241
272
  file_writer.write_categories(categories)
242
273
  end
243
274
 
275
+ # Write global errors and attachments
276
+ # @return [void]
277
+ def write_globals
278
+ file_writer.write_globals(@globals)
279
+ end
280
+
244
281
  # Add step to current fixture|step|test case
245
282
  # @param [Allure::StepResult] step_result
246
283
  # @return [Allure::StepResult]
@@ -260,6 +297,10 @@ module Allure
260
297
 
261
298
  attr_reader :logger
262
299
 
300
+ def global_labels
301
+ @global_labels ||= config.global_labels.map { |label| Label.new(label[:name], label[:value]) }
302
+ end
303
+
263
304
  def file_writer
264
305
  @file_writer ||= FileWriter.new(config.results_directory)
265
306
  end
@@ -20,10 +20,12 @@ module Allure
20
20
  :link_issue_pattern,
21
21
  :clean_results_directory,
22
22
  :environment_properties,
23
- :categories
23
+ :categories,
24
+ :global_labels
24
25
 
25
26
  def initialize
26
27
  @results_directory = "reports/allure-results"
28
+ @global_labels = []
27
29
  @logging_level = LOGLEVELS.index(ENV.fetch("ALLURE_LOG_LEVEL", "INFO")) || Logger::INFO
28
30
  end
29
31
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "tempfile"
4
+
3
5
  module Allure
4
6
  # Allure result file writer
5
7
  class FileWriter
@@ -11,6 +13,8 @@ module Allure
11
13
  TEST_RESULT_CONTAINER_SUFFIX = "-container.json"
12
14
  # @return [String] attachment file suffix
13
15
  ATTACHMENT_FILE_SUFFIX = "-attachment"
16
+ # @return [String] globals chunk suffix
17
+ GLOBALS_SUFFIX = "-globals.json"
14
18
  # @return [String] environment info file
15
19
  ENVIRONMENT_FILE = "environment.properties"
16
20
  # @return [String] categories definition json
@@ -45,6 +49,13 @@ module Allure
45
49
  source.is_a?(File) ? copy(source.path, attachment.source) : write(attachment.source, source)
46
50
  end
47
51
 
52
+ # Write allure globals chunk
53
+ # @param [Allure::Globals] globals
54
+ # @return [void]
55
+ def write_globals(globals)
56
+ write("#{SecureRandom.uuid}#{GLOBALS_SUFFIX}", dump_json(globals))
57
+ end
58
+
48
59
  # Write allure report environment info
49
60
  # @param [Hash<Symbol, String>] environment
50
61
  # @return [void]
@@ -74,12 +85,30 @@ module Allure
74
85
  end
75
86
 
76
87
  def write(name, source)
77
- filename = File.join(output_dir, name)
78
- File.write(filename, source)
88
+ atomic_write(name) { |temp_file| temp_file.write(source) }
79
89
  end
80
90
 
81
91
  def copy(from, to)
82
- FileUtils.cp(from, File.join(output_dir, to))
92
+ atomic_write(to) { |temp_file| IO.copy_stream(from, temp_file) }
93
+ end
94
+
95
+ def atomic_write(name)
96
+ filename = File.join(output_dir, name)
97
+ target_mode = begin
98
+ File.stat(filename).mode
99
+ rescue Errno::ENOENT
100
+ 0o644
101
+ end
102
+
103
+ Tempfile.create("#{name}.tmp", output_dir) do |temp_file|
104
+ temp_file.binmode
105
+
106
+ yield temp_file
107
+
108
+ temp_file.chmod(target_mode)
109
+ temp_file.close
110
+ File.rename(temp_file.path, filename)
111
+ end
83
112
  end
84
113
  end
85
114
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Allure
4
+ # Allure model global attachment object
5
+ class GlobalAttachment < Attachment
6
+ # @param [Number] timestamp
7
+ # @param [Hash] options
8
+ # @option options [String] :name attachment name
9
+ # @option options [String] :type attachment type, {Allure::ContentType}
10
+ # @option options [String] :source attachment file name
11
+ def initialize(timestamp:, **options)
12
+ super(**options)
13
+
14
+ @timestamp = timestamp
15
+ end
16
+
17
+ attr_accessor :timestamp
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "status_details"
4
+
5
+ module Allure
6
+ # Allure model global error object
7
+ class GlobalError < StatusDetails
8
+ # @param [Number] timestamp
9
+ # @param [Hash] options
10
+ # @option options [Boolean] :known
11
+ # @option options [Boolean] :muted
12
+ # @option options [Boolean] :flaky
13
+ # @option options [String] :message
14
+ # @option options [String] :trace
15
+ def initialize(timestamp:, status: nil, **options)
16
+ super(**options)
17
+
18
+ @status = status
19
+ @timestamp = timestamp
20
+ end
21
+
22
+ attr_accessor :timestamp, :status
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Allure
4
+ # Allure model run-level globals chunk
5
+ class Globals < JSONable
6
+ # @param [Array<Allure::GlobalAttachment>] attachments
7
+ # @param [Array<Allure::GlobalError>] errors
8
+ def initialize(attachments: [], errors: [])
9
+ super()
10
+
11
+ @attachments = attachments
12
+ @errors = errors
13
+ end
14
+
15
+ attr_accessor :attachments, :errors
16
+
17
+ # Add an error to the globals
18
+ # @param [Allure::GlobalError] error
19
+ # @return [void]
20
+ def add_error(error)
21
+ @errors.push(error)
22
+ end
23
+
24
+ # Add an attachment to the globals
25
+ # @param [Allure::GlobalAttachment] attachment
26
+ # @return [void]
27
+ def add_attachment(attachment)
28
+ @attachments.push(attachment)
29
+ end
30
+ end
31
+ end
@@ -9,6 +9,7 @@ module Allure
9
9
  # @param [Hash] options
10
10
  # @option options [String] :name
11
11
  # @option options [String] :full_name
12
+ # @option options [Array<String>] :title_path
12
13
  # @option options [String] :description
13
14
  # @option options [String] :description_html
14
15
  # @option options [String] :status ('broken')
@@ -26,6 +27,7 @@ module Allure
26
27
  @uuid = uuid
27
28
  @history_id = history_id
28
29
  @full_name = options[:full_name] || "Unnamed"
30
+ @title_path = options[:title_path]
29
31
  @labels = options[:labels] || []
30
32
  @links = options[:links] || []
31
33
  @parameters << Parameter.new("environment", environment) if environment
@@ -33,6 +35,7 @@ module Allure
33
35
 
34
36
  attr_accessor :uuid,
35
37
  :full_name,
38
+ :title_path,
36
39
  :labels,
37
40
  :links
38
41
 
@@ -157,9 +157,13 @@ module Allure
157
157
 
158
158
  # Get exception status detail
159
159
  # @param [Exception] exception
160
+ # @param [Hash] options
161
+ # @option options [Boolean] :known
162
+ # @option options [Boolean] :muted
163
+ # @option options [Boolean] :flaky
160
164
  # @return [Allure::StatusDetails]
161
- def status_details(exception)
162
- StatusDetails.new(message: exception&.message, trace: exception&.backtrace&.join("\n"))
165
+ def status_details(exception, **options)
166
+ StatusDetails.new(message: exception&.message, trace: exception&.backtrace&.join("\n"), **options)
163
167
  end
164
168
 
165
169
  # Allure attachment object
@@ -172,6 +176,38 @@ module Allure
172
176
  Attachment.new(name: name, source: file_name, type: type)
173
177
  end
174
178
 
179
+ # Allure global attachment object
180
+ # @param [String] name
181
+ # @param [String] type
182
+ # @param [Number] timestamp
183
+ # @return [Allure::GlobalAttachment]
184
+ def prepare_global_attachment(name, type, timestamp: self.timestamp)
185
+ attachment = prepare_attachment(name, type) || return
186
+
187
+ GlobalAttachment.new(
188
+ name: attachment.name,
189
+ source: attachment.source,
190
+ type: attachment.type,
191
+ timestamp: timestamp
192
+ )
193
+ end
194
+
195
+ # Allure global error object
196
+ # @param [Number] timestamp
197
+ # @param [StandardError] :exception
198
+ # @param [Hash] options
199
+ # @option options [Boolean] :known
200
+ # @option options [Boolean] :muted
201
+ # @option options [Boolean] :flaky
202
+ # @return [Allure::GlobalError]
203
+ def prepare_global_error(timestamp: self.timestamp, exception: nil, **options)
204
+ GlobalError.new(
205
+ timestamp: timestamp,
206
+ status: status(exception),
207
+ **status_details(exception, **options).to_hash.transform_keys(&:to_sym)
208
+ )
209
+ end
210
+
175
211
  private
176
212
 
177
213
  # Check if value is full url
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-ruby-commons
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.28.0
4
+ version: 2.32.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrejs Cunskis
@@ -82,6 +82,9 @@ files:
82
82
  - lib/allure_ruby_commons/model/content_type.rb
83
83
  - lib/allure_ruby_commons/model/executable_item.rb
84
84
  - lib/allure_ruby_commons/model/fixture_result.rb
85
+ - lib/allure_ruby_commons/model/global_attachment.rb
86
+ - lib/allure_ruby_commons/model/global_error.rb
87
+ - lib/allure_ruby_commons/model/globals.rb
85
88
  - lib/allure_ruby_commons/model/label.rb
86
89
  - lib/allure_ruby_commons/model/link.rb
87
90
  - lib/allure_ruby_commons/model/parameter.rb
@@ -118,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
121
  - !ruby/object:Gem::Version
119
122
  version: '0'
120
123
  requirements: []
121
- rubygems_version: 3.6.9
124
+ rubygems_version: 4.0.20
122
125
  specification_version: 4
123
126
  summary: Common library for allure results generation
124
127
  test_files: []