allure-cucumber 2.13.4 → 2.13.6.1
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 +4 -4
- data/README.md +29 -21
- data/lib/allure-cucumber.rb +3 -3
- data/lib/allure_cucumber/config.rb +45 -25
- data/lib/allure_cucumber/formatter.rb +25 -29
- data/lib/allure_cucumber/models/cucumber_model.rb +130 -0
- data/lib/allure_cucumber/models/scenario.rb +103 -0
- data/lib/allure_cucumber/models/step.rb +33 -0
- data/lib/allure_cucumber/{tag_parser.rb → models/tag_parser.rb} +16 -18
- metadata +12 -11
- data/lib/allure_cucumber/ast_transformer.rb +0 -40
- data/lib/allure_cucumber/cucumber_model.rb +0 -135
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eec16fa4b2661ebc292fcfe4822f3c53c5af7d66985269696ea79a7fde7ebc30
|
4
|
+
data.tar.gz: 8081549604e82be68e300179457fe6721e79f2eef605c3b848b9808938458f24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4768b05e93476e415640b22bf27463da0e4231bd2176d461046e2994fa43f88433a0d5aa488956c52666f26a002059c447048983e7ea36325cfd485da8afe65f
|
7
|
+
data.tar.gz: 5570eda7e1d86330723f363778542a3a90b93d328a7d413e632037e5ad7556909ac0ff996ea48bdb8b7ebd054d542a04221ac56c8c31f49503b0378ca736aa46
|
data/README.md
CHANGED
@@ -1,44 +1,58 @@
|
|
1
1
|
# Allure Cucumber Adaptor
|
2
|
+
|
2
3
|
[](https://www.rubydoc.info/gems/allure-cucumber)
|
3
4
|
|
4
5
|
This repository contains Allure adaptor for [Cucumber](http://cukes.info/) framework.
|
5
6
|
|
7
|
+
## Cucumber versions
|
8
|
+
|
9
|
+
allure-cucumber versions <= 2.13.4 support only cucumber 3 and lower\
|
10
|
+
allure-cucumber versions >= 2.13.5 only support cucumber 4 and are not backwards compatible with cucumber 3 and lower
|
11
|
+
|
6
12
|
## Installation
|
7
13
|
|
8
14
|
Add this line to your application's Gemfile:
|
9
15
|
|
10
16
|
```ruby
|
11
|
-
gem
|
17
|
+
gem "allure-cucumber"
|
12
18
|
```
|
13
19
|
|
14
20
|
And then execute:
|
15
21
|
|
16
22
|
```bash
|
17
|
-
|
23
|
+
bundle
|
18
24
|
```
|
19
25
|
|
20
26
|
Or install it yourself as:
|
21
27
|
|
22
28
|
```bash
|
23
|
-
|
29
|
+
gem install allure-cucumber
|
30
|
+
```
|
31
|
+
|
32
|
+
Require in "support/env.rb":
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require "allure-cucumber"
|
24
36
|
```
|
25
37
|
|
26
38
|
## Configuration
|
27
39
|
|
28
|
-
Common allure configuration is set via `
|
40
|
+
Common allure configuration is set via `AllureCucumber.configure` method. To change it, add the following in `features/support/env.rb` file:
|
29
41
|
|
30
42
|
```ruby
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
43
|
+
require "allure-cucumber"
|
44
|
+
|
45
|
+
AllureCucumber.configure do |config|
|
46
|
+
config.results_directory = "/whatever/you/like"
|
47
|
+
config.clean_results_directory = true
|
48
|
+
config.logging_level = Logger::INFO
|
35
49
|
# these are used for creating links to bugs or test cases where {} is replaced with keys of relevant items
|
36
|
-
|
37
|
-
|
50
|
+
config.link_tms_pattern = "http://www.jira.com/browse/{}"
|
51
|
+
config.link_issue_pattern = "http://www.jira.com/browse/{}"
|
38
52
|
end
|
39
53
|
```
|
40
54
|
|
41
|
-
By default, allure-cucumber will analyze your cucumber tags looking for Test Management, Issue Management, and Severity
|
55
|
+
By default, allure-cucumber will analyze your cucumber tags looking for Test Management, Issue Management, and Severity tag. Links to TMS and ISSUE and test severity will be displayed in the report. By default these prefixes are used:
|
42
56
|
|
43
57
|
```ruby
|
44
58
|
DEFAULT_TMS_PREFIX = 'TMS:'
|
@@ -58,10 +72,10 @@ Example:
|
|
58
72
|
You can configure these prefixes as well as tms and issue tracker urls like this:
|
59
73
|
|
60
74
|
```ruby
|
61
|
-
AllureCucumber.configure do |
|
62
|
-
|
63
|
-
|
64
|
-
|
75
|
+
AllureCucumber.configure do |config|
|
76
|
+
config.tms_prefix = 'HIPTEST--'
|
77
|
+
config.issue_prefix = 'JIRA++'
|
78
|
+
config.severity_prefix = 'URGENCY:'
|
65
79
|
end
|
66
80
|
```
|
67
81
|
|
@@ -78,12 +92,6 @@ Additional special tags exists for setting status detail of test scenarios, allu
|
|
78
92
|
|
79
93
|
## Usage
|
80
94
|
|
81
|
-
Put the following in your `features/support/env.rb` file:
|
82
|
-
|
83
|
-
```ruby
|
84
|
-
require 'allure-cucumber'
|
85
|
-
```
|
86
|
-
|
87
95
|
Use `--format AllureCucumber::CucumberFormatter --out where/you-want-results` while running cucumber or add it to `cucumber.yml`. Note that cucumber `--out` option overrides `results_directory` set via `Allure.configure` method.
|
88
96
|
|
89
97
|
You can also manually attach screenshots and links to test steps and test cases by interacting with allure lifecycle directly. For more info check out `allure-ruby-commons`
|
data/lib/allure-cucumber.rb
CHANGED
@@ -3,8 +3,8 @@
|
|
3
3
|
|
4
4
|
require "allure-ruby-commons"
|
5
5
|
|
6
|
-
require "allure_cucumber/formatter"
|
7
6
|
require "allure_cucumber/config"
|
7
|
+
require "allure_cucumber/formatter"
|
8
8
|
|
9
9
|
# Main allure-cucumber module providing configuration methods
|
10
10
|
module AllureCucumber
|
@@ -12,7 +12,7 @@ module AllureCucumber
|
|
12
12
|
# Get allure cucumber configuration
|
13
13
|
# @return [Allure::CucumberConfig]
|
14
14
|
def configuration
|
15
|
-
CucumberConfig
|
15
|
+
CucumberConfig.instance
|
16
16
|
end
|
17
17
|
|
18
18
|
# Set allure configuration
|
@@ -20,7 +20,7 @@ module AllureCucumber
|
|
20
20
|
# @yieldreturn [void]
|
21
21
|
# @return [void]
|
22
22
|
def configure
|
23
|
-
yield(
|
23
|
+
yield(configuration)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -1,32 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "singleton"
|
4
|
+
require "forwardable"
|
5
|
+
|
3
6
|
module AllureCucumber
|
4
7
|
# Allure cucumber configuration
|
5
|
-
class CucumberConfig
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
8
|
+
class CucumberConfig < Allure::Config
|
9
|
+
include Singleton
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
# @return [String] default tms tag prefix
|
13
|
+
DEFAULT_TMS_PREFIX = "TMS:"
|
14
|
+
# @return [String] default issue tag prefix
|
15
|
+
DEFAULT_ISSUE_PREFIX = "ISSUE:"
|
16
|
+
# @return [String] default severity tag prefix
|
17
|
+
DEFAULT_SEVERITY_PREFIX = "SEVERITY:"
|
18
|
+
|
19
|
+
def_delegators :@allure_config,
|
20
|
+
:clean_results_directory,
|
21
|
+
:clean_results_directory=,
|
22
|
+
:link_issue_pattern,
|
23
|
+
:link_issue_pattern=,
|
24
|
+
:link_tms_pattern,
|
25
|
+
:link_tms_pattern=,
|
26
|
+
:logging_level,
|
27
|
+
:logging_level=,
|
28
|
+
:results_directory,
|
29
|
+
:results_directory=
|
30
|
+
|
31
|
+
attr_writer :tms_prefix, :issue_prefix, :severity_prefix
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@allure_config = Allure.configuration
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
def tms_prefix
|
39
|
+
@tms_prefix || DEFAULT_TMS_PREFIX
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [String]
|
43
|
+
def issue_prefix
|
44
|
+
@issue_prefix || DEFAULT_ISSUE_PREFIX
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [String]
|
48
|
+
def severity_prefix
|
49
|
+
@severity_prefix || DEFAULT_SEVERITY_PREFIX
|
30
50
|
end
|
31
51
|
end
|
32
52
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "cucumber/core"
|
4
|
+
|
5
|
+
require_relative "models/cucumber_model"
|
4
6
|
|
5
7
|
module AllureCucumber
|
6
8
|
# Main formatter class. Translates cucumber event to allure lifecycle
|
7
9
|
class CucumberFormatter
|
8
|
-
include AllureCucumberModel
|
9
|
-
|
10
10
|
# @return [Hash] hook handler methods
|
11
11
|
HOOK_HANDLERS = {
|
12
12
|
"Before hook" => :start_prepare_fixture,
|
@@ -25,6 +25,8 @@ module AllureCucumber
|
|
25
25
|
c.results_directory = config.out_stream if config.out_stream.is_a?(String)
|
26
26
|
end
|
27
27
|
|
28
|
+
@cucumber_model = AllureCucumberModel.new(config)
|
29
|
+
|
28
30
|
config.on_event(:test_run_started, &method(:on_test_run_started))
|
29
31
|
config.on_event(:test_case_started, &method(:on_test_case_started))
|
30
32
|
config.on_event(:test_step_started, &method(:on_test_step_started))
|
@@ -33,48 +35,46 @@ module AllureCucumber
|
|
33
35
|
end
|
34
36
|
|
35
37
|
# Clean test result directory before starting run
|
36
|
-
# @param [Cucumber::Events::TestRunStarted
|
38
|
+
# @param [Cucumber::Events::TestRunStarted] _event
|
37
39
|
# @return [void]
|
38
40
|
def on_test_run_started(_event)
|
39
41
|
lifecycle.clean_results_dir
|
40
42
|
end
|
41
43
|
|
42
44
|
# Handle test case started event
|
43
|
-
# @param [Cucumber::
|
45
|
+
# @param [Cucumber::Events::TestCaseStarted] event
|
44
46
|
# @return [void]
|
45
47
|
def on_test_case_started(event)
|
46
48
|
lifecycle.start_test_container(Allure::TestResultContainer.new(name: event.test_case.name))
|
47
|
-
lifecycle.start_test_case(test_result(event.test_case))
|
49
|
+
lifecycle.start_test_case(cucumber_model.test_result(event.test_case))
|
48
50
|
end
|
49
51
|
|
50
52
|
# Handle test step started event
|
51
|
-
# @param [Cucumber::
|
53
|
+
# @param [Cucumber::Events::TestStepStarted] event
|
52
54
|
# @return [void]
|
53
55
|
def on_test_step_started(event)
|
54
|
-
|
56
|
+
event.test_step.hook? ? handle_hook_started(event.test_step) : handle_step_started(event.test_step)
|
55
57
|
end
|
56
58
|
|
57
59
|
# Handle test step finished event
|
58
|
-
# @param [Cucumber::
|
60
|
+
# @param [Cucumber::Events::TestStepFinished] event
|
59
61
|
# @return [void]
|
60
62
|
def on_test_step_finished(event)
|
61
|
-
return if prepare_world_hook?(event.test_step)
|
62
|
-
|
63
63
|
update_block = proc do |step|
|
64
64
|
step.stage = Allure::Stage::FINISHED
|
65
65
|
step.status = ALLURE_STATUS.fetch(event.result.to_sym, Allure::Status::BROKEN)
|
66
66
|
end
|
67
|
-
step_type =
|
67
|
+
step_type = event.test_step.hook? ? "fixture" : "test_step"
|
68
68
|
|
69
69
|
lifecycle.public_send("update_#{step_type}", &update_block)
|
70
70
|
lifecycle.public_send("stop_#{step_type}")
|
71
71
|
end
|
72
72
|
|
73
73
|
# Handle test case finished event
|
74
|
-
# @param [Cucumber::
|
74
|
+
# @param [Cucumber::Events::TestCaseFinished] event
|
75
75
|
# @return [void]
|
76
76
|
def on_test_case_finished(event)
|
77
|
-
failure_details = failure_details(event.result)
|
77
|
+
failure_details = cucumber_model.failure_details(event.result)
|
78
78
|
status = ALLURE_STATUS.fetch(event.result.to_sym, Allure::Status::BROKEN)
|
79
79
|
lifecycle.update_test_case do |test_case|
|
80
80
|
test_case.stage = Allure::Stage::FINISHED
|
@@ -89,30 +89,26 @@ module AllureCucumber
|
|
89
89
|
|
90
90
|
private
|
91
91
|
|
92
|
-
|
93
|
-
# @return [Boolean]
|
94
|
-
def hook?(test_step)
|
95
|
-
HOOK_HANDLERS.key?(test_step.text)
|
96
|
-
end
|
92
|
+
attr_accessor :cucumber_model
|
97
93
|
|
98
|
-
#
|
99
|
-
# @return [
|
100
|
-
def
|
101
|
-
|
94
|
+
# Get thread specific lifecycle
|
95
|
+
# @return [Allure::AllureLifecycle]
|
96
|
+
def lifecycle
|
97
|
+
Allure.lifecycle
|
102
98
|
end
|
103
99
|
|
104
100
|
# @param [Cucumber::Core::Test::Step] test_step
|
105
101
|
# @return [void]
|
106
102
|
def handle_step_started(test_step)
|
107
|
-
|
103
|
+
step = cucumber_model.step_result(test_step)
|
104
|
+
lifecycle.start_test_step(step[:allure_step])
|
105
|
+
step[:attachments].each { |att| lifecycle.write_attachment(att[:source], att[:allure_attachment]) }
|
108
106
|
end
|
109
107
|
|
110
|
-
# @param [Cucumber::Core::Test::
|
108
|
+
# @param [Cucumber::Core::Test::HookStep] hook_step
|
111
109
|
# @return [void]
|
112
|
-
def handle_hook_started(
|
113
|
-
|
114
|
-
|
115
|
-
lifecycle.public_send(HOOK_HANDLERS[test_step.text], fixture_result(test_step))
|
110
|
+
def handle_hook_started(hook_step)
|
111
|
+
lifecycle.public_send(HOOK_HANDLERS[hook_step.text], cucumber_model.fixture_result(hook_step))
|
116
112
|
end
|
117
113
|
end
|
118
114
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
require "cucumber/core"
|
5
|
+
require "cucumber/formatter/ast_lookup"
|
6
|
+
|
7
|
+
require_relative "scenario"
|
8
|
+
require_relative "step"
|
9
|
+
require_relative "tag_parser"
|
10
|
+
|
11
|
+
module AllureCucumber
|
12
|
+
# Support class for transforming cucumber test entities in to allure model entities
|
13
|
+
class AllureCucumberModel
|
14
|
+
include TagParser
|
15
|
+
|
16
|
+
# @param [Cucumber::Configuration] config
|
17
|
+
def initialize(config)
|
18
|
+
@ast_lookup = Cucumber::Formatter::AstLookup.new(config)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Convert to allure test result
|
22
|
+
# @param [Cucumber::Core::Test::Case] test_case
|
23
|
+
# @return [Allure::TestResult]
|
24
|
+
def test_result(test_case)
|
25
|
+
scenario = Scenario.new(test_case, ast_lookup)
|
26
|
+
|
27
|
+
Allure::TestResult.new(
|
28
|
+
name: scenario.name,
|
29
|
+
description: scenario.description,
|
30
|
+
description_html: scenario.description,
|
31
|
+
history_id: scenario.id,
|
32
|
+
full_name: "#{scenario.feature_name}: #{scenario.name}",
|
33
|
+
labels: labels(scenario),
|
34
|
+
links: links(scenario),
|
35
|
+
parameters: parameters(scenario),
|
36
|
+
status_details: Allure::StatusDetails.new(**status_detail_tags(scenario.tags)),
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convert to allure step result
|
41
|
+
# @param [Cucumber::Core::Test::Step] test_step
|
42
|
+
# @return [Hash]
|
43
|
+
def step_result(test_step)
|
44
|
+
step = Step.new(ast_lookup.step_source(test_step))
|
45
|
+
attachments = step_attachments(step)
|
46
|
+
allure_step = Allure::StepResult.new(
|
47
|
+
name: step.name,
|
48
|
+
attachments: attachments.map { |att| att[:allure_attachment] },
|
49
|
+
)
|
50
|
+
|
51
|
+
{ allure_step: allure_step, attachments: attachments }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Convert to allure step result
|
55
|
+
# @param [Cucumber::Core::Test::HookStep] hook_step
|
56
|
+
# @return [Allure::StepResult]
|
57
|
+
def fixture_result(hook_step)
|
58
|
+
Allure::FixtureResult.new(name: hook_step.location.to_s.split("/").last)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get failure details
|
62
|
+
# @param [Cucumber::Core::Test::Result] result
|
63
|
+
# @return [Hash<Symbol, String>]
|
64
|
+
def failure_details(result)
|
65
|
+
return { message: result.exception.message, trace: result.exception.backtrace.join("\n") } if result.failed?
|
66
|
+
return { message: result.message, trace: result.backtrace.join("\n") } if result.undefined?
|
67
|
+
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
attr_reader :ast_lookup, :lifecycle
|
74
|
+
|
75
|
+
# @param [Scenario] scenario
|
76
|
+
# @return [Array<Allure::Label>]
|
77
|
+
def labels(scenario)
|
78
|
+
labels = []
|
79
|
+
labels << Allure::ResultUtils.framework_label("cucumber")
|
80
|
+
labels << Allure::ResultUtils.feature_label(scenario.feature_name)
|
81
|
+
labels << Allure::ResultUtils.package_label(scenario.feature_folder)
|
82
|
+
labels << Allure::ResultUtils.suite_label(scenario.feature_name)
|
83
|
+
labels << Allure::ResultUtils.story_label(scenario.name)
|
84
|
+
labels << Allure::ResultUtils.test_class_label(scenario.feature_file_name)
|
85
|
+
unless scenario.tags.empty?
|
86
|
+
labels.push(*tag_labels(scenario.tags))
|
87
|
+
labels << severity(scenario.tags)
|
88
|
+
end
|
89
|
+
|
90
|
+
labels
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param [Cucumber::Core::Test::Case] test_case
|
94
|
+
# @return [Array<Allure::Link>]
|
95
|
+
def links(test_case)
|
96
|
+
tms_links(test_case.tags) + issue_links(test_case.tags)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param [AllureCucumber::Scenario] scenario
|
100
|
+
# @return [Array<Allure::Parameter>]
|
101
|
+
def parameters(scenario)
|
102
|
+
scenario.examples.map { |k, v| Allure::Parameter.new(k, v) }
|
103
|
+
end
|
104
|
+
|
105
|
+
# @param [Step] step
|
106
|
+
# @return [Array<Allure::Attachment>]
|
107
|
+
def step_attachments(step)
|
108
|
+
[data_table_attachment(step), docstring_attachment(step)].compact
|
109
|
+
end
|
110
|
+
|
111
|
+
# @param [Step] step
|
112
|
+
# @return [Allure::Attachment]
|
113
|
+
def data_table_attachment(step)
|
114
|
+
return unless step.data_table
|
115
|
+
|
116
|
+
attachment = Allure::ResultUtils.prepare_attachment("data-table", Allure::ContentType::CSV)
|
117
|
+
csv = step.data_table.rows.each_with_object([]) { |row, arr| arr.push(row.cells.map(&:value).to_csv) }.join("")
|
118
|
+
{ source: csv, allure_attachment: attachment }
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param [Step] step
|
122
|
+
# @return [String]
|
123
|
+
def docstring_attachment(step)
|
124
|
+
return unless step.doc_string
|
125
|
+
|
126
|
+
attachment = Allure::ResultUtils.prepare_attachment("docstring", Allure::ContentType::TXT)
|
127
|
+
{ source: step.doc_string.content, allure_attachment: attachment }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "digest"
|
4
|
+
|
5
|
+
module AllureCucumber
|
6
|
+
# Cucumber scenario wrapper class
|
7
|
+
class Scenario
|
8
|
+
# @param [Cucumber::Core::Test::Case] test_case
|
9
|
+
# @param [Cucumber::Formatter::AstLookup] ast_lookup
|
10
|
+
def initialize(test_case, ast_lookup)
|
11
|
+
@test_case = test_case
|
12
|
+
@feature = ast_lookup.gherkin_document(test_case.location.file).feature
|
13
|
+
@scenario_source = ast_lookup.scenario_source(test_case)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Unique scenario id
|
17
|
+
# @return [String]
|
18
|
+
def id
|
19
|
+
@id ||= Digest::MD5.hexdigest(test_case.inspect)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Feature name scenario belongs to
|
23
|
+
# @return [String]
|
24
|
+
def feature_name
|
25
|
+
@feature_name ||= feature.name
|
26
|
+
end
|
27
|
+
|
28
|
+
# Scenario name
|
29
|
+
# @return [String]
|
30
|
+
def name
|
31
|
+
@name ||= scenario_outline? ? "#{scenario.name}, #{example_row}" : scenario.name
|
32
|
+
end
|
33
|
+
|
34
|
+
# Scenario description or it's location
|
35
|
+
# @return [String]
|
36
|
+
def description
|
37
|
+
@description ||= begin
|
38
|
+
scenario.description.empty? ? "Location - #{test_case.location}" : scenario.description.strip
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Scenario outline row parameters
|
43
|
+
# @return [Hash<String, String>]
|
44
|
+
def examples
|
45
|
+
@examples ||= scenario_outline? ? outline_parameters : {}
|
46
|
+
end
|
47
|
+
|
48
|
+
# Scenario tags
|
49
|
+
# @return [Array<String>]
|
50
|
+
def tags
|
51
|
+
@tags ||= test_case.tags.map(&:name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Feature file name
|
55
|
+
# @return [String]
|
56
|
+
def feature_file_name
|
57
|
+
@feature_file_name ||= test_case.location.file.split("/").last.gsub(".feature", "")
|
58
|
+
end
|
59
|
+
|
60
|
+
# Feature folder
|
61
|
+
# @return [String]
|
62
|
+
def feature_folder
|
63
|
+
@feature_folder ||= test_case.location.file.split("/")[-2]
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
attr_reader :test_case, :scenario_source, :feature
|
69
|
+
|
70
|
+
# Is scenario outline
|
71
|
+
# @return [Boolean]
|
72
|
+
def scenario_outline?
|
73
|
+
scenario_source.type == :ScenarioOutline
|
74
|
+
end
|
75
|
+
|
76
|
+
# Cucumber scenario object
|
77
|
+
# @return [
|
78
|
+
# Cucumber::Messages::GherkinDocument::Feature::Scenario,
|
79
|
+
# Cucumber::Messages::GherkinDocument::Feature::ScenarioOutline
|
80
|
+
# ]
|
81
|
+
def scenario
|
82
|
+
@scenario ||= scenario_outline? ? scenario_source.scenario_outline : scenario_source.scenario
|
83
|
+
end
|
84
|
+
|
85
|
+
# Scenario outline example row
|
86
|
+
# @return [String]
|
87
|
+
def example_row
|
88
|
+
@example_row ||= begin
|
89
|
+
"Examples (##{scenario_source.examples.table_body.index { |row| row.id == scenario_source.row.id } + 1})"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Scenario outline row parameters
|
94
|
+
# @return [Hash<String, String>]
|
95
|
+
def outline_parameters
|
96
|
+
@outline_parameters ||= begin
|
97
|
+
names = scenario_source.examples.table_header.cells.map(&:value)
|
98
|
+
values = scenario_source.row.cells.map(&:value)
|
99
|
+
names.zip(values).to_h
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AllureCucumber
|
4
|
+
# Cucumber step wrapper class
|
5
|
+
class Step
|
6
|
+
# @param [Cucumber::Formatter::AstLookup::StepSource] step_source
|
7
|
+
def initialize(step_source)
|
8
|
+
@step = step_source.step
|
9
|
+
end
|
10
|
+
|
11
|
+
# Step name
|
12
|
+
# @return [String]
|
13
|
+
def name
|
14
|
+
@name ||= "#{step.keyword}#{step.text}"
|
15
|
+
end
|
16
|
+
|
17
|
+
# Step data table
|
18
|
+
# @return [Cucumber::Messages::GherkinDocument::Feature::Step::DataTable]
|
19
|
+
def data_table
|
20
|
+
@data_table ||= step.data_table
|
21
|
+
end
|
22
|
+
|
23
|
+
# Step docstring
|
24
|
+
# @return [String]
|
25
|
+
def doc_string
|
26
|
+
@doc_string ||= step.doc_string
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :step
|
32
|
+
end
|
33
|
+
end
|
@@ -1,46 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "config"
|
4
|
-
|
5
3
|
module AllureCucumber
|
6
4
|
# Cucumber tag parser helper methods
|
7
5
|
module TagParser
|
8
|
-
# @param [Array<
|
6
|
+
# @param [Array<String>] tags
|
9
7
|
# @return [Array<Allure::Label>]
|
10
8
|
def tag_labels(tags)
|
11
9
|
tags
|
12
|
-
.reject { |tag| reserved?(tag
|
13
|
-
.map { |tag| Allure::ResultUtils.tag_label(tag.
|
10
|
+
.reject { |tag| reserved?(tag) }
|
11
|
+
.map { |tag| Allure::ResultUtils.tag_label(tag.delete_prefix("@")) }
|
14
12
|
end
|
15
13
|
|
16
|
-
# @param [Array<
|
14
|
+
# @param [Array<String>] tags
|
17
15
|
# @return [Array<Allure::Link>]
|
18
16
|
def tms_links(tags)
|
19
|
-
return [] unless
|
17
|
+
return [] unless AllureCucumber.configuration.link_tms_pattern
|
20
18
|
|
21
19
|
matching_links(tags, :tms)
|
22
20
|
end
|
23
21
|
|
24
|
-
# @param [Array<
|
22
|
+
# @param [Array<String>] tags
|
25
23
|
# @return [Array<Allure::Link>]
|
26
24
|
def issue_links(tags)
|
27
|
-
return [] unless
|
25
|
+
return [] unless AllureCucumber.configuration.link_issue_pattern
|
28
26
|
|
29
27
|
matching_links(tags, :issue)
|
30
28
|
end
|
31
29
|
|
32
|
-
# @param [Array<
|
30
|
+
# @param [Array<String>] tags
|
33
31
|
# @return [Allure::Label]
|
34
32
|
def severity(tags)
|
35
33
|
severity_pattern = reserved_patterns[:severity]
|
36
34
|
severity = tags
|
37
|
-
.detect { |tag| tag.
|
35
|
+
.detect { |tag| tag.match?(severity_pattern) }
|
38
36
|
&.match(severity_pattern)&.[](:severity) || "normal"
|
39
37
|
|
40
38
|
Allure::ResultUtils.severity_label(severity)
|
41
39
|
end
|
42
40
|
|
43
|
-
# @param [Array<
|
41
|
+
# @param [Array<String>] tags
|
44
42
|
# @return [Hash<Symbol, Boolean>]
|
45
43
|
def status_detail_tags(tags)
|
46
44
|
{
|
@@ -52,22 +50,22 @@ module AllureCucumber
|
|
52
50
|
|
53
51
|
private
|
54
52
|
|
55
|
-
# @param [Array<
|
53
|
+
# @param [Array<String>] tags
|
56
54
|
# @param [Symbol] type
|
57
55
|
# @return [Array<Allure::Link>]
|
58
56
|
def matching_links(tags, type)
|
59
57
|
pattern = reserved_patterns[type]
|
60
58
|
tags
|
61
|
-
.select { |tag| tag.
|
62
|
-
.map { |tag| tag.
|
59
|
+
.select { |tag| tag.match?(pattern) }
|
60
|
+
.map { |tag| tag.match(pattern) { |match| Allure::ResultUtils.public_send("#{type}_link", match[type]) } }
|
63
61
|
end
|
64
62
|
|
65
63
|
# @return [Hash<Symbol, Regexp>]
|
66
64
|
def reserved_patterns
|
67
65
|
@reserved_patterns ||= {
|
68
|
-
tms: /@#{
|
69
|
-
issue: /@#{
|
70
|
-
severity: /@#{
|
66
|
+
tms: /@#{AllureCucumber.configuration.tms_prefix}(?<tms>\S+)/,
|
67
|
+
issue: /@#{AllureCucumber.configuration.issue_prefix}(?<issue>\S+)/,
|
68
|
+
severity: /@#{AllureCucumber.configuration.severity_prefix}(?<severity>\S+)/,
|
71
69
|
flaky: /@flaky/,
|
72
70
|
muted: /@muted/,
|
73
71
|
known: /@known/,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: allure-cucumber
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.13.
|
4
|
+
version: 2.13.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrejs Cunskis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: allure-ruby-commons
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.13.
|
19
|
+
version: 2.13.6.1
|
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.
|
26
|
+
version: 2.13.6.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: cucumber
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 4.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 4.0.0
|
41
41
|
description: Cucumber adaptor to generate rich allure test reports
|
42
42
|
email: andrejs.cunskis@gmail.com
|
43
43
|
executables: []
|
@@ -46,11 +46,12 @@ extra_rdoc_files: []
|
|
46
46
|
files:
|
47
47
|
- README.md
|
48
48
|
- lib/allure-cucumber.rb
|
49
|
-
- lib/allure_cucumber/ast_transformer.rb
|
50
49
|
- lib/allure_cucumber/config.rb
|
51
|
-
- lib/allure_cucumber/cucumber_model.rb
|
52
50
|
- lib/allure_cucumber/formatter.rb
|
53
|
-
- lib/allure_cucumber/
|
51
|
+
- lib/allure_cucumber/models/cucumber_model.rb
|
52
|
+
- lib/allure_cucumber/models/scenario.rb
|
53
|
+
- lib/allure_cucumber/models/step.rb
|
54
|
+
- lib/allure_cucumber/models/tag_parser.rb
|
54
55
|
homepage: https://github.com/allure-framework/allure-ruby
|
55
56
|
licenses:
|
56
57
|
- Apache-2.0
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AllureCucumber
|
4
|
-
# Cucumber::Core::Ast is removed in cucumber-core 4.0 version.
|
5
|
-
# This will have to be updated accordingly, once stable version rolls out
|
6
|
-
module AstTransformer
|
7
|
-
# Get scenario object
|
8
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
9
|
-
# @return [Cucumber::Core::Ast::Scenario, Cucumber::Core::Ast::ScenarioOutline]
|
10
|
-
def scenario(test_case)
|
11
|
-
test_case.source.detect do |it|
|
12
|
-
it.is_a?(Cucumber::Core::Ast::Scenario) || it.is_a?(Cucumber::Core::Ast::ScenarioOutline)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Get step object
|
17
|
-
# @param [Cucumber::Core::Test::Step] test_step
|
18
|
-
# @return [Cucumber::Core::Ast::Step]
|
19
|
-
def step(test_step)
|
20
|
-
test_step.source.detect { |it| it.is_a?(Cucumber::Core::Ast::Step) }
|
21
|
-
end
|
22
|
-
|
23
|
-
# Get scenario outline example row
|
24
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
25
|
-
# @return [Cucumber::Core::Ast::ExamplesTable::Row]
|
26
|
-
def example_row(test_case)
|
27
|
-
test_case.source.detect { |it| it.is_a?(Cucumber::Core::Ast::ExamplesTable::Row) }
|
28
|
-
end
|
29
|
-
|
30
|
-
# Get step multiline argument
|
31
|
-
# @param [Cucumber::Core::Test::Step] test_step
|
32
|
-
# @return [Cucumber::Core::Ast::DataTable, String]
|
33
|
-
def multiline_arg(test_step)
|
34
|
-
multiline_arg = step(test_step).multiline_arg
|
35
|
-
return if multiline_arg.is_a?(Cucumber::Core::Ast::EmptyMultilineArgument)
|
36
|
-
|
37
|
-
multiline_arg
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,135 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "cucumber"
|
4
|
-
require "cucumber/core"
|
5
|
-
require "digest"
|
6
|
-
require "csv"
|
7
|
-
|
8
|
-
require_relative "ast_transformer"
|
9
|
-
require_relative "tag_parser"
|
10
|
-
|
11
|
-
module AllureCucumber
|
12
|
-
# Support class for transforming cucumber test entities in to allure model entities
|
13
|
-
module AllureCucumberModel
|
14
|
-
include AstTransformer
|
15
|
-
include TagParser
|
16
|
-
|
17
|
-
# Convert to allure test result
|
18
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
19
|
-
# @return [TestResult]
|
20
|
-
def test_result(test_case)
|
21
|
-
Allure::TestResult.new(
|
22
|
-
name: test_case.name,
|
23
|
-
description: description(test_case),
|
24
|
-
description_html: description(test_case),
|
25
|
-
history_id: Digest::MD5.hexdigest(test_case.inspect),
|
26
|
-
full_name: "#{test_case.feature.name}: #{test_case.name}",
|
27
|
-
labels: labels(test_case),
|
28
|
-
links: links(test_case),
|
29
|
-
parameters: parameters(test_case) || [],
|
30
|
-
status_details: Allure::StatusDetails.new(**status_detail_tags(test_case.tags.map(&:name))),
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Convert to allure step result
|
35
|
-
# @param [Cucumber::Core::Test::Step] test_step
|
36
|
-
# @return [StepResult]
|
37
|
-
def step_result(test_step)
|
38
|
-
Allure::StepResult.new(
|
39
|
-
name: "#{step(test_step).keyword}#{test_step.text}",
|
40
|
-
attachments: [multiline_arg_attachment(test_step)].compact,
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Convert to allure step result
|
45
|
-
# @param [Cucumber::Core::Test::Step] test_step
|
46
|
-
# @return [StepResult]
|
47
|
-
def fixture_result(test_step)
|
48
|
-
location = test_step.location.to_s.split("/").last
|
49
|
-
Allure::FixtureResult.new(name: location)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Get failure details
|
53
|
-
# @param [Cucumber::Core::Test::Result] result <description>
|
54
|
-
# @return [Hash<Symbol, String>]
|
55
|
-
def failure_details(result)
|
56
|
-
return { message: result.exception.message, trace: result.exception.backtrace.join("\n") } if result.failed?
|
57
|
-
return { message: result.message, trace: result.backtrace.join("\n") } if result.undefined?
|
58
|
-
|
59
|
-
{}
|
60
|
-
end
|
61
|
-
|
62
|
-
# Get thread specific lifecycle
|
63
|
-
# @return [Allure::AllureLifecycle]
|
64
|
-
def lifecycle
|
65
|
-
Allure.lifecycle
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
71
|
-
# @return [Array<Allure::Label>]
|
72
|
-
def labels(test_case)
|
73
|
-
labels = []
|
74
|
-
labels << Allure::ResultUtils.framework_label("cucumber")
|
75
|
-
labels << Allure::ResultUtils.feature_label(test_case.feature.name)
|
76
|
-
labels << Allure::ResultUtils.package_label(test_case.feature.name)
|
77
|
-
labels << Allure::ResultUtils.suite_label(test_case.feature.name)
|
78
|
-
labels << Allure::ResultUtils.story_label(test_case.name)
|
79
|
-
labels << Allure::ResultUtils.test_class_label(test_case.name)
|
80
|
-
unless test_case.tags.empty?
|
81
|
-
labels.push(*tag_labels(test_case.tags))
|
82
|
-
labels << severity(test_case.tags)
|
83
|
-
end
|
84
|
-
|
85
|
-
labels
|
86
|
-
end
|
87
|
-
|
88
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
89
|
-
# @return [Array<Allure::Link>]
|
90
|
-
def links(test_case)
|
91
|
-
return [] unless test_case.tags
|
92
|
-
|
93
|
-
tms_links(test_case.tags) + issue_links(test_case.tags)
|
94
|
-
end
|
95
|
-
|
96
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
97
|
-
# @return [Array<Allure::Parameter>]
|
98
|
-
def parameters(test_case)
|
99
|
-
example_row(test_case)&.values&.map { |value| Allure::Parameter.new("argument", value) }
|
100
|
-
end
|
101
|
-
|
102
|
-
# @param [Cucumber::Core::Test::Case] test_case
|
103
|
-
# @return [String]
|
104
|
-
def description(test_case)
|
105
|
-
scenario = scenario(test_case)
|
106
|
-
scenario.description.empty? ? "Location - #{scenario.file_colon_line}" : scenario.description.strip
|
107
|
-
end
|
108
|
-
|
109
|
-
# @param [Cucumber::Core::Test::Step] test_step
|
110
|
-
# @return [Allure::Attachment]
|
111
|
-
def multiline_arg_attachment(test_step)
|
112
|
-
arg = multiline_arg(test_step)
|
113
|
-
return unless arg
|
114
|
-
|
115
|
-
arg.data_table? ? data_table_attachment(arg) : docstring_attachment(arg)
|
116
|
-
end
|
117
|
-
|
118
|
-
# @param [Cucumber::Core::Ast::DataTable] multiline_arg
|
119
|
-
# @return [Allure::Attachment]
|
120
|
-
def data_table_attachment(multiline_arg)
|
121
|
-
attachment = lifecycle.prepare_attachment("data-table", Allure::ContentType::CSV)
|
122
|
-
csv = multiline_arg.raw.each_with_object([]) { |row, arr| arr.push(row.to_csv) }.join("")
|
123
|
-
lifecycle.write_attachment(csv, attachment)
|
124
|
-
attachment
|
125
|
-
end
|
126
|
-
|
127
|
-
# @param [String] multiline_arg
|
128
|
-
# @return [String]
|
129
|
-
def docstring_attachment(multiline_arg)
|
130
|
-
attachment = lifecycle.prepare_attachment("docstring", Allure::ContentType::TXT)
|
131
|
-
lifecycle.write_attachment(multiline_arg.content, attachment)
|
132
|
-
attachment
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|