allure-ruby-commons 2.13.8.1 → 2.19.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: be70de370f6d6732ca70063312ccb4ffd0cf27ede2c50f53f7427ba718ce11d9
4
- data.tar.gz: 67b723e4ef1b8092f279a27a9c250a093124b8f78c93dbc34a8655afc29420bd
3
+ metadata.gz: d63128392504c90df6eccbf93a5f3f0cd39e09d0a09c0b5365fc42ee54a07d90
4
+ data.tar.gz: e70469671849de4218ed7bd79368cde5cc6d8cdd8bbe495882c13b4cb58c1212
5
5
  SHA512:
6
- metadata.gz: c10538c94a3334367b08d536db7f2449ef184201d7c5d95e02914c018ad4691b80dac94e898ee03d10e53f98741532afec30192b4e558be1ad19aeaf27324eb2
7
- data.tar.gz: dad294ed8428f5e84a514203f8515cbe7241ebab5535ceb5163c2cf83df589ba5874ad5bd8aa3f820e5e18b42e92436567c96b8d5f5f3ab2554447ef1f4915b7
6
+ metadata.gz: 79249df603728c94f5a88cfe9879410b331ec1485f2a57be91a6805f10a2fb37211a98653a2719d33c74c5994ecbaa582deac15c6edd399dfde71da9db1af48d
7
+ data.tar.gz: 3f72dfec99534df2e5b661799814d36010074fa36d2702947dfbb80084cd22180915a4a96ac9d6da3b98c1ba685d335bacd0459b43f2a3ee59f910fadc4f198d
data/README.md CHANGED
@@ -20,12 +20,23 @@ Following configuration options are supported:
20
20
 
21
21
  ```ruby
22
22
  Allure.configure do |config|
23
- config.results_directory = "/whatever/you/like"
23
+ config.results_directory = "report/allure-results"
24
24
  config.clean_results_directory = true
25
25
  config.logging_level = Logger::INFO
26
+ config.logger = Logger.new($stdout, Logger::DEBUG)
27
+ config.environment = "staging"
28
+
26
29
  # these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
27
30
  config.link_tms_pattern = "http://www.jira.com/browse/{}"
28
31
  config.link_issue_pattern = "http://www.jira.com/browse/{}"
32
+
33
+ # additional metadata
34
+ # environment.properties
35
+ config.environment_properties = {
36
+ custom_attribute: "foo"
37
+ }
38
+ # categories.json
39
+ config.categories = File.new("my_custom_categories.json")
29
40
  end
30
41
  ```
31
42
 
@@ -35,6 +46,29 @@ Getting the configuration object:
35
46
  Allure.configuration
36
47
  ```
37
48
 
49
+ ### Allure execution environment
50
+
51
+ It is possible to set up custom allure environment which will be used as custom parameter `environment` in every test case. This is useful if you run same tests on different environments and generate single report. This way different runs are not put as retry. Environment can be configured in following ways:
52
+
53
+ * via `ALLURE_ENVIRONMENT` environment variable
54
+ * via `configure` method
55
+
56
+ ### Environment properties
57
+
58
+ To add additional environment information to the report it is possible to set configuration property `environment_properties`.
59
+
60
+ Option can be set to hash or block returning a hash:
61
+
62
+ ```ruby
63
+ # hash
64
+ config.environment_properties = {
65
+ custom_attribute: "foo"
66
+ }
67
+
68
+ # lambda
69
+ config.environment_properties = -> { { custom_attributes: "foo"} }
70
+ ```
71
+
38
72
  ### Log level
39
73
 
40
74
  Log level can be also configured via environment variable `ALLURE_LOG_LEVEL` which accepts one of the following values: `DEBUG INFO WARN ERROR FATAL UNKNOWN`.
@@ -54,22 +88,19 @@ Allure.add_attachment(name: "attachment", source: "/path/to/test.txt", type: All
54
88
  Allure.add_link(name: "Custom Url", url: "http://www.github.com")
55
89
  ```
56
90
 
57
- ## Testing
58
-
59
- Install dependencies:
91
+ ## Steps
60
92
 
61
- ```bash
62
- bundle install
63
- ```
64
-
65
- Run tests:
93
+ It is possible to mark method definitions to be automatically added to report as steps. The class just needs to extend `AllureStepAnnotation`
94
+ and `step` method needs to be used before the method definition.
66
95
 
67
- ```bash
68
- bundle exec rspec
69
- ```
96
+ ```ruby
97
+ class TestHelper
98
+ extend AllureStepAnnotation
70
99
 
71
- ## Building
100
+ step("Singleton step")
101
+ def self.class_method; end
72
102
 
73
- ```bash
74
- gem build allure-ruby-commons.gemspec
103
+ step("Standard step")
104
+ def standard_method; end
105
+ end
75
106
  ```
@@ -8,178 +8,240 @@ require_rel "allure_ruby_commons/**/*rb"
8
8
 
9
9
  # Namespace for classes that handle allure report generation and different framework adaptors
10
10
  module Allure
11
- class << self
12
- # Get thread specific allure lifecycle object
13
- # @return [AllureLifecycle]
14
- def lifecycle
15
- Thread.current[:lifecycle] ||= AllureLifecycle.new
16
- end
11
+ # Set lifecycle object
12
+ # @param [AllureLifecycle] lifecycle
13
+ # @return [void]
14
+ def self.lifecycle=(lifecycle)
15
+ Thread.current[:lifecycle] = lifecycle
16
+ end
17
17
 
18
- # Set lifecycle object
19
- # @param [AllureLifecycle] lifecycle
20
- # @return [void]
21
- def lifecycle=(lifecycle)
22
- Thread.current[:lifecycle] = lifecycle
23
- end
18
+ extend self # rubocop:disable Style/ModuleFunction
24
19
 
25
- # Get allure configuration
26
- # @return [Config]
27
- def configuration
28
- Config.instance
29
- end
20
+ # Get thread specific allure lifecycle object
21
+ # @return [AllureLifecycle]
22
+ def lifecycle
23
+ Thread.current[:lifecycle] ||= AllureLifecycle.new
24
+ end
30
25
 
31
- # Set allure configuration
32
- # @yieldparam [Config]
33
- # @yieldreturn [void]
34
- # @return [void]
35
- def configure
36
- yield(configuration)
37
- end
26
+ # Get allure configuration
27
+ # @return [Config]
28
+ def configuration
29
+ Config.instance
30
+ end
38
31
 
39
- # Add epic to current test case
40
- # @param [String] value
41
- # @return [void]
42
- def epic(value)
43
- label(ResultUtils::EPIC_LABEL_NAME, value)
44
- end
32
+ # Set allure configuration
33
+ # @yieldparam [Config]
34
+ # @yieldreturn [void]
35
+ # @return [void]
36
+ def configure
37
+ yield(configuration)
38
+ end
45
39
 
46
- # Add feature to current test case
47
- # @param [String] value
48
- # @return [void]
49
- def feature(value)
50
- label(ResultUtils::FEATURE_LABEL_NAME, value)
51
- end
40
+ # Add epic to current test case
41
+ # @param [String] value
42
+ # @return [void]
43
+ def epic(value)
44
+ replace_label(ResultUtils::EPIC_LABEL_NAME, value)
45
+ end
52
46
 
53
- # Add story to current test case
54
- # @param [String] value
55
- # @return [void]
56
- def story(value)
57
- label(ResultUtils::STORY_LABEL_NAME, value)
58
- end
47
+ # Add feature to current test case
48
+ # @param [String] value
49
+ # @return [void]
50
+ def feature(value)
51
+ replace_label(ResultUtils::FEATURE_LABEL_NAME, value)
52
+ end
59
53
 
60
- # Add suite to current test case
61
- # @param [String] value
62
- # @return [void]
63
- def suite(value)
64
- label(ResultUtils::SUITE_LABEL_NAME, value)
65
- end
54
+ # Add story to current test case
55
+ # @param [String] value
56
+ # @return [void]
57
+ def story(value)
58
+ replace_label(ResultUtils::STORY_LABEL_NAME, value)
59
+ end
66
60
 
67
- # Add label to current test case
68
- # @param [String] name
69
- # @param [String] value
70
- # @return [void]
71
- def label(name, value)
72
- lifecycle.update_test_case do |test_case|
73
- test_case.labels.push(Label.new(name, value))
74
- end
75
- end
61
+ # Add suite to current test case
62
+ # @param [String] value
63
+ # @return [void]
64
+ def suite(value)
65
+ replace_label(ResultUtils::SUITE_LABEL_NAME, value)
66
+ end
76
67
 
77
- # Add description to current test case
78
- # @param [String] description
79
- # @return [void]
80
- def add_description(description)
81
- lifecycle.update_test_case do |test_case|
82
- test_case.description = description
83
- end
84
- end
68
+ # Add tag to current test case
69
+ # @param [String] value
70
+ # @return [void]
71
+ def tag(value)
72
+ label(ResultUtils::TAG_LABEL_NAME, value)
73
+ end
85
74
 
86
- # Add html description to current test case
87
- # @param [String] description_html
88
- # @return [void]
89
- def description_html(description_html)
90
- lifecycle.update_test_case do |test_case|
91
- test_case.description_html = description_html
92
- end
75
+ # Add label to current test case
76
+ # @param [String] name
77
+ # @param [String] value
78
+ # @return [void]
79
+ def label(name, value)
80
+ lifecycle.update_test_case do |test_case|
81
+ test_case.labels.push(Label.new(name, value))
93
82
  end
83
+ end
94
84
 
95
- # Add parameter to current test case
96
- # @param [String] name
97
- # @param [String] value
98
- # @return [void]
99
- def parameter(name, value)
100
- lifecycle.update_test_case do |test_case|
101
- test_case.parameters.push(Parameter.new(name, value))
102
- end
85
+ # Replace label in current test case
86
+ #
87
+ # @param [String] name
88
+ # @param [String] value
89
+ # @return [void]
90
+ def replace_label(name, value)
91
+ lifecycle.update_test_case do |test_case|
92
+ present = test_case.labels.detect { |l| l.name == name }
93
+ return label(name, value) unless present
94
+
95
+ test_case.labels.map! { |l| l.name == name ? Label.new(name, value) : l }
103
96
  end
97
+ end
104
98
 
105
- # Add tms link to current test case
106
- # @param [String] name
107
- # @param [String] url
108
- # @return [void]
109
- def tms(name, url)
110
- add_link(name: name, url: url, type: ResultUtils::TMS_LINK_TYPE)
99
+ # Add description to current test case
100
+ # @param [String] description
101
+ # @return [void]
102
+ def add_description(description)
103
+ lifecycle.update_test_case do |test_case|
104
+ test_case.description = description
111
105
  end
106
+ end
112
107
 
113
- # Add issue linkt to current test case
114
- # @param [String] name
115
- # @param [String] url
116
- # @return [void]
117
- def issue(name, url)
118
- add_link(name: name, url: url, type: ResultUtils::ISSUE_LINK_TYPE)
108
+ # Add html description to current test case
109
+ # @param [String] description_html
110
+ # @return [void]
111
+ def description_html(description_html)
112
+ lifecycle.update_test_case do |test_case|
113
+ test_case.description_html = description_html
119
114
  end
115
+ end
120
116
 
121
- # Add link to current test case
122
- # @param [String ] url
123
- # @param [String] name
124
- # @param [String] type type of the link used to display link icon
125
- # @return [void]
126
- def add_link(url:, name: nil, type: "custom")
127
- lifecycle.update_test_case do |test_case|
128
- test_case.links.push(Link.new(type, name || url, url))
129
- end
117
+ # Add parameter to current test case
118
+ # @param [String] name
119
+ # @param [String] value
120
+ # @return [void]
121
+ def parameter(name, value)
122
+ lifecycle.update_test_case do |test_case|
123
+ test_case.parameters.push(Parameter.new(name, value))
130
124
  end
125
+ end
131
126
 
132
- # Add attachment to current test case or step
133
- # @param [String] name Attachment name
134
- # @param [File, String] source File or string to save as attachment
135
- # @param [String] type attachment type defined in {ContentType} or any other valid mime type
136
- # @param [Boolean] test_case add attachment to current test case instead of test step
137
- # @return [void]
138
- def add_attachment(name:, source:, type:, test_case: false)
139
- lifecycle.add_attachment(name: name, source: source, type: type, test_case: test_case)
127
+ # Add tms link to current test case
128
+ # @param [String] name
129
+ # @param [String] url
130
+ # @return [void]
131
+ def tms(name, url)
132
+ add_link(name: name, url: url, type: ResultUtils::TMS_LINK_TYPE)
133
+ end
134
+
135
+ # Add issue linkt to current test case
136
+ # @param [String] name
137
+ # @param [String] url
138
+ # @return [void]
139
+ def issue(name, url)
140
+ add_link(name: name, url: url, type: ResultUtils::ISSUE_LINK_TYPE)
141
+ end
142
+
143
+ # Add link to current test case
144
+ # @param [String ] url
145
+ # @param [String] name
146
+ # @param [String] type type of the link used to display link icon
147
+ # @return [void]
148
+ def add_link(url:, name: nil, type: "custom")
149
+ lifecycle.update_test_case do |test_case|
150
+ test_case.links.push(Link.new(type, name || url, url))
140
151
  end
152
+ end
141
153
 
142
- # Add allure report environment info
143
- # @param [Hash<Symbol, String>] environment
144
- # @return [void]
145
- def add_environment(environment)
146
- lifecycle.write_environment(environment)
154
+ # Add attachment to current test case or step
155
+ # @param [String] name Attachment name
156
+ # @param [File, String] source File or string to save as attachment
157
+ # @param [String] type attachment type defined in {ContentType} or any other valid mime type
158
+ # @param [Boolean] test_case add attachment to current test case instead of test step
159
+ # @return [void]
160
+ def add_attachment(name:, source:, type:, test_case: false)
161
+ lifecycle.add_attachment(name: name, source: source, type: type, test_case: test_case)
162
+ end
163
+
164
+ # Manually create environment.properties file
165
+ # if this method is called before test run started and
166
+ # option clean_results_directory is enabled, the file will be deleted
167
+ # @param [Hash<Symbol, String>, Proc] environment
168
+ # @return [void]
169
+ def add_environment(environment)
170
+ lifecycle.write_environment(environment)
171
+ end
172
+
173
+ # Manually create categories.json file
174
+ # if this method is called before test run started and
175
+ # option clean_results_directory is enabled, the file will be deleted
176
+ # @param [File, Array<Category>] categories
177
+ # @return [void]
178
+ def add_categories(categories)
179
+ lifecycle.write_categories(categories)
180
+ end
181
+
182
+ # Set test case status detail to flaky
183
+ #
184
+ # @return [void]
185
+ def set_flaky
186
+ lifecycle.update_test_case do |test_case|
187
+ test_case.status_details.flaky = true
147
188
  end
189
+ end
148
190
 
149
- # Add categories info
150
- # @param [File, Array<Category>] categories
151
- # @return [void]
152
- def add_categories(categories)
153
- lifecycle.write_categories(categories)
191
+ # Set test case status detail to muted
192
+ #
193
+ # @return [void]
194
+ def set_muted
195
+ lifecycle.update_test_case do |test_case|
196
+ test_case.status_details.muted = true
154
197
  end
198
+ end
155
199
 
156
- # Add step with provided name and optional status to current test step, fixture or test case
157
- # @param [String] name
158
- # @param [Symbol] status {Status}, {Status::PASSED} by default
159
- # @return [void]
160
- def step(name:, status: nil)
161
- lifecycle.add_test_step(StepResult.new(name: name, status: status || Status::PASSED, stage: Stage::FINISHED))
162
- lifecycle.stop_test_step
200
+ # Set test case status detail to known
201
+ #
202
+ # @return [void]
203
+ def set_known
204
+ lifecycle.update_test_case do |test_case|
205
+ test_case.status_details.known = true
163
206
  end
207
+ end
208
+
209
+ # Add step with provided name and optional status to current test step, fixture or test case
210
+ # @param [String] name
211
+ # @param [Symbol] status {Status}, {Status::PASSED} by default
212
+ # @return [void]
213
+ def step(name:, status: nil)
214
+ lifecycle.add_test_step(StepResult.new(name: name, status: status || Status::PASSED, stage: Stage::FINISHED))
215
+ lifecycle.stop_test_step
216
+ end
217
+
218
+ # Run passed block as step with given name and return result of yield
219
+ # @param [String] name
220
+ # @yield [] step block
221
+ # @return [Object]
222
+ def run_step(name)
223
+ lifecycle.start_test_step(StepResult.new(name: name, stage: Stage::RUNNING))
224
+ result = yield
225
+ lifecycle.update_test_step { |step| step.status = Status::PASSED }
226
+
227
+ result
228
+ rescue StandardError => e
229
+ lifecycle.update_test_step do |step|
230
+ step.status = ResultUtils.status(e)
231
+ step.status_details = ResultUtils.status_details(e)
232
+ end
233
+ raise(e)
234
+ ensure
235
+ lifecycle.stop_test_step
236
+ end
164
237
 
165
- # Run passed block as step with given name and return result of yield
166
- # @param [String] name
167
- # @yield [] step block
168
- # @return [Object]
169
- def run_step(name)
170
- lifecycle.start_test_step(StepResult.new(name: name, stage: Stage::RUNNING))
171
- result = yield
172
- lifecycle.update_test_step { |step| step.status = Status::PASSED }
173
-
174
- result
175
- rescue StandardError => e
176
- lifecycle.update_test_step do |step|
177
- step.status = ResultUtils.status(e)
178
- step.status_details = ResultUtils.status_details(e)
179
- end
180
- raise(e)
181
- ensure
182
- lifecycle.stop_test_step
238
+ # Add parameter to current test step
239
+ # @param [String] name
240
+ # @param [String] value
241
+ # @return [void]
242
+ def step_parameter(name, value)
243
+ lifecycle.update_test_step do |step|
244
+ step.parameters.push(Parameter.new(name, value))
183
245
  end
184
246
  end
185
247
  end
@@ -8,14 +8,19 @@ module Allure
8
8
  class AllureLifecycle # rubocop:disable Metrics/ClassLength
9
9
  extend Forwardable
10
10
 
11
- def initialize
11
+ # Allure lifecycle instance
12
+ #
13
+ # @param [Allure::Config] configuration
14
+ def initialize(config = Config.instance)
12
15
  @test_context = []
13
16
  @step_context = []
14
- @logger = Logger.new($stdout, level: Config.instance.logging_level)
15
- @file_writer = FileWriter.new
17
+ @config = config
18
+ @logger = config.logger
16
19
  end
17
20
 
18
- def_delegators :file_writer, :write_attachment, :write_environment, :write_categories
21
+ attr_reader :config
22
+
23
+ def_delegators :file_writer, :write_attachment
19
24
 
20
25
  # Start test result container
21
26
  # @param [Allure::TestResultContainer] test_result_container
@@ -215,6 +220,27 @@ module Allure
215
220
  write_attachment(source, attachment)
216
221
  end
217
222
 
223
+ # Add environment.properties file
224
+ #
225
+ # @param [Hash, Proc] env
226
+ # @return [void]
227
+ def write_environment(env = config.environment_properties)
228
+ return unless env
229
+
230
+ env_properties = env.respond_to?(:call) ? env.call : env
231
+ file_writer.write_environment(env_properties)
232
+ end
233
+
234
+ # Add categories.json
235
+ #
236
+ # @param [File, Array<Category>] categories
237
+ # @return [void]
238
+ def write_categories(categories = config.categories)
239
+ return unless categories
240
+
241
+ file_writer.write_categories(categories)
242
+ end
243
+
218
244
  # Add step to current fixture|step|test case
219
245
  # @param [Allure::StepResult] step_result
220
246
  # @return [Allure::StepResult]
@@ -227,14 +253,16 @@ module Allure
227
253
  # Clean results directory
228
254
  # @return [void]
229
255
  def clean_results_dir
230
- Allure.configuration.tap do |c|
231
- FileUtils.rm_f(Dir.glob("#{c.results_directory}/**/*")) if c.clean_results_directory
232
- end
256
+ FileUtils.rm_f(Dir.glob("#{config.results_directory}/**/*")) if config.clean_results_directory
233
257
  end
234
258
 
235
259
  private
236
260
 
237
- attr_accessor :logger, :file_writer
261
+ attr_reader :logger
262
+
263
+ def file_writer
264
+ @file_writer ||= FileWriter.new(config.results_directory)
265
+ end
238
266
 
239
267
  def current_executable
240
268
  current_test_step || @current_fixture || @current_test_case
@@ -10,41 +10,36 @@ module Allure
10
10
 
11
11
  # @return [Array<String>] valid log levels
12
12
  LOGLEVELS = %w[DEBUG INFO WARN ERROR FATAL UNKNOWN].freeze
13
- # @return [String] test plan path env var name
14
- TESTPLAN_PATH = "ALLURE_TESTPLAN_PATH"
15
13
 
16
- attr_accessor :results_directory, :logging_level, :link_tms_pattern, :link_issue_pattern, :clean_results_directory
14
+ attr_writer :environment, :logger
15
+
16
+ attr_accessor :results_directory,
17
+ :logging_level,
18
+ :link_tms_pattern,
19
+ :link_issue_pattern,
20
+ :clean_results_directory,
21
+ :environment_properties,
22
+ :categories
17
23
 
18
24
  def initialize
19
25
  @results_directory = "reports/allure-results"
20
26
  @logging_level = LOGLEVELS.index(ENV.fetch("ALLURE_LOG_LEVEL", "INFO")) || Logger::INFO
21
27
  end
22
28
 
23
- # Allure id's of executable tests
29
+ # Allure environment
24
30
  #
25
- # @return [Array]
26
- def test_ids
27
- @test_ids ||= tests&.map { |test| test[:id] }
28
- end
31
+ # @return [String]
32
+ def environment
33
+ return(@environment) if defined?(@environment)
29
34
 
30
- # Test names of executable tests
31
- #
32
- # @return [Array]
33
- def test_names
34
- @test_names ||= tests&.map { |test| test[:selector] }
35
+ @environment ||= ENV["ALLURE_ENVIRONMENT"]
35
36
  end
36
37
 
37
- private
38
-
39
- # Tests to execute from allure testplan.json
38
+ # Logger instance
40
39
  #
41
- # @return [Array<Hash>]
42
- def tests
43
- @tests ||= begin
44
- Oj.load_file(ENV[TESTPLAN_PATH], symbol_keys: true)&.fetch(:tests) if ENV[TESTPLAN_PATH]
45
- end
46
- rescue Oj::ParseError
47
- nil
40
+ # @return [Logger]
41
+ def logger
42
+ @logger ||= Logger.new($stdout, level: logging_level)
48
43
  end
49
44
  end
50
45
  end
@@ -13,19 +13,28 @@ module Allure
13
13
  ENVIRONMENT_FILE = "environment.properties"
14
14
  # @return [String] categories definition json
15
15
  CATEGORIES_FILE = "categories.json"
16
+ # @return [Hash] Oj json options
17
+ OJ_OPTIONS = { mode: :custom, use_to_hash: true, ascii_only: true }.freeze
18
+
19
+ # File writer instance
20
+ #
21
+ # @param [String] results_directory
22
+ def initialize(results_directory)
23
+ @results_directory = results_directory
24
+ end
16
25
 
17
26
  # Write test result
18
27
  # @param [Allure::TestResult] test_result
19
28
  # @return [void]
20
29
  def write_test_result(test_result)
21
- write("#{test_result.uuid}#{TEST_RESULT_SUFFIX}", Oj.dump(test_result))
30
+ write("#{test_result.uuid}#{TEST_RESULT_SUFFIX}", Oj.dump(test_result, OJ_OPTIONS))
22
31
  end
23
32
 
24
33
  # Write test result container
25
34
  # @param [Allure::TestResultContainer] test_container_result
26
35
  # @return [void]
27
36
  def write_test_result_container(test_container_result)
28
- write("#{test_container_result.uuid}#{TEST_RESULT_CONTAINER_SUFFIX}", Oj.dump(test_container_result))
37
+ write("#{test_container_result.uuid}#{TEST_RESULT_CONTAINER_SUFFIX}", Oj.dump(test_container_result, OJ_OPTIONS))
29
38
  end
30
39
 
31
40
  # Write allure attachment file
@@ -52,19 +61,21 @@ module Allure
52
61
  if categories.is_a?(File)
53
62
  copy(categories.path, CATEGORIES_FILE)
54
63
  else
55
- write(CATEGORIES_FILE, Oj.dump(categories))
64
+ write(CATEGORIES_FILE, Oj.dump(categories, OJ_OPTIONS))
56
65
  end
57
66
  end
58
67
 
59
68
  private
60
69
 
70
+ attr_reader :results_directory
71
+
61
72
  def output_dir
62
- @output_dir ||= FileUtils.mkpath(Config.instance.results_directory).first
73
+ @output_dir ||= FileUtils.mkpath(results_directory).first
63
74
  end
64
75
 
65
76
  def write(name, source)
66
77
  filename = File.join(output_dir, name)
67
- File.open(filename, "w") { |file| file.write(source) }
78
+ File.write(filename, source)
68
79
  end
69
80
 
70
81
  def copy(from, to)
@@ -5,8 +5,6 @@ require "oj"
5
5
  module Allure
6
6
  # General jsonable object implementation
7
7
  class JSONable
8
- Oj.default_options = { mode: :custom, use_to_hash: true, ascii_only: true }
9
-
10
8
  # Return object hash represantation
11
9
  # @return [Hash]
12
10
  def to_hash
@@ -27,9 +27,16 @@ module Allure
27
27
  @parameters = options[:parameters] || []
28
28
  end
29
29
 
30
- attr_accessor(
31
- :name, :status, :status_details, :stage, :description, :description_html,
32
- :steps, :attachments, :parameters, :start, :stop
33
- )
30
+ attr_accessor :name,
31
+ :status,
32
+ :status_details,
33
+ :stage,
34
+ :description,
35
+ :description_html,
36
+ :steps,
37
+ :attachments,
38
+ :parameters,
39
+ :start,
40
+ :stop
34
41
  end
35
42
  end
@@ -5,6 +5,7 @@ module Allure
5
5
  class TestResult < ExecutableItem
6
6
  # @param [String] uuid
7
7
  # @param [String] history_id
8
+ # @param [String] environment
8
9
  # @param [Hash] options
9
10
  # @option options [String] :name
10
11
  # @option options [String] :full_name
@@ -18,15 +19,22 @@ module Allure
18
19
  # @option options [Array<Allure::Link>] :links ([])
19
20
  # @option options [Array<Allure::Attachment>] :attachments ([])
20
21
  # @option options [Array<Allure::Parameter>] :parameters ([])
21
- def initialize(uuid: UUID.generate, history_id: UUID.generate, **options)
22
+ def initialize(uuid: UUID.generate, history_id: UUID.generate, environment: nil, **options)
22
23
  super
24
+
25
+ @name = options[:name]
23
26
  @uuid = uuid
24
- @history_id = history_id
27
+ @history_id = Digest::MD5.hexdigest("#{history_id}#{environment}")
25
28
  @full_name = options[:full_name] || "Unnamed"
26
29
  @labels = options[:labels] || []
27
30
  @links = options[:links] || []
31
+ @parameters << Parameter.new("environment", environment) if environment
28
32
  end
29
33
 
30
- attr_accessor :uuid, :history_id, :full_name, :labels, :links
34
+ attr_accessor :uuid,
35
+ :history_id,
36
+ :full_name,
37
+ :labels,
38
+ :links
31
39
  end
32
40
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "socket"
4
+ require "uri"
4
5
 
5
6
  module Allure
6
7
  # Variouse helper methods
@@ -59,6 +60,13 @@ module Allure
59
60
  Label.new(FRAMEWORK_LABEL_NAME, value)
60
61
  end
61
62
 
63
+ # Epic label
64
+ # @param [String] value
65
+ # @return [Allure::Label]
66
+ def epic_label(value)
67
+ Label.new(EPIC_LABEL_NAME, value)
68
+ end
69
+
62
70
  # Feature label
63
71
  # @param [String] value
64
72
  # @return [Allure::Label]
@@ -66,6 +74,13 @@ module Allure
66
74
  Label.new(FEATURE_LABEL_NAME, value)
67
75
  end
68
76
 
77
+ # Story label
78
+ # @param [String] value
79
+ # @return [Allure::Label]
80
+ def story_label(value)
81
+ Label.new(STORY_LABEL_NAME, value)
82
+ end
83
+
69
84
  # Package label
70
85
  # @param [String] value
71
86
  # @return [Allure::Label]
@@ -94,13 +109,6 @@ module Allure
94
109
  Label.new(SUB_SUITE_LABEL_NAME, value)
95
110
  end
96
111
 
97
- # Story label
98
- # @param [String] value
99
- # @return [Allure::Label]
100
- def story_label(value)
101
- Label.new(STORY_LABEL_NAME, value)
102
- end
103
-
104
112
  # Test case label
105
113
  # @param [String] value
106
114
  # @return [Allure::Label]
@@ -124,16 +132,20 @@ module Allure
124
132
 
125
133
  # TMS link
126
134
  # @param [String] value
135
+ # @param [String] link_pattern
127
136
  # @return [Allure::Link]
128
- def tms_link(value)
129
- Link.new(TMS_LINK_TYPE, value, tms_url(value))
137
+ def tms_link(name, value, link_pattern)
138
+ link_name = url?(value) ? name : value
139
+ Link.new(TMS_LINK_TYPE, link_name, url(value, link_pattern))
130
140
  end
131
141
 
132
142
  # Issue link
133
143
  # @param [String] value
144
+ # @param [String] link_pattern
134
145
  # @return [Allure::Link]
135
- def issue_link(value)
136
- Link.new(ISSUE_LINK_TYPE, value, issue_url(value))
146
+ def issue_link(name, value, link_pattern)
147
+ link_name = url?(value) ? name : value
148
+ Link.new(ISSUE_LINK_TYPE, link_name, url(value, link_pattern))
137
149
  end
138
150
 
139
151
  # Get status based on exception type
@@ -162,12 +174,21 @@ module Allure
162
174
 
163
175
  private
164
176
 
165
- def tms_url(value)
166
- Allure.configuration.link_tms_pattern.sub("{}", value)
177
+ # Check if value is full url
178
+ #
179
+ # @param [String] value
180
+ # @return [Boolean]
181
+ def url?(value)
182
+ URI.parse(value.to_s).scheme
167
183
  end
168
184
 
169
- def issue_url(value)
170
- Allure.configuration.link_issue_pattern.sub("{}", value)
185
+ # Construct url from pattern
186
+ #
187
+ # @param [String] value
188
+ # @param [String] link_pattern
189
+ # @return [String]
190
+ def url(value, link_pattern)
191
+ link_pattern.sub("{}", value)
171
192
  end
172
193
  end
173
194
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adds support for annotating methods as allure steps
4
+ #
5
+ module AllureStepAnnotation
6
+ # Mark method definition as allure step
7
+ #
8
+ # @param [String] step_name
9
+ # @return [void]
10
+ def step(step_name = "")
11
+ @allure_step = step_name
12
+ end
13
+
14
+ private
15
+
16
+ def singleton_method_added(method_name)
17
+ return super unless @allure_step
18
+
19
+ original_method = singleton_method(method_name)
20
+ step_name = @allure_step.empty? ? method_name.to_s : @allure_step
21
+ @allure_step = nil
22
+
23
+ define_singleton_method(method_name) do |*args, &block|
24
+ Allure.run_step(step_name) { original_method.call(*args, &block) }
25
+ end
26
+ end
27
+
28
+ def method_added(method_name)
29
+ return super unless @allure_step
30
+
31
+ original_method = instance_method(method_name)
32
+ step_name = @allure_step.empty? ? method_name.to_s : @allure_step
33
+ @allure_step = nil
34
+
35
+ define_method(method_name) do |*args, &block|
36
+ Allure.run_step(step_name) { original_method.bind_call(self, *args, &block) }
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Allure
4
+ class TestPlan
5
+ # @return [String] test plan path env var name
6
+ TESTPLAN_PATH = "ALLURE_TESTPLAN_PATH"
7
+
8
+ class << self
9
+ # Allure id's of executable tests
10
+ #
11
+ # @return [Array]
12
+ def test_ids
13
+ @test_ids ||= tests&.map { |test| test[:id] }
14
+ end
15
+
16
+ # Test names of executable tests
17
+ #
18
+ # @return [Array]
19
+ def test_names
20
+ @test_names ||= tests&.map { |test| test[:selector] }
21
+ end
22
+
23
+ private
24
+
25
+ # Tests to execute from allure testplan.json
26
+ #
27
+ # @return [Array<Hash>]
28
+ def tests
29
+ @tests ||= Oj.load_file(ENV[TESTPLAN_PATH], symbol_keys: true)&.fetch(:tests) if ENV[TESTPLAN_PATH]
30
+ rescue Oj::ParseError
31
+ nil
32
+ end
33
+ end
34
+ end
35
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-ruby-commons
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.8.1
4
+ version: 2.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrejs Cunskis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-14 00:00:00.000000000 Z
11
+ date: 2022-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mime-types
@@ -118,6 +118,8 @@ files:
118
118
  - lib/allure_ruby_commons/model/test_result.rb
119
119
  - lib/allure_ruby_commons/model/test_result_container.rb
120
120
  - lib/allure_ruby_commons/result_utils.rb
121
+ - lib/allure_ruby_commons/step_annotation.rb
122
+ - lib/allure_ruby_commons/testplan.rb
121
123
  homepage: https://github.com/allure-framework/allure-ruby
122
124
  licenses:
123
125
  - Apache-2.0
@@ -127,6 +129,7 @@ metadata:
127
129
  documentation_uri: https://github.com/allure-framework/allure-ruby/blob/master/allure-ruby-commons/README.md
128
130
  source_code_uri: https://github.com/allure-framework/allure-ruby/tree/master/allure-ruby-commons
129
131
  wiki_uri: https://github.com/allure-framework/allure-ruby/wiki
132
+ rubygems_mfa_required: 'false'
130
133
  post_install_message:
131
134
  rdoc_options: []
132
135
  require_paths:
@@ -135,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
138
  requirements:
136
139
  - - ">="
137
140
  - !ruby/object:Gem::Version
138
- version: 2.5.0
141
+ version: 2.7.0
139
142
  required_rubygems_version: !ruby/object:Gem::Requirement
140
143
  requirements:
141
144
  - - ">="
142
145
  - !ruby/object:Gem::Version
143
146
  version: '0'
144
147
  requirements: []
145
- rubygems_version: 3.2.3
148
+ rubygems_version: 3.3.7
146
149
  signing_key:
147
150
  specification_version: 4
148
151
  summary: Common library for allure results generation