allure-rspec 2.13.8.2 → 2.13.10

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: 73aaf789a4f2dad6d1681e4fe8ca764158f9a94739380d57d109db2713dcd27d
4
- data.tar.gz: e8f7a74c004f18ae20f3c3a0e602e7342e4b4a6b8ac10ca6e62bb886b5dce67a
3
+ metadata.gz: 6713eef98c82f9aaaedf42b680dfc60cd6a1f0d078d0bbde6d41ca093bd43cc7
4
+ data.tar.gz: f2621a5be7fe54c960a40cb49aba240aa6ade93aefc7843a671b42011ee5b6d5
5
5
  SHA512:
6
- metadata.gz: ac2616d7aba707b9d9b0446e34ae29737a465ce79dc92382c32239809137a00e6a5e46c52de829c8874015e9bc2f79b5c37fe68e92006623026c62272e88d6db
7
- data.tar.gz: 944ed0ded513b4b97c8ecd3ddd59f6ed0f6e20fc71de6660bbfd9808e95ffdbc0d441f1c3920cd0067184fd6c2559770f779bad0ccb211f7998f3f825d4eb669
6
+ metadata.gz: c55b18d7fe448382e93a775f71f00c1297c621947d655466baab033923aba86c466bc40d377d5f0a9bcd54e281edc1befb602dfad44d04b47f2b72a65fb60739
7
+ data.tar.gz: 89a69e78576802c4c3c3c36bd816c6e00c75bda47edac1d029e430c019d9556db80d10f88d6c6e6a99d1144d3e64549e4e6e0b0e8f7ec15ff277a967dd796ce6
data/README.md CHANGED
@@ -24,12 +24,15 @@ Following configuration options are supported:
24
24
 
25
25
  ```ruby
26
26
  AllureRspec.configure do |config|
27
- config.results_directory = "/whatever/you/like"
28
- config.clean_results_directory = true
29
- config.logging_level = Logger::INFO
30
- # these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
31
- config.link_tms_pattern = "http://www.jira.com/browse/{}"
32
- config.link_issue_pattern = "http://www.jira.com/browse/{}"
27
+ config.results_directory = "report/allure-results"
28
+ config.clean_results_directory = true
29
+ config.logging_level = Logger::INFO
30
+ config.logger = Logger.new($stdout, Logger::DEBUG)
31
+ config.environment = "staging"
32
+
33
+ # these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
34
+ config.link_tms_pattern = "http://www.jira.com/browse/{}"
35
+ config.link_issue_pattern = "http://www.jira.com/browse/{}"
33
36
  end
34
37
  ```
35
38
 
@@ -53,11 +56,12 @@ end
53
56
 
54
57
  ### Adding tms links
55
58
 
56
- Configure tms link pattern:
59
+ Configure tms link pattern and rspec tag:
57
60
 
58
61
  ```ruby
59
62
  AllureRspec.configure do |config|
60
63
  config.link_tms_pattern = "http://www.jira.com/browse/{}"
64
+ config.tms_tag = :tms
61
65
  end
62
66
  ```
63
67
 
@@ -84,6 +88,7 @@ Configure issue link pattern:
84
88
  ```ruby
85
89
  AllureRspec.configure do |config|
86
90
  config.link_issue_pattern = "http://www.jira.com/browse/{}"
91
+ config.issue_tag = :issue
87
92
  end
88
93
  ```
89
94
 
@@ -105,7 +110,15 @@ end
105
110
 
106
111
  ### Adding custom severity and status details
107
112
 
108
- Test severity (`normal` by default) can be changed via `severity` tag:
113
+ Configure severity tag:
114
+
115
+ ```ruby
116
+ AllureRspec.configure do |config|
117
+ config.severity_tag = :severity
118
+ end
119
+ ```
120
+
121
+ Test severity is set to `normal` by default:
109
122
 
110
123
  ```ruby
111
124
  it "some test case", severity: :critical do
@@ -131,6 +144,35 @@ it "some test case", allure_1: "visual_test", allure_2: "core_functionality" do
131
144
  end
132
145
  ```
133
146
 
147
+ All rspec metadata tags will also be added as labels in test report.
148
+
149
+ ### Behavior driven test grouping
150
+
151
+ Marking tests with tags `:epic, :feature, :story`, will group tests accordingly in Behavior report tab.\
152
+ Tag values can also be configured:
153
+
154
+ ```ruby
155
+ AllureRspec.configure do |config|
156
+ config.epic_tag = :epic
157
+ config.feature_tag = :feature
158
+ config.story_tag = :story
159
+ end
160
+ ```
161
+
162
+ ```ruby
163
+ context "context", feature: "my feature" do
164
+ it "some test case", story: "user story" do
165
+ # test
166
+ end
167
+ end
168
+
169
+ context "context 2", feature: "my feature" do
170
+ it "some test case 2", story: "user story" do
171
+ # test
172
+ end
173
+ end
174
+ ```
175
+
134
176
  ### Custom actions
135
177
 
136
178
  Rspec example object has access to [Allure](https://www.rubydoc.info/github/allure-framework/allure-ruby/Allure) helper methods.
data/lib/allure-rspec.rb CHANGED
@@ -2,19 +2,19 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "allure-ruby-commons"
5
- require "allure_rspec/config"
6
- require "allure_rspec/formatter"
5
+
6
+ require_rel "allure_rspec/**/*.rb"
7
7
 
8
8
  module AllureRspec
9
9
  class << self
10
10
  # Get allure cucumber configuration
11
- # @return [RspecConfig]
11
+ # @return [AllureRspec::RspecConfig]
12
12
  def configuration
13
13
  RspecConfig.instance
14
14
  end
15
15
 
16
16
  # Set allure configuration
17
- # @yieldparam [RspecConfig]
17
+ # @yieldparam [AllureRspec::RspecConfig]
18
18
  # @yieldreturn [void]
19
19
  # @return [void]
20
20
  def configure
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllureRspec
4
+ module Utils
5
+ # Strip relative ./ form path
6
+ # @param [String] path
7
+ # @return [String]
8
+ def strip_relative(path)
9
+ path.gsub("./", "")
10
+ end
11
+ end
12
+ end
@@ -1,14 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "forwardable"
4
3
  require "singleton"
5
4
 
6
5
  module AllureRspec
7
- # Shorthand configuration class
8
- class RspecConfig < Allure::Config
6
+ # Allure RSpec configuration class
7
+ #
8
+ # @!attribute results_directory
9
+ # @return [String]
10
+ # @!attribute clean_results_directory
11
+ # @return [Boolean]
12
+ # @!attribute link_issue_pattern
13
+ # @return [String]
14
+ # @!attribute link_tms_pattern
15
+ # @return [String]
16
+ # @!attribute logging_level
17
+ # @return [Integer]
18
+ # @!attribute [r] logger
19
+ # @return [Logger]
20
+ # @!attribute environment
21
+ # @return [String]
22
+ class RspecConfig
9
23
  include Singleton
10
24
  extend Forwardable
11
25
 
26
+ # @return [Symbol] default tms tag
27
+ DEFAULT_TMS_TAG = :tms
28
+ # @return [Symbol] default issue tag
29
+ DEFAULT_ISSUE_TAG = :issue
30
+ # @return [Symbol] default severity tag
31
+ DEFAULT_SEVERITY_TAG = :severity
32
+ # @return [Symbol] default epic tag
33
+ DEFAULT_EPIC_TAG = :epic
34
+ # @return [Symbol] default feature tag
35
+ DEFAULT_FEATURE_TAG = :feature
36
+ # @return [Symbol] default story tag
37
+ DEFAULT_STORY_TAG = :story
38
+
12
39
  def_delegators :@allure_config,
13
40
  :clean_results_directory,
14
41
  :clean_results_directory=,
@@ -18,13 +45,52 @@ module AllureRspec
18
45
  :link_tms_pattern=,
19
46
  :logging_level,
20
47
  :logging_level=,
48
+ :logger,
49
+ :logger=,
21
50
  :results_directory,
22
- :results_directory=
51
+ :results_directory=,
52
+ :environment,
53
+ :environment=
23
54
 
24
55
  def initialize
25
- super()
26
-
27
56
  @allure_config = Allure.configuration
28
57
  end
58
+
59
+ attr_writer :tms_tag,
60
+ :issue_tag,
61
+ :severity_tag,
62
+ :epic_tag,
63
+ :feature_tag,
64
+ :story_tag
65
+
66
+ # @return [Symbol]
67
+ def tms_tag
68
+ @tms_prefix || DEFAULT_TMS_TAG
69
+ end
70
+
71
+ # @return [Symbol]
72
+ def issue_tag
73
+ @issue_prefix || DEFAULT_ISSUE_TAG
74
+ end
75
+
76
+ # @return [Symbol]
77
+ def severity_tag
78
+ @severity_prefix || DEFAULT_SEVERITY_TAG
79
+ end
80
+
81
+ # @return [Symbol]
82
+ def epic_tag
83
+ @epic_prefix || DEFAULT_EPIC_TAG
84
+ end
85
+
86
+ # @return [Symbol]
87
+ def feature_tag
88
+ @feature_prefix || DEFAULT_FEATURE_TAG
89
+ end
90
+
91
+ # @return [Symbol]
92
+ def story_tag
93
+ @story_prefix || DEFAULT_STORY_TAG
94
+ end
29
95
  end
30
96
  end
@@ -1,16 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "ruby2_keywords"
4
3
  require "rspec/core"
5
4
  require "rspec/core/formatters/base_formatter"
6
5
 
7
- require_relative "rspec_model"
8
-
9
6
  # Main allure-rspec module
10
7
  module AllureRspec
11
8
  # Main rspec formatter class translating rspec events to allure lifecycle
12
9
  class RSpecFormatter < RSpec::Core::Formatters::BaseFormatter
13
- include AllureRspecModel
10
+ include Utils
11
+
12
+ # @return [Hash] allure statuses mapping
13
+ ALLURE_STATUS = {
14
+ failed: Allure::Status::FAILED,
15
+ pending: Allure::Status::SKIPPED,
16
+ passed: Allure::Status::PASSED
17
+ }.freeze
14
18
 
15
19
  RSpec::Core::Formatters.register(
16
20
  self,
@@ -21,20 +25,19 @@ module AllureRspec
21
25
  :example_finished
22
26
  )
23
27
 
24
- RSpec::Core::Example.class_eval do
25
- Allure.singleton_methods.each do |method|
26
- ruby2_keywords define_method(method) { |*args, &block| Allure.__send__(method, *args, &block) }
27
- end
28
+ RSpec.configure do |config|
29
+ ids = Allure::TestPlan.test_ids
30
+ names = Allure::TestPlan.test_names
31
+
32
+ config.filter_run_when_matching(*ids.map { |id| { allure_id: id } }) if ids
33
+ config.full_description = names if names
28
34
  end
29
35
 
30
- RSpec.configure do |config|
31
- Allure.configure do |allure_config|
32
- ids = allure_config.test_ids
33
- names = allure_config.test_names
36
+ def initialize(output)
37
+ super
34
38
 
35
- config.filter_run_when_matching(*ids.map { |id| { allure_id: id } }) if ids
36
- config.full_description = names if names
37
- end
39
+ @allure_config = AllureRspec.configuration
40
+ Allure.lifecycle = @lifecycle = Allure::AllureLifecycle.new(@allure_config)
38
41
  end
39
42
 
40
43
  # Start test run
@@ -42,6 +45,10 @@ module AllureRspec
42
45
  # @return [void]
43
46
  def start(_start_notification)
44
47
  lifecycle.clean_results_dir
48
+
49
+ RSpec::Core::Example.class_eval do
50
+ include Allure
51
+ end
45
52
  end
46
53
 
47
54
  # Starts example group
@@ -78,10 +85,48 @@ module AllureRspec
78
85
 
79
86
  private
80
87
 
81
- # Get thread specific lifecycle
82
- # @return [Allure::AllureLifecycle]
83
- def lifecycle
84
- Allure.lifecycle
88
+ attr_reader :lifecycle, :allure_config
89
+
90
+ # Transform example to <Allure::TestResult>
91
+ # @param [RSpec::Core::Example] example
92
+ # @return [Allure::TestResult]
93
+ def test_result(example)
94
+ parser = RspecMetadataParser.new(example, allure_config)
95
+
96
+ Allure::TestResult.new(
97
+ name: example.description,
98
+ description: "Location - #{strip_relative(example.location)}",
99
+ description_html: "Location - #{strip_relative(example.location)}",
100
+ history_id: Digest::MD5.hexdigest(example.id),
101
+ full_name: example.full_description,
102
+ labels: parser.labels,
103
+ links: parser.links,
104
+ status_details: parser.status_details,
105
+ environment: allure_config.environment
106
+ )
107
+ end
108
+
109
+ # Update test status on finish
110
+ # @param [RSpec::Core::Example::ExecutionResult] result
111
+ # @return [Proc]
112
+ def update_test_proc(result)
113
+ Allure::ResultUtils.status_details(result.exception).yield_self do |status_detail|
114
+ proc do |test_case|
115
+ test_case.stage = Allure::Stage::FINISHED
116
+ test_case.status = status(result)
117
+ test_case.status_details.message = status_detail.message
118
+ test_case.status_details.trace = status_detail.trace
119
+ end
120
+ end
121
+ end
122
+
123
+ # Get allure status from result
124
+ # @param [RSpec::Core::Example::ExecutionResult] result
125
+ # @return [Symbol]
126
+ def status(result)
127
+ return Allure::ResultUtils.status(result.exception) if result.status == :failed
128
+
129
+ ALLURE_STATUS[result.status]
85
130
  end
86
131
  end
87
132
  end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllureRspec
4
+ # RSpec metadata parser
5
+ #
6
+ class RspecMetadataParser
7
+ include Utils
8
+
9
+ RSPEC_IGNORED_METADATA = %i[
10
+ absolute_file_path
11
+ block
12
+ described_class
13
+ description
14
+ description_args
15
+ example_group
16
+ execution_result
17
+ file_path
18
+ full_description
19
+ last_run_status
20
+ line_number
21
+ location
22
+ rerun_file_path
23
+ retry
24
+ retry_attempts
25
+ retry_exceptions
26
+ scoped_id
27
+ shared_group_inclusion_backtrace
28
+ type
29
+ ].freeze
30
+
31
+ # Metadata parser instance
32
+ #
33
+ # @param [RSpec::Core::Example] example
34
+ # @param [AllureRspec::RspecConfig] config <description>
35
+ def initialize(example, config)
36
+ @example = example
37
+ @config = config
38
+ end
39
+
40
+ # Get allure labels
41
+ # @return [Array<Allure::Label>]
42
+ def labels
43
+ [
44
+ framework_label,
45
+ package_label,
46
+ test_class_label,
47
+ severity,
48
+ *tag_labels,
49
+ *behavior_labels,
50
+ *suite_labels
51
+ ].select(&:value)
52
+ end
53
+
54
+ # Get attachable links
55
+ # @return [Array<Allure::Link>]
56
+ def links
57
+ matching_links(:tms) + matching_links(:issue)
58
+ end
59
+
60
+ # Get status details
61
+ # @return [Allure::StatusDetails]
62
+ def status_details
63
+ Allure::StatusDetails.new(
64
+ flaky: !metadata[:flaky].nil?,
65
+ muted: !metadata[:muted].nil?,
66
+ known: !metadata[:known].nil?
67
+ )
68
+ end
69
+
70
+ private
71
+
72
+ # @return [RSpec::Core::Example]
73
+ attr_reader :example
74
+
75
+ # @return [AllureRspec::RspecConfig]
76
+ attr_reader :config
77
+
78
+ # Example metadata
79
+ #
80
+ # @return [Hash]
81
+ def metadata
82
+ @metadata ||= example.metadata
83
+ end
84
+
85
+ # Get package label
86
+ # @return [Allure::Label]
87
+ def package_label
88
+ Allure::ResultUtils.package_label(Pathname.new(strip_relative(example.file_path)).parent.to_s)
89
+ end
90
+
91
+ # Get test class label
92
+ #
93
+ # @return [Allure::Label]
94
+ def test_class_label
95
+ Allure::ResultUtils.test_class_label(File.basename(example.file_path, ".rb"))
96
+ end
97
+
98
+ # Get framework label
99
+ # @return [Allure::Label]
100
+ def framework_label
101
+ Allure::ResultUtils.framework_label("rspec")
102
+ end
103
+
104
+ # Get severity
105
+ # @return [String]
106
+ def severity
107
+ Allure::ResultUtils.severity_label(metadata[config.severity_tag] || "normal")
108
+ end
109
+
110
+ # Get test suite labels
111
+ # @return [Array<Allure::Label>]
112
+ def suite_labels
113
+ SuiteLabels.new(example.example_group).fetch
114
+ end
115
+
116
+ # Get custom labels
117
+ # @return [Array<Allure::Label>]
118
+ def tag_labels
119
+ metadata
120
+ .reject { |k| RSPEC_IGNORED_METADATA.include?(k) || special_metadata_tag?(k) }
121
+ .map { |k, v| allure?(k) ? Allure::ResultUtils.tag_label(v) : Allure::ResultUtils.tag_label(k.to_s) }
122
+ end
123
+
124
+ # Get behavior labels
125
+ # @return [Array<Allure::Label>]
126
+ def behavior_labels
127
+ metadata = example.metadata
128
+ epic = metadata[config.epic_tag] || Pathname.new(strip_relative(example.file_path)).parent.to_s
129
+ feature = metadata[config.feature_tag] || example.example_group.description
130
+ story = metadata[config.story_tag]
131
+
132
+ [
133
+ Allure::ResultUtils.epic_label(epic),
134
+ Allure::ResultUtils.feature_label(feature),
135
+ Allure::ResultUtils.story_label(story)
136
+ ]
137
+ end
138
+
139
+ # tms and issue links
140
+ # @param [Symbol] type
141
+ # @return [Array<Allure::Link>]
142
+ def matching_links(type)
143
+ link_pattern = config.public_send("link_#{type}_pattern")
144
+ return [] unless link_pattern
145
+
146
+ metadata
147
+ .select { |k| __send__("#{type}?", k) }.values
148
+ .map { |v| Allure::ResultUtils.public_send("#{type}_link", v, link_pattern) }
149
+ end
150
+
151
+ # Special allure metadata tags
152
+ #
153
+ # @param [Symbol] key
154
+ # @return [boolean]
155
+ def special_metadata_tag?(key)
156
+ tms?(key) || issue?(key) || [
157
+ config.severity_tag,
158
+ config.epic_tag,
159
+ config.feature_tag,
160
+ config.story_tag
161
+ ].include?(key)
162
+ end
163
+
164
+ # Does key match custom allure label
165
+ # @param [Symbol] key
166
+ # @return [boolean]
167
+ def allure?(key)
168
+ key.to_s.match?(/allure(_\d+)?/i)
169
+ end
170
+
171
+ # Does key match tms pattern
172
+ # @param [Symbol] key
173
+ # @return [boolean]
174
+ def tms?(key)
175
+ key.to_s.match?(/#{config.tms_tag}(_\d+)?/i)
176
+ end
177
+
178
+ # Does key match issue pattern
179
+ # @param [Symbol] key
180
+ # @return [boolean]
181
+ def issue?(key)
182
+ key.to_s.match?(/#{config.issue_tag}(_\d+)?/i)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AllureRspec
4
+ # Suite label generator
5
+ #
6
+ class SuiteLabels
7
+ include Utils
8
+
9
+ def initialize(example_group)
10
+ @example_group = example_group
11
+ end
12
+
13
+ # Get test suite labels
14
+ # @return [Array<Allure::Label>]
15
+ def fetch
16
+ parents = example_group.parent_groups.map do |group|
17
+ group.description.empty? ? "Anonymous" : group.description
18
+ end
19
+
20
+ labels = []
21
+ labels << Allure::ResultUtils.suite_label(suite(parents))
22
+ labels << Allure::ResultUtils.parent_suite_label(parent_suite(parents)) if parent_suite(parents)
23
+ labels << Allure::ResultUtils.sub_suite_label(sub_suites(parents)) if sub_suites(parents)
24
+
25
+ labels
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :example_group
31
+
32
+ # @param [Array<String>] parents
33
+ # @return [String]
34
+ def suite(parents)
35
+ parents.length == 1 ? parents.last : parents[-2]
36
+ end
37
+
38
+ # @param [Array<String>] parents
39
+ # @return [String]
40
+ def parent_suite(parents)
41
+ parents.length > 1 ? parents.last : nil
42
+ end
43
+
44
+ # @param [Array<String>] parents
45
+ # @return [String]
46
+ def sub_suites(parents)
47
+ parents.length > 2 ? parents[0..-3].join(" > ") : nil
48
+ end
49
+ end
50
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: allure-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.13.8.2
4
+ version: 2.13.10
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-16 00:00:00.000000000 Z
11
+ date: 2021-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allure-ruby-commons
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.13.8.2
19
+ version: 2.13.10
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.13.8.2
26
+ version: 2.13.10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec-core
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,20 +44,6 @@ dependencies:
44
44
  - - "<"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '4'
47
- - !ruby/object:Gem::Dependency
48
- name: ruby2_keywords
49
- requirement: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - "~>"
52
- - !ruby/object:Gem::Version
53
- version: 0.0.2
54
- type: :runtime
55
- prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- requirements:
58
- - - "~>"
59
- - !ruby/object:Gem::Version
60
- version: 0.0.2
61
47
  description: Cucumber adaptor to generate rich allure test reports
62
48
  email: andrejs.cunskis@gmail.com
63
49
  executables: []
@@ -66,10 +52,11 @@ extra_rdoc_files: []
66
52
  files:
67
53
  - README.md
68
54
  - lib/allure-rspec.rb
55
+ - lib/allure_rspec/_utils.rb
69
56
  - lib/allure_rspec/config.rb
70
57
  - lib/allure_rspec/formatter.rb
71
- - lib/allure_rspec/rspec_model.rb
72
- - lib/allure_rspec/tag_parser.rb
58
+ - lib/allure_rspec/metadata_parser.rb
59
+ - lib/allure_rspec/suite_labels.rb
73
60
  homepage: https://github.com/allure-framework/allure-ruby/tree/master/allure-rspec
74
61
  licenses:
75
62
  - Apache-2.0
@@ -94,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
81
  - !ruby/object:Gem::Version
95
82
  version: '0'
96
83
  requirements: []
97
- rubygems_version: 3.2.3
84
+ rubygems_version: 3.2.15
98
85
  signing_key:
99
86
  specification_version: 4
100
87
  summary: Allure rspec ruby adaptor
@@ -1,121 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "digest"
4
- require "pathname"
5
-
6
- require_relative "tag_parser"
7
-
8
- module AllureRspec
9
- # Support class for transforming rspec test entities in to allure model entities
10
- module AllureRspecModel
11
- include TagParser
12
-
13
- # @return [Hash] allure statuses mapping
14
- ALLURE_STATUS = {
15
- failed: Allure::Status::FAILED,
16
- pending: Allure::Status::SKIPPED,
17
- passed: Allure::Status::PASSED
18
- }.freeze
19
-
20
- # Transform example to <Allure::TestResult>
21
- # @param [RSpec::Core::Example] example
22
- # @return [Allure::TestResult]
23
- def test_result(example)
24
- Allure::TestResult.new(
25
- name: example.description,
26
- description: "Location - #{strip_relative(example.location)}",
27
- description_html: "Location - #{strip_relative(example.location)}",
28
- history_id: Digest::MD5.hexdigest(example.id),
29
- full_name: example.full_description,
30
- labels: labels(example),
31
- links: links(example),
32
- status_details: Allure::StatusDetails.new(**status_detail_tags(example.metadata))
33
- )
34
- end
35
-
36
- # Update test status on finish
37
- # @param [RSpec::Core::Example::ExecutionResult] result
38
- # @return [Proc]
39
- def update_test_proc(result)
40
- Allure::ResultUtils.status_details(result.exception).yield_self do |status_detail|
41
- proc do |test_case|
42
- test_case.stage = Allure::Stage::FINISHED
43
- test_case.status = status(result)
44
- test_case.status_details.message = status_detail.message
45
- test_case.status_details.trace = status_detail.trace
46
- end
47
- end
48
- end
49
-
50
- private
51
-
52
- # @param [RSpec::Core::Example] example
53
- # @return [Array<Allure::Label>]
54
- def links(example)
55
- tms_links(example.metadata) + issue_links(example.metadata)
56
- end
57
-
58
- # Get allure status from result
59
- # @param [RSpec::Core::Example::ExecutionResult] result
60
- # @return [Symbol]
61
- def status(result)
62
- return Allure::ResultUtils.status(result.exception) if result.status == :failed
63
-
64
- ALLURE_STATUS[result.status]
65
- end
66
-
67
- # @param [RSpec::Core::Example] example
68
- # @return [Array<Allure::Label>]
69
- def labels(example)
70
- labels = []
71
- labels << Allure::ResultUtils.framework_label("rspec")
72
- labels << Allure::ResultUtils.feature_label(example.example_group.description)
73
- labels << Allure::ResultUtils.package_label(Pathname.new(strip_relative(example.file_path)).parent.to_s)
74
- labels << Allure::ResultUtils.story_label(example.description)
75
- labels << Allure::ResultUtils.test_class_label(File.basename(example.file_path, ".rb"))
76
- labels << severity(example.metadata)
77
- labels.push(*tag_labels(example.metadata))
78
- labels.push(*suite_labels(example.example_group))
79
-
80
- labels
81
- end
82
-
83
- # Add suite labels
84
- # @param [RSpec::Core::ExampleGroup] example_group
85
- # @return [Array<Allure::Label>]
86
- def suite_labels(example_group)
87
- parents = example_group.parent_groups.map { |group| group.description.empty? ? "Anonymous" : group.description }
88
- labels = []
89
- labels << Allure::ResultUtils.suite_label(suite(parents))
90
- labels << Allure::ResultUtils.parent_suite_label(parent_suite(parents)) if parent_suite(parents)
91
- labels << Allure::ResultUtils.sub_suite_label(sub_suites(parents)) if sub_suites(parents)
92
-
93
- labels
94
- end
95
-
96
- # @param [Array<String>] parents
97
- # @return [String]
98
- def suite(parents)
99
- parents.length == 1 ? parents.last : parents[-2]
100
- end
101
-
102
- # @param [Array<String>] parents
103
- # @return [String]
104
- def parent_suite(parents)
105
- parents.length > 1 ? parents.last : nil
106
- end
107
-
108
- # @param [Array<String>] parents
109
- # @return [String]
110
- def sub_suites(parents)
111
- parents.length > 2 ? parents[0..-3].join(" > ") : nil
112
- end
113
-
114
- # Strip relative ./ form path
115
- # @param [String] path
116
- # @return [String]
117
- def strip_relative(path)
118
- path.gsub("./", "")
119
- end
120
- end
121
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AllureRspec
4
- # RSpec custom tag parser
5
- module TagParser
6
- # Get custom labels
7
- # @param [Hash] metadata
8
- # @return [Array<Allure::Label>]
9
- def tag_labels(metadata)
10
- return [] unless metadata.keys.any? { |k| allure?(k) }
11
-
12
- metadata.select { |k| allure?(k) }.values.map { |v| Allure::ResultUtils.tag_label(v) }
13
- end
14
-
15
- # Get tms links
16
- # @param [Hash] metadata
17
- # @return [Array<Allure::Link>]
18
- def tms_links(metadata)
19
- matching_links(metadata, :tms)
20
- end
21
-
22
- # Get issue links
23
- # @param [Hash] metadata
24
- # @return [Array<Allure::Link>]
25
- def issue_links(metadata)
26
- matching_links(metadata, :issue)
27
- end
28
-
29
- # Get severity
30
- # @param [Hash] metadata
31
- # @return [String]
32
- def severity(metadata)
33
- Allure::ResultUtils.severity_label(metadata[:severity] || "normal")
34
- end
35
-
36
- # Get status details
37
- # @param [Hash] metadata
38
- # @return [Hash<Symbol, Boolean>]
39
- def status_detail_tags(metadata)
40
- {
41
- flaky: !metadata[:flaky].nil?,
42
- muted: !metadata[:muted].nil?,
43
- known: !metadata[:known].nil?
44
- }
45
- end
46
-
47
- private
48
-
49
- # @param [Hash] metadata
50
- # @param [Symbol] type
51
- # @return [Array<Allure::Link>]
52
- def matching_links(metadata, type)
53
- unless AllureRspec.configuration.public_send("link_#{type}_pattern") &&
54
- metadata.keys.any? { |k| __send__("#{type}?", k) }
55
- return []
56
- end
57
-
58
- metadata
59
- .select { |k| __send__("#{type}?", k) }.values
60
- .map { |v| Allure::ResultUtils.public_send("#{type}_link", v) }
61
- end
62
-
63
- # Does key match custom allure label
64
- # @param [Symbol] key
65
- # @return [boolean]
66
- def allure?(key)
67
- key.to_s.match?(/allure(_\d+)?/i)
68
- end
69
-
70
- # Does key match tms pattern
71
- # @param [Symbol] key
72
- # @return [boolean]
73
- def tms?(key)
74
- key.to_s.match?(/tms(_\d+)?/i)
75
- end
76
-
77
- # Does key match issue pattern
78
- # @param [Symbol] key
79
- # @return [boolean]
80
- def issue?(key)
81
- key.to_s.match?(/issue(_\d+)?/i)
82
- end
83
- end
84
- end