allure-ruby-commons 2.13.1 → 2.14.0

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: 5a9115fbeeca5e229495d548047fa91edac5cb364a3a18c629f7d860fff43b3c
4
- data.tar.gz: 302ce724cd87c8c8a392687355c693774e40e0dfeb6d00cc4e67c5202a2dd733
3
+ metadata.gz: b90157e53cb38a4fa6703c63cb675f75f85291f886c97fc7825ed33a5cbaff28
4
+ data.tar.gz: 3a4aff315c87fbdaa55709505dd629c731350ef01874f67e8a58cb0b08be2c09
5
5
  SHA512:
6
- metadata.gz: 7392a3abf6e355d4e1a7e1dfddca5c39c68ffe89549eaf72db2a0e7e4793c4019e7f2dfb5877c82be92775476ac70349218e1c85087ed17aa7374a0d6c461beb
7
- data.tar.gz: 9a263ffc1763bbb4647c5341259bf12f6e8e766feb026fc4f7fae41c51b109609b64b410baaadb0080f9bd07edfccb113ffb47553e5ddbf7632770188ed8190a
6
+ metadata.gz: ee87093a5030d0037ae10799ad0ea26247f90c7ffef686f2029356886cab173e7a5fd379d831f77fb0879d53b5321bdec8e39cd08c201dcb084c33435a16890b
7
+ data.tar.gz: 23921b2da0d5397f872f23e7fcaaf649f5d6f03caa5602f85821cd4f383eb8d7ef5fc4e9c90a7542ea734351605467ae8c09b04c303964a80c6e93f1b17c4831
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Allure Ruby Adaptor API
2
2
 
3
+ [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/allure-ruby-commons)
4
+
3
5
  This is a helper library containing the basics for any ruby-based Allure adaptor.
4
6
  Using it you can easily implement the adaptor for your favorite ruby testing library or
5
7
  you can just create the report of any other kind using the basic Allure terms.
@@ -9,7 +11,7 @@ you can just create the report of any other kind using the basic Allure terms.
9
11
  Add the dependency to your Gemfile
10
12
 
11
13
  ```ruby
12
- gem 'allure-ruby-commons'
14
+ gem "allure-ruby-commons"
13
15
  ```
14
16
 
15
17
  ## Configuration
@@ -17,13 +19,16 @@ Add the dependency to your Gemfile
17
19
  Following configuration options are supported:
18
20
 
19
21
  ```ruby
20
- Allure.configure do |c|
21
- c.results_directory = "/whatever/you/like"
22
- c.clean_results_directory = true
23
- c.logging_level = Logger::INFO
22
+ Allure.configure do |config|
23
+ config.results_directory = "report/allure-results"
24
+ config.clean_results_directory = true
25
+ config.logging_level = Logger::INFO
26
+ config.logger = Logger.new($stdout, Logger::DEBUG)
27
+ config.environment = "staging"
28
+
24
29
  # these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
25
- c.link_tms_pattern = "http://www.jira.com/browse/{}"
26
- c.link_issue_pattern = "http://www.jira.com/browse/{}"
30
+ config.link_tms_pattern = "http://www.jira.com/browse/{}"
31
+ config.link_issue_pattern = "http://www.jira.com/browse/{}"
27
32
  end
28
33
  ```
29
34
 
@@ -33,6 +38,17 @@ Getting the configuration object:
33
38
  Allure.configuration
34
39
  ```
35
40
 
41
+ ### Allure environment
42
+
43
+ It is possible to set up custom allure environment which will be used to prefix test case names. 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:
44
+
45
+ * via `ALLURE_ENVIRONMENT` environment variable
46
+ * via `configure` method
47
+
48
+ ### Log level
49
+
50
+ 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`.
51
+
36
52
  ## Allure lifecycle
37
53
 
38
54
  Reports are built using API defined in AllureLifecycle class and using allure specific entities defined in models.
@@ -48,6 +64,23 @@ Allure.add_attachment(name: "attachment", source: "/path/to/test.txt", type: All
48
64
  Allure.add_link(name: "Custom Url", url: "http://www.github.com")
49
65
  ```
50
66
 
67
+ ## Steps
68
+
69
+ It is possible to mark method definitions to be automatically added to report as steps. The class just needs to extend `AllureStepAnnotation`
70
+ and `step` method needs to be used before the method definition.
71
+
72
+ ```ruby
73
+ class TestHelper
74
+ extend AllureStepAnnotation
75
+
76
+ step("Singleton step")
77
+ def self.class_method; end
78
+
79
+ step("Standard step")
80
+ def standard_method; end
81
+ end
82
+ ```
83
+
51
84
  ## Testing
52
85
 
53
86
  Install dependencies:
@@ -3,166 +3,205 @@
3
3
 
4
4
  require "require_all"
5
5
  require "uuid"
6
+
6
7
  require_rel "allure_ruby_commons/**/*rb"
7
8
 
8
9
  # Namespace for classes that handle allure report generation and different framework adaptors
9
10
  module Allure
10
- class << self
11
- # Get thread specific allure lifecycle object
12
- # @return [Allure::AllureLifecycle]
13
- def lifecycle
14
- Thread.current[:lifecycle] ||= AllureLifecycle.new
15
- end
11
+ # Set lifecycle object
12
+ # @param [AllureLifecycle] lifecycle
13
+ # @return [void]
14
+ def self.lifecycle=(lifecycle)
15
+ Thread.current[:lifecycle] = lifecycle
16
+ end
16
17
 
17
- # Set lifecycle object
18
- # @param [Allure::AllureLifecycle] lifecycle
19
- # @return [void]
20
- def lifecycle=(lifecycle)
21
- Thread.current[:lifecycle] = lifecycle
22
- end
18
+ extend self # rubocop:disable Style/ModuleFunction
23
19
 
24
- # Get allure configuration
25
- # @return [Allure::Config]
26
- def configuration
27
- Config
28
- end
20
+ # Get thread specific allure lifecycle object
21
+ # @return [AllureLifecycle]
22
+ def lifecycle
23
+ Thread.current[:lifecycle] ||= AllureLifecycle.new
24
+ end
29
25
 
30
- # Set allure configuration
31
- # @yieldparam [Allure::Config]
32
- # @yieldreturn [void]
33
- # @return [void]
34
- def configure
35
- yield(Config)
36
- end
26
+ # Get allure configuration
27
+ # @return [Config]
28
+ def configuration
29
+ Config.instance
30
+ end
37
31
 
38
- # Add epic to current test case
39
- # @param [String] value
40
- # @return [void]
41
- def epic(value)
42
- label(ResultUtils::EPIC_LABEL_NAME, value)
43
- end
32
+ # Set allure configuration
33
+ # @yieldparam [Config]
34
+ # @yieldreturn [void]
35
+ # @return [void]
36
+ def configure
37
+ yield(configuration)
38
+ end
44
39
 
45
- # Add feature to current test case
46
- # @param [String] value
47
- # @return [void]
48
- def feature(value)
49
- label(ResultUtils::FEATURE_LABEL_NAME, value)
50
- 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
51
46
 
52
- # Add story to current test case
53
- # @param [String] value
54
- # @return [void]
55
- def story(value)
56
- label(ResultUtils::STORY_LABEL_NAME, value)
57
- 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
58
53
 
59
- # Add suite to current test case
60
- # @param [String] value
61
- # @return [void]
62
- def suite(value)
63
- label(ResultUtils::SUITE_LABEL_NAME, value)
64
- 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
65
60
 
66
- # Add label to current test case
67
- # @param [String] name
68
- # @param [String] value
69
- # @return [void]
70
- def label(name, value)
71
- lifecycle.update_test_case do |test_case|
72
- test_case.labels.push(Label.new(name, value))
73
- end
74
- 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
75
67
 
76
- # Add description to current test case
77
- # @param [String] description
78
- # @return [void]
79
- def add_description(description)
80
- lifecycle.update_test_case do |test_case|
81
- test_case.description = description
82
- end
83
- 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
84
74
 
85
- # Add html description to current test case
86
- # @param [String] description_html
87
- # @return [void]
88
- def description_html(description_html)
89
- lifecycle.update_test_case do |test_case|
90
- test_case.description_html = description_html
91
- 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))
92
82
  end
83
+ end
93
84
 
94
- # Add parameter to current test case
95
- # @param [String] name
96
- # @param [String] value
97
- # @return [void]
98
- def parameter(name, value)
99
- lifecycle.update_test_case do |test_case|
100
- test_case.parameters.push(Parameter.new(name, value))
101
- end
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
103
94
 
104
- # Add tms link to current test case
105
- # @param [String] name
106
- # @param [String] url
107
- # @return [void]
108
- def tms(name, url)
109
- add_link(name: name, url: url, type: ResultUtils::TMS_LINK_TYPE)
95
+ test_case.labels.map! { |l| l.name == name ? Label.new(name, value) : l }
110
96
  end
97
+ end
111
98
 
112
- # Add issue linkt to current test case
113
- # @param [String] name
114
- # @param [String] url
115
- # @return [void]
116
- def issue(name, url)
117
- add_link(name: name, url: url, type: ResultUtils::ISSUE_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
118
105
  end
106
+ end
119
107
 
120
- # Add link to current test case
121
- # @param [String ] url
122
- # @param [String] name
123
- # @param [String] type type of the link used to display link icon
124
- # @return [void]
125
- def add_link(url:, name: nil, type: "custom")
126
- lifecycle.update_test_case do |test_case|
127
- test_case.links.push(Link.new(type, name || url, url))
128
- end
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
129
114
  end
115
+ end
130
116
 
131
- # Add attachment to current test case or step
132
- # @param [String] name Attachment name
133
- # @param [File, String] source File or string to save as attachment
134
- # @param [String] type attachment type defined in {Allure::ContentType} or any other valid mime type
135
- # @param [Boolean] test_case add attachment to current test case instead of test step
136
- # @return [void]
137
- def add_attachment(name:, source:, type:, test_case: false)
138
- lifecycle.add_attachment(name: name, source: source, type: type, test_case: test_case)
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))
139
124
  end
125
+ end
140
126
 
141
- # Add step with provided name and optional status to current test step, fixture or test case
142
- # @param [String] name
143
- # @param [Symbol] status <Allure::Status>, <Allure::Status::PASSED> by default
144
- # @return [void]
145
- def step(name:, status: nil)
146
- lifecycle.add_test_step(StepResult.new(name: name, status: status || Status::PASSED, stage: Stage::FINISHED))
147
- end
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
148
142
 
149
- # Run passed block as step with given name
150
- # @param [String] name
151
- # @yield [] step block
152
- # @return [void]
153
- def run_step(name)
154
- lifecycle.start_test_step(StepResult.new(name: name, stage: Stage::RUNNING))
155
- yield
156
- lifecycle.update_test_step { |step| step.status = Status::PASSED }
157
- rescue => e
158
- lifecycle.update_test_step do |step|
159
- step.status = ResultUtils.status(e)
160
- step.status_details = ResultUtils.status_details(e)
161
- end
162
- raise(e)
163
- ensure
164
- lifecycle.stop_test_step
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))
165
151
  end
166
152
  end
153
+
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
+ # Add allure report environment info
165
+ # @param [Hash<Symbol, String>] environment
166
+ # @return [void]
167
+ def add_environment(environment)
168
+ lifecycle.write_environment(environment)
169
+ end
170
+
171
+ # Add categories info
172
+ # @param [File, Array<Category>] categories
173
+ # @return [void]
174
+ def add_categories(categories)
175
+ lifecycle.write_categories(categories)
176
+ end
177
+
178
+ # Add step with provided name and optional status to current test step, fixture or test case
179
+ # @param [String] name
180
+ # @param [Symbol] status {Status}, {Status::PASSED} by default
181
+ # @return [void]
182
+ def step(name:, status: nil)
183
+ lifecycle.add_test_step(StepResult.new(name: name, status: status || Status::PASSED, stage: Stage::FINISHED))
184
+ lifecycle.stop_test_step
185
+ end
186
+
187
+ # Run passed block as step with given name and return result of yield
188
+ # @param [String] name
189
+ # @yield [] step block
190
+ # @return [Object]
191
+ def run_step(name)
192
+ lifecycle.start_test_step(StepResult.new(name: name, stage: Stage::RUNNING))
193
+ result = yield
194
+ lifecycle.update_test_step { |step| step.status = Status::PASSED }
195
+
196
+ result
197
+ rescue StandardError => e
198
+ lifecycle.update_test_step do |step|
199
+ step.status = ResultUtils.status(e)
200
+ step.status_details = ResultUtils.status_details(e)
201
+ end
202
+ raise(e)
203
+ ensure
204
+ lifecycle.stop_test_step
205
+ end
167
206
  end
168
207
  # rubocop:enable Naming/FileName
@@ -1,20 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
+ require "forwardable"
4
5
 
5
6
  module Allure
6
7
  # Main class for creating and writing allure results
7
- class AllureLifecycle
8
- def initialize
8
+ class AllureLifecycle # rubocop:disable Metrics/ClassLength
9
+ extend Forwardable
10
+
11
+ # Allure lifecycle instance
12
+ #
13
+ # @param [Allure::Config] configuration
14
+ def initialize(config = Config.instance)
9
15
  @test_context = []
10
16
  @step_context = []
17
+ @config = config
18
+ @logger = config.logger
19
+ @file_writer = FileWriter.new(config.results_directory)
11
20
  end
12
21
 
22
+ attr_reader :config
23
+
24
+ def_delegators :file_writer, :write_attachment, :write_environment, :write_categories
25
+
13
26
  # Start test result container
14
27
  # @param [Allure::TestResultContainer] test_result_container
15
28
  # @return [Allure::TestResultContainer]
16
29
  def start_test_container(test_result_container)
17
30
  test_result_container.tap do |container|
31
+ logger.debug { "Starting test container: #{container.name}" }
32
+
18
33
  container.start = ResultUtils.timestamp
19
34
  @test_context.push(container)
20
35
  end
@@ -29,7 +44,7 @@ module Allure
29
44
  # @return [void]
30
45
  def update_test_container
31
46
  unless current_test_result_container
32
- return logger.error("Could not update test container, no container is running.")
47
+ return logger.error { "Could not update test container, no container is running." }
33
48
  end
34
49
 
35
50
  yield(current_test_result_container)
@@ -39,10 +54,11 @@ module Allure
39
54
  # @return [void]
40
55
  def stop_test_container
41
56
  unless current_test_result_container
42
- return logger.error("Could not stop test container, no container is running.")
57
+ return logger.error { "Could not stop test container, no container is running." }
43
58
  end
44
59
 
45
60
  current_test_result_container.tap do |container|
61
+ logger.debug { "Stopping container: #{container.name}" }
46
62
  container.stop = ResultUtils.timestamp
47
63
  file_writer.write_test_result_container(container)
48
64
  clear_last_test_container
@@ -55,9 +71,10 @@ module Allure
55
71
  def start_test_case(test_result)
56
72
  clear_step_context
57
73
  unless current_test_result_container
58
- return logger.error("Could not start test case, test container is not started")
74
+ return logger.error { "Could not start test case, test container is not started" }
59
75
  end
60
76
 
77
+ logger.debug("Starting test case: #{test_result.name}")
61
78
  test_result.start = ResultUtils.timestamp
62
79
  test_result.stage = Stage::RUNNING
63
80
  test_result.labels.push(ResultUtils.thread_label, ResultUtils.host_label, ResultUtils.language_label)
@@ -73,7 +90,7 @@ module Allure
73
90
  # @yieldreturn [void]
74
91
  # @return [void]
75
92
  def update_test_case
76
- return logger.error("Could not update test case, no test case running") unless @current_test_case
93
+ return logger.error { "Could not update test case, no test case running" } unless @current_test_case
77
94
 
78
95
  yield(@current_test_case)
79
96
  end
@@ -81,8 +98,9 @@ module Allure
81
98
  # Stop current test case and write result
82
99
  # @return [void]
83
100
  def stop_test_case
84
- return logger.error("Could not stop test case, no test case is running") unless @current_test_case
101
+ return logger.error { "Could not stop test case, no test case is running" } unless @current_test_case
85
102
 
103
+ logger.debug { "Stopping test case: #{@current_test_case.name}" }
86
104
  @current_test_case.stop = ResultUtils.timestamp
87
105
  @current_test_case.stage = Stage::FINISHED
88
106
  file_writer.write_test_result(@current_test_case)
@@ -94,8 +112,9 @@ module Allure
94
112
  # @param [Allure::StepResult] step_result
95
113
  # @return [Allure::StepResult]
96
114
  def start_test_step(step_result)
97
- return logger.error("Could not start test step, no test case is running") unless @current_test_case
115
+ return logger.error { "Could not start test step, no test case is running" } unless @current_test_case
98
116
 
117
+ logger.debug { "Starting test step: #{step_result.name}" }
99
118
  step_result.start = ResultUtils.timestamp
100
119
  step_result.stage = Stage::RUNNING
101
120
  add_test_step(step_result)
@@ -110,7 +129,7 @@ module Allure
110
129
  # @yieldreturn [void]
111
130
  # @return [void]
112
131
  def update_test_step
113
- return logger.error("Could not update test step, no step is running") unless current_test_step
132
+ return logger.error { "Could not update test step, no step is running" } unless current_test_step
114
133
 
115
134
  yield(current_test_step)
116
135
  end
@@ -118,8 +137,9 @@ module Allure
118
137
  # Stop current test step
119
138
  # @return [void]
120
139
  def stop_test_step
121
- return logger.error("Could not stop test step, no step is running") unless current_test_step
140
+ return logger.error { "Could not stop test step, no step is running" } unless current_test_step
122
141
 
142
+ logger.debug { "Stopping test step: #{current_test_step.name}" }
123
143
  current_test_step.stop = ResultUtils.timestamp
124
144
  current_test_step.stage = Stage::FINISHED
125
145
  clear_last_test_step
@@ -153,6 +173,7 @@ module Allure
153
173
  return false
154
174
  end
155
175
 
176
+ logger.debug { "Starting fixture: #{fixture_result.name}" }
156
177
  fixture_result.start = ResultUtils.timestamp
157
178
  fixture_result.stage = Stage::RUNNING
158
179
  end
@@ -165,7 +186,7 @@ module Allure
165
186
  # @yieldreturn [void]
166
187
  # @return [void]
167
188
  def update_fixture
168
- return logger.error("Could not update fixture, fixture is not started") unless @current_fixture
189
+ return logger.error { "Could not update fixture, fixture is not started" } unless @current_fixture
169
190
 
170
191
  yield(@current_fixture)
171
192
  end
@@ -173,8 +194,9 @@ module Allure
173
194
  # Stop current test fixture
174
195
  # @return [void]
175
196
  def stop_fixture
176
- return logger.error("Could not stop fixture, fixture is not started") unless @current_fixture
197
+ return logger.error { "Could not stop fixture, fixture is not started" } unless @current_fixture
177
198
 
199
+ logger.debug { "Stopping fixture: #{@current_fixture.name}" }
178
200
  @current_fixture.stop = ResultUtils.timestamp
179
201
  @current_fixture.stage = Stage::FINISHED
180
202
  clear_current_fixture
@@ -188,32 +210,15 @@ module Allure
188
210
  # @param [Boolean] test_case add attachment to current test case
189
211
  # @return [void]
190
212
  def add_attachment(name:, source:, type:, test_case: false)
191
- attachment = prepare_attachment(name, type) || begin
192
- return logger.error("Can't add attachment, unrecognized mime type: #{type}")
193
- end
194
- executable_item = (test_case && @current_test_case) || current_executable
195
- executable_item&.attachments&.push(attachment) || begin
196
- return logger.error("Can't add attachment, no test, step or fixture is running")
197
- end
198
- write_attachment(source, attachment)
199
- end
213
+ attachment = ResultUtils.prepare_attachment(name, type)
214
+ return logger.error { "Can't add attachment, unrecognized mime type: #{type}" } unless attachment
200
215
 
201
- # Create attachment object
202
- # @param [String] name
203
- # @param [String] type
204
- # @return [Allure::Attachment]
205
- def prepare_attachment(name, type)
206
- extension = ContentType.to_extension(type) || return
207
- file_name = "#{UUID.generate}-attachment.#{extension}"
208
- Attachment.new(name: name, source: file_name, type: type)
209
- end
216
+ executable_item = test_case ? @current_test_case : current_executable
217
+ return logger.error { "Can't add attachment, no test, step or fixture is running" } unless executable_item
210
218
 
211
- # Write attachment file
212
- # @param [File, String] source
213
- # @param [Allure::Attachment] attachment
214
- # @return [void]
215
- def write_attachment(source, attachment)
216
- file_writer.write_attachment(source, attachment)
219
+ executable_item.attachments.push(attachment)
220
+ logger.debug { "Adding attachment '#{name}' to '#{executable_item.name}'" }
221
+ write_attachment(source, attachment)
217
222
  end
218
223
 
219
224
  # Add step to current fixture|step|test case
@@ -228,20 +233,12 @@ module Allure
228
233
  # Clean results directory
229
234
  # @return [void]
230
235
  def clean_results_dir
231
- Allure.configuration.tap do |c|
232
- FileUtils.rm_f(Dir.glob("#{c.results_directory}/*")) if c.clean_results_directory
233
- end
236
+ FileUtils.rm_f(Dir.glob("#{config.results_directory}/**/*")) if config.clean_results_directory
234
237
  end
235
238
 
236
239
  private
237
240
 
238
- def logger
239
- @logger ||= Logger.new(STDOUT, level: Config.logging_level)
240
- end
241
-
242
- def file_writer
243
- @file_writer ||= FileWriter.new
244
- end
241
+ attr_reader :logger, :file_writer
245
242
 
246
243
  def current_executable
247
244
  current_test_step || @current_fixture || @current_test_case