allure-cucumber 2.13.4 → 2.13.5.rc.1

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: 6d8e51c721ebb6ab689c0b0a4d0403f0985ce78dcfed3c7636ab373d6a022d01
4
- data.tar.gz: 38e5d9e0f65921e12e16b097c6cbbbe7525f7ced18d64f9d107f05be3eb309e0
3
+ metadata.gz: 660dd75c5884bb993804ca888ccb2babc2e997bf38a3c4c12105dfffe9948394
4
+ data.tar.gz: 06fd91978393b639e8d92b6b87b7ce752778d254a5a50caf19565d34fefd9f31
5
5
  SHA512:
6
- metadata.gz: dcce7431269029e6193e1465c1b42daaed2cb0890034654a0310fc7e63dbcd6000f30c6e2782ed4d86828858de50a665b80e15423a566a4fa7194782ac9548e5
7
- data.tar.gz: 0a66d830ccb8db25ac1a843ee18ca286ec2a951f671064d100d7deab67d7b1cf97615ab5caec171018ebe1c6603d7b33bc11c318ace76eb5bc0a80f408a4d5cd
6
+ metadata.gz: dec76bf5806c56bfaa484797b2e27e794dae083ab48cbd741e654cd72adf9e19e280723be0d96c3a6b218c826dc4caa757883e22427eb81273ea39f1bca561b6
7
+ data.tar.gz: 2fdc18e522ead6101e5fab6d73e973861bc576167a778b268cc3eaf32e0e45a9866df8f93860705c09c33cd2dfbe04694bb6258508414578f32fa193e40badd0
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Allure Cucumber Adaptor
2
+
2
3
  [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/gems/allure-cucumber)
3
4
 
4
5
  This repository contains Allure adaptor for [Cucumber](http://cukes.info/) framework.
@@ -14,15 +15,20 @@ gem 'allure-cucumber'
14
15
  And then execute:
15
16
 
16
17
  ```bash
17
- $ bundle
18
+ bundle
18
19
  ```
19
20
 
20
21
  Or install it yourself as:
21
22
 
22
23
  ```bash
23
- $ gem install allure-cucumber
24
+ gem install allure-cucumber
24
25
  ```
25
26
 
27
+ ## Cucumber versions
28
+
29
+ allure-cucumber versions <= 2.13.4 support only cucumber 3 and lower\
30
+ allure-cucumber versions >= 2.13.5 only support cucumber 4 and are not backwards compatible with cucumber 3 and lower
31
+
26
32
  ## Configuration
27
33
 
28
34
  Common allure configuration is set via `Allure.configure` method. To change id, add the following in `features/support/env.rb` file:
@@ -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
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "cucumber_model"
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<Type>] _event
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::Core::Events::TestCaseStarted] event
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::Core::Events::TestStepStarted] event
53
+ # @param [Cucumber::Events::TestStepStarted] event
52
54
  # @return [void]
53
55
  def on_test_step_started(event)
54
- hook?(event.test_step) ? handle_hook_started(event.test_step) : handle_step_started(event.test_step)
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::Core::Events::TestStepFinished] event
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 = hook?(event.test_step) ? "fixture" : "test_step"
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::Core::Events::TestCaseFinished] event
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
- # @param [Cucumber::Core::Test::Step] test_step <description>
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
- # @param [Cucumber::Core::Test::Step] test_step
99
- # @return [Boolean]
100
- def prepare_world_hook?(test_step)
101
- hook?(test_step) && test_step.inspect.include?("prepare_world.rb")
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
- lifecycle.start_test_step(step_result(test_step))
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::Step] test_step
108
+ # @param [Cucumber::Core::Test::HookStep] hook_step
111
109
  # @return [void]
112
- def handle_hook_started(test_step)
113
- return if prepare_world_hook?(test_step)
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,19 +1,17 @@
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<Cucumber::Core::Ast::Tag>] tags
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.name) }
13
- .map { |tag| Allure::ResultUtils.tag_label(tag.name.delete_prefix("@")) }
10
+ .reject { |tag| reserved?(tag) }
11
+ .map { |tag| Allure::ResultUtils.tag_label(tag.delete_prefix("@")) }
14
12
  end
15
13
 
16
- # @param [Array<Cucumber::Core::Ast::Tag>] tags
14
+ # @param [Array<String>] tags
17
15
  # @return [Array<Allure::Link>]
18
16
  def tms_links(tags)
19
17
  return [] unless Allure::Config.link_tms_pattern
@@ -21,7 +19,7 @@ module AllureCucumber
21
19
  matching_links(tags, :tms)
22
20
  end
23
21
 
24
- # @param [Array<Cucumber::Core::Ast::Tag>] tags
22
+ # @param [Array<String>] tags
25
23
  # @return [Array<Allure::Link>]
26
24
  def issue_links(tags)
27
25
  return [] unless Allure::Config.link_issue_pattern
@@ -29,18 +27,18 @@ module AllureCucumber
29
27
  matching_links(tags, :issue)
30
28
  end
31
29
 
32
- # @param [Array<Cucumber::Core::Ast::Tag>] tags
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.name.match?(severity_pattern) }&.name
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<Cucumber::Core::Ast::Tag>] tags
41
+ # @param [Array<String>] tags
44
42
  # @return [Hash<Symbol, Boolean>]
45
43
  def status_detail_tags(tags)
46
44
  {
@@ -52,14 +50,14 @@ module AllureCucumber
52
50
 
53
51
  private
54
52
 
55
- # @param [Array<Cucumber::Core::Ast::Tag>] tags
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.name.match?(pattern) }
62
- .map { |tag| tag.name.match(pattern) { |match| Allure::ResultUtils.public_send("#{type}_link", match[type]) } }
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>]
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
4
+ version: 2.13.5.rc.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-02-25 00:00:00.000000000 Z
11
+ date: 2020-03-28 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.4
19
+ version: 2.13.5.rc.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.4
26
+ version: 2.13.5.rc.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: '3.1'
33
+ version: 4.0.0.rc5
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: '3.1'
40
+ version: 4.0.0.rc5
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/tag_parser.rb
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
@@ -71,9 +72,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
71
72
  version: 2.5.0
72
73
  required_rubygems_version: !ruby/object:Gem::Requirement
73
74
  requirements:
74
- - - ">="
75
+ - - ">"
75
76
  - !ruby/object:Gem::Version
76
- version: '0'
77
+ version: 1.3.1
77
78
  requirements: []
78
79
  rubygems_version: 3.1.2
79
80
  signing_key:
@@ -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