qat-cucumber 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/bin/qat +5 -0
- data/lib/qat/cli/generator/project.rb +32 -0
- data/lib/qat/cli/generator.rb +48 -0
- data/lib/qat/cli/main.rb +102 -0
- data/lib/qat/cli/plugins/core.rb +19 -0
- data/lib/qat/cli.rb +52 -0
- data/lib/qat/cucumber/core_ext/formatter/html.rb +48 -0
- data/lib/qat/cucumber/core_ext/formatter/junit.rb +57 -0
- data/lib/qat/cucumber/core_ext/result.rb +16 -0
- data/lib/qat/cucumber/core_ext.rb +3 -0
- data/lib/qat/cucumber/hooks/scenario.rb +76 -0
- data/lib/qat/cucumber/hooks.rb +72 -0
- data/lib/qat/cucumber/logger.rb +49 -0
- data/lib/qat/cucumber/time.rb +55 -0
- data/lib/qat/cucumber/version.rb +15 -0
- data/lib/qat/cucumber/world.rb +40 -0
- data/lib/qat/cucumber.rb +76 -0
- data/lib/qat/formatter/console.rb +101 -0
- data/lib/qat/formatter/dashboard.rb +84 -0
- data/lib/qat/formatter/loggable/mdc.rb +74 -0
- data/lib/qat/formatter/loggable/scenario_info.rb +40 -0
- data/lib/qat/formatter/loggable.rb +92 -0
- data/lib/qat/formatter/scenario/name.rb +47 -0
- data/lib/qat/formatter/tags.rb +81 -0
- data/lib/qat/formatter/test_ids.rb +93 -0
- data/lib/qat/jenkins.rb +43 -0
- data/lib/qat/project/Gemfile +13 -0
- data/lib/qat/project/Rakefile +3 -0
- data/lib/qat/project/config/cucumber.yml +13 -0
- data/lib/qat/project/config/default.yml +1 -0
- data/lib/qat/project/config/env-dummy/hosts.yml +9 -0
- data/lib/qat/project/config/env-dummy/jenkins.yml +7 -0
- data/lib/qat/project/config/env-dummy/logger.yml +23 -0
- data/lib/qat/project/config/env-dummy/time.yml +11 -0
- data/lib/qat/project/features/feature.feature +45 -0
- data/lib/qat/project/features/step_definitions/steps.rb +4 -0
- data/lib/qat/project/features/support/env.rb +6 -0
- data/lib/qat/project/features/support/hooks.rb +32 -0
- data/lib/qat/tasks/list.rb +50 -0
- data/lib/qat/tasks/steps.rb +20 -0
- data/lib/qat/tasks/tags/test_ids/helpers.rb +105 -0
- data/lib/qat/tasks/tags/test_ids/report.rb +41 -0
- data/lib/qat/tasks/tags/test_ids.rb +60 -0
- data/lib/qat/tasks/tags.rb +2 -0
- data/lib/qat/tasks/test.rb +35 -0
- data/lib/qat/tasks.rb +8 -0
- metadata +193 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'minitest'
|
3
|
+
require 'cucumber'
|
4
|
+
require_relative 'version'
|
5
|
+
require 'qat/logger'
|
6
|
+
|
7
|
+
module QAT
|
8
|
+
module Cucumber
|
9
|
+
#Cucumber World utility. Will be automatically included in the World object when this file is required.
|
10
|
+
#Includes MiniTest and a Logger utility.
|
11
|
+
#In order to define the Logger channel, a World Class should be defined by the user.
|
12
|
+
#Should be required in the env.rb file.
|
13
|
+
module World
|
14
|
+
include QAT::Logger
|
15
|
+
include Minitest::Assertions
|
16
|
+
|
17
|
+
attr_accessor :assertions
|
18
|
+
|
19
|
+
# @!attribute assertions
|
20
|
+
# @return [Integer] Counter of assertions for Minitest integration.
|
21
|
+
def assertions
|
22
|
+
@assertions ||= 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_id
|
26
|
+
QAT[:current_test_id]
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_run_id
|
30
|
+
QAT[:current_test_run_id]
|
31
|
+
end
|
32
|
+
|
33
|
+
def evidence_prefix
|
34
|
+
QAT[:current_test_run_id]
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
data/lib/qat/cucumber.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'minitest'
|
3
|
+
require 'cucumber'
|
4
|
+
require_relative 'cucumber/version'
|
5
|
+
require_relative 'cucumber/core_ext'
|
6
|
+
require 'qat/logger'
|
7
|
+
require 'qat/core'
|
8
|
+
require 'qat/configuration'
|
9
|
+
require 'qat/time'
|
10
|
+
require_relative 'jenkins' if ENV['JENKINS_URL']
|
11
|
+
require_relative 'cucumber/logger'
|
12
|
+
require_relative 'cucumber/time'
|
13
|
+
|
14
|
+
require_relative 'cucumber/hooks'
|
15
|
+
require_relative 'cucumber/world'
|
16
|
+
World QAT::Cucumber::World
|
17
|
+
|
18
|
+
#QAT Module works as a namespace for all sub modules.
|
19
|
+
#Some singleton methods are also available, as defined by various sub classes.
|
20
|
+
#@since 0.1.0
|
21
|
+
module QAT
|
22
|
+
# Namespace for various helpers when running with cucumber.
|
23
|
+
#Just require 'qat/cucumber' to automatically integrate all the available helpers.
|
24
|
+
#
|
25
|
+
#@since 0.1.0
|
26
|
+
module Cucumber
|
27
|
+
include QAT::Logger
|
28
|
+
|
29
|
+
class << self
|
30
|
+
include QAT::Cucumber::Logger
|
31
|
+
include QAT::Cucumber::Time
|
32
|
+
|
33
|
+
# Launches the pre-test configurations and integrations
|
34
|
+
# This includes:
|
35
|
+
# - Time Synchronization between the host running tests
|
36
|
+
# and a target host (test environment?) if configured
|
37
|
+
# - Setups the Jenkins integration if running this CI Server
|
38
|
+
def launch!
|
39
|
+
current_configuration = QAT.configuration
|
40
|
+
|
41
|
+
raise EmptyConfiguration.new "No valid configuration exists to run tests!" unless current_configuration
|
42
|
+
raise InvalidConfiguration.new "No valid environment is defined, aborting test execution!" unless current_configuration.environment
|
43
|
+
|
44
|
+
config_logger(current_configuration)
|
45
|
+
|
46
|
+
time_sync if current_configuration[:time]
|
47
|
+
|
48
|
+
setup_jenkins((current_configuration)) if ENV['JENKINS_URL']
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Initializes the Jenkins configuration for test run
|
54
|
+
# @param configuration [Hash] configuration
|
55
|
+
def setup_jenkins(configuration)
|
56
|
+
jenkins_vars = configuration.dig(:jenkins, :env_vars)
|
57
|
+
|
58
|
+
if jenkins_vars
|
59
|
+
QAT::Jenkins.register_vars(jenkins_vars)
|
60
|
+
else
|
61
|
+
log.debug { "Configuring Jenkins with default options." }
|
62
|
+
QAT::Jenkins.register_vars
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# This class represents a empty configuration error when there is no configuration available
|
68
|
+
class EmptyConfiguration < StandardError
|
69
|
+
end
|
70
|
+
# This class represents a invalid configuration error when the configuration is not complete
|
71
|
+
class InvalidConfiguration < StandardError
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
QAT::Cucumber.launch!
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'cucumber/formatter/console'
|
3
|
+
require 'cucumber/formatter/io'
|
4
|
+
require 'cucumber/gherkin/formatter/escaping'
|
5
|
+
require 'qat/logger'
|
6
|
+
require_relative 'loggable'
|
7
|
+
|
8
|
+
module QAT
|
9
|
+
module Formatter
|
10
|
+
# Formatter to print Feature, Scenario and Step information on the fly. Will use STDOUT by default or a specified
|
11
|
+
# logger configuration channel.
|
12
|
+
#@see QAT::Loggger
|
13
|
+
#@since 0.1.0
|
14
|
+
class Console
|
15
|
+
include ::FileUtils
|
16
|
+
include ::Cucumber::Formatter::Io
|
17
|
+
include ::Cucumber::Gherkin::Formatter::Escaping
|
18
|
+
include QAT::Formatter::Loggable
|
19
|
+
include QAT::Logger
|
20
|
+
|
21
|
+
#@api private
|
22
|
+
def initialize(_, path_or_io, options)
|
23
|
+
@options = options
|
24
|
+
|
25
|
+
check_outputter path_or_io unless options[:dry_run]
|
26
|
+
end
|
27
|
+
|
28
|
+
#@api private
|
29
|
+
def before_test_case test_case
|
30
|
+
return if @options[:dry_run]
|
31
|
+
|
32
|
+
unless @current_feature
|
33
|
+
@current_feature = test_case.source[0]
|
34
|
+
log.info { "Running #{@current_feature.keyword}: \"#{@current_feature.name}\"" }
|
35
|
+
mdc_before_feature! @current_feature.name
|
36
|
+
end
|
37
|
+
|
38
|
+
@current_scenario = test_case.source[1]
|
39
|
+
end
|
40
|
+
|
41
|
+
#@api private
|
42
|
+
def after_feature *_
|
43
|
+
return if @options[:dry_run]
|
44
|
+
|
45
|
+
log.info { "Finished #{@current_feature.keyword}: \"#{@current_feature.name}\"" }
|
46
|
+
@current_feature = nil
|
47
|
+
mdc_after_feature!
|
48
|
+
end
|
49
|
+
|
50
|
+
#@api private
|
51
|
+
def after_test_case step, result
|
52
|
+
return if @options[:dry_run]
|
53
|
+
|
54
|
+
log.error { result.exception } if result.failed?
|
55
|
+
|
56
|
+
log.info { "Finished #{@current_scenario.keyword}: \"#{format_scenario_name step}\" - #{result.to_sym}\n" } if @current_scenario
|
57
|
+
end
|
58
|
+
|
59
|
+
#@api private
|
60
|
+
def before_test_step step
|
61
|
+
return if @options[:dry_run]
|
62
|
+
|
63
|
+
begin_test_step step do |type|
|
64
|
+
case type
|
65
|
+
when :after_step
|
66
|
+
log.info "Step Done!" if @step_running
|
67
|
+
when :before_scenario
|
68
|
+
log.info { "Running #{@current_scenario.keyword}: \"#{format_scenario_name step}\"" }
|
69
|
+
when :before_step
|
70
|
+
log.info "Step Done!\n" if @step_running
|
71
|
+
step_name = "#{step.source.last.keyword}#{step.name}"
|
72
|
+
log.info { "Step \"#{step_name}\"" }
|
73
|
+
mdc_add_step! step_name
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#@api private
|
79
|
+
def puts obj
|
80
|
+
return if @options[:dry_run]
|
81
|
+
|
82
|
+
log.debug { obj }
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
def format_scenario_name step
|
87
|
+
return '' unless @current_scenario
|
88
|
+
outline_number, outline_example = nil, nil
|
89
|
+
scenario_name = if @current_scenario.is_a? ::Cucumber::Core::Ast::ScenarioOutline
|
90
|
+
outline_example = step.source[3].values
|
91
|
+
outline_number = calculate_outline_id(step)
|
92
|
+
"#{@current_scenario.name} ##{outline_number}"
|
93
|
+
else
|
94
|
+
@current_scenario.name
|
95
|
+
end
|
96
|
+
mdc_before_scenario! @current_scenario.name, tags_from_test_step(step), outline_number, outline_example
|
97
|
+
return scenario_name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'cucumber/formatter/console'
|
3
|
+
require 'cucumber/formatter/io'
|
4
|
+
require 'cucumber/gherkin/formatter/escaping'
|
5
|
+
require 'qat/logger'
|
6
|
+
require_relative 'loggable'
|
7
|
+
|
8
|
+
module QAT
|
9
|
+
module Formatter
|
10
|
+
# Formatter to send error information to a Dashboard server. Output should be configured in the logger file.
|
11
|
+
#@see QAT::Loggger
|
12
|
+
#@since 0.1.0
|
13
|
+
class Dashboard
|
14
|
+
include ::FileUtils
|
15
|
+
include ::Cucumber::Formatter::Io
|
16
|
+
include ::Cucumber::Gherkin::Formatter::Escaping
|
17
|
+
include QAT::Formatter::Loggable
|
18
|
+
include QAT::Logger
|
19
|
+
|
20
|
+
#@api private
|
21
|
+
def initialize(_, path_or_io, options)
|
22
|
+
@options = options
|
23
|
+
|
24
|
+
ensure_outputter path_or_io unless options[:dry_run]
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
#@api private
|
29
|
+
def before_test_case test_case
|
30
|
+
return if @options[:dry_run]
|
31
|
+
|
32
|
+
unless @current_feature
|
33
|
+
@current_feature = test_case.source[0]
|
34
|
+
mdc_before_feature! @current_feature.name
|
35
|
+
end
|
36
|
+
|
37
|
+
@current_scenario = test_case.source[1]
|
38
|
+
end
|
39
|
+
|
40
|
+
#@api private
|
41
|
+
def after_feature *_
|
42
|
+
return if @options[:dry_run]
|
43
|
+
|
44
|
+
@current_feature = nil
|
45
|
+
mdc_after_feature!
|
46
|
+
end
|
47
|
+
|
48
|
+
#@api private
|
49
|
+
def after_test_case step, passed
|
50
|
+
return if @options[:dry_run]
|
51
|
+
|
52
|
+
if passed.respond_to? :exception
|
53
|
+
mdc_add_step! @step_name
|
54
|
+
mdc_add_status_failed!
|
55
|
+
log.error passed.exception
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
#@api private
|
60
|
+
def before_test_step step
|
61
|
+
return if @options[:dry_run]
|
62
|
+
|
63
|
+
begin_test_step step do |type|
|
64
|
+
if type == :before_step
|
65
|
+
@step_name = "#{step.source.last.keyword}#{step.name}"
|
66
|
+
mdc_add_step! @step_name
|
67
|
+
elsif :before_scenario
|
68
|
+
outline_number, outline_example = nil, nil
|
69
|
+
if @current_scenario.is_a? ::Cucumber::Core::Ast::ScenarioOutline
|
70
|
+
outline_example = step.source[3].values
|
71
|
+
outline_number = calculate_outline_id(step)
|
72
|
+
end
|
73
|
+
mdc_before_scenario! @current_scenario.name, tags_from_test_step(step), outline_number, outline_example
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# #@api private
|
79
|
+
# def exception e, _
|
80
|
+
# log.error e
|
81
|
+
# end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'qat/logger'
|
2
|
+
require_relative 'scenario_info'
|
3
|
+
|
4
|
+
module QAT
|
5
|
+
module Formatter
|
6
|
+
module Loggable
|
7
|
+
#Helper module to manage loggable mdc information
|
8
|
+
#@since 2.0.2
|
9
|
+
module Mdc
|
10
|
+
include ScenarioInfo
|
11
|
+
|
12
|
+
#Set the MDC key 'feature' with the given value.
|
13
|
+
#@param feature_name [String] Name of the current feature
|
14
|
+
#@since 0.1.0
|
15
|
+
def mdc_before_feature!(feature_name)
|
16
|
+
Log4r::MDC.put 'feature', feature_name
|
17
|
+
end
|
18
|
+
|
19
|
+
#Remove the MDC key 'feature'.
|
20
|
+
#@since 0.1.0
|
21
|
+
def mdc_after_feature!
|
22
|
+
Log4r::MDC.remove 'feature'
|
23
|
+
end
|
24
|
+
|
25
|
+
#Set the MDC key 'scenario' with the given value.
|
26
|
+
#Optionally scenario outline data can also be provided
|
27
|
+
#@param scenario_name [String] Name of the current feature
|
28
|
+
#@param tags [Array<String>] List of tags
|
29
|
+
#@param outline_number [Integer] Number of the current scenario outline
|
30
|
+
#@param outline_example [Array<String>] Values of the current outline's example row
|
31
|
+
#@since 0.1.0
|
32
|
+
def mdc_before_scenario!(scenario_name, tags, outline_number = nil, outline_example = nil)
|
33
|
+
mdc_reset_scenario!
|
34
|
+
Log4r::MDC.put 'scenario', scenario_name
|
35
|
+
|
36
|
+
test_id = test_id(tags, outline_number)
|
37
|
+
Log4r::MDC.put 'test_id', test_id
|
38
|
+
loggable_tags = tags.reject { |tag| tag.match(/^\@test\#/) }
|
39
|
+
Log4r::MDC.put 'tags', loggable_tags
|
40
|
+
|
41
|
+
Log4r::MDC.put 'outline_number', outline_number if outline_number
|
42
|
+
Log4r::MDC.put 'outline_example', outline_example if outline_example
|
43
|
+
end
|
44
|
+
|
45
|
+
#Remove the MDC key 'scenario'. Other options set in #mdc_before_scenario! will also be unset.
|
46
|
+
#@since 0.1.0
|
47
|
+
def mdc_reset_scenario!
|
48
|
+
mdc_remove_step!
|
49
|
+
Log4r::MDC.remove 'scenario'
|
50
|
+
Log4r::MDC.remove 'tags'
|
51
|
+
Log4r::MDC.remove 'outline_number'
|
52
|
+
Log4r::MDC.remove 'outline_example'
|
53
|
+
end
|
54
|
+
|
55
|
+
#Set the MDC key 'step' with the given value.
|
56
|
+
#@param step_name [String] Name of the current step
|
57
|
+
#@since 0.1.0
|
58
|
+
def mdc_add_step!(step_name)
|
59
|
+
Log4r::MDC.put 'step', step_name
|
60
|
+
end
|
61
|
+
|
62
|
+
#Remove the MDC key 'step'.
|
63
|
+
#@since 0.1.0
|
64
|
+
def mdc_remove_step!
|
65
|
+
Log4r::MDC.remove 'step'
|
66
|
+
end
|
67
|
+
|
68
|
+
def mdc_add_status_failed!
|
69
|
+
Log4r::MDC.put 'status', 'failed'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'qat/logger'
|
2
|
+
|
3
|
+
module QAT
|
4
|
+
module Formatter
|
5
|
+
module Loggable
|
6
|
+
#Helper module to manage loggable scenario information
|
7
|
+
#@since 2.0.2
|
8
|
+
module ScenarioInfo
|
9
|
+
protected
|
10
|
+
|
11
|
+
def tags_from_test_step(step)
|
12
|
+
step.source.inject([]) do |sum, current_source|
|
13
|
+
sum << current_source.tags if current_source.respond_to? :tags
|
14
|
+
sum
|
15
|
+
end.flatten.map(&:name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_id(tags, outline_id)
|
19
|
+
tag = tags.select { |tag| tag.match /^\@test\#\d+$/ }.first
|
20
|
+
if tag
|
21
|
+
id = tag.gsub '@test#', 'test_'
|
22
|
+
id << ".#{outline_id}" if outline_id
|
23
|
+
id
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def calculate_outline_id(step)
|
30
|
+
source = step.source
|
31
|
+
tables = source[1].instance_exec { @examples_tables }
|
32
|
+
table_lines = tables.each.map { |line| line.example_rows.size }
|
33
|
+
table_num = tables.index source[2]
|
34
|
+
previous_outlines = table_lines[0...table_num].inject(0) { |sum, lines| sum += lines; sum }
|
35
|
+
"#{previous_outlines + source[3].number}".to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'qat/logger'
|
2
|
+
require_relative 'loggable/mdc'
|
3
|
+
|
4
|
+
module QAT
|
5
|
+
#Namespace for custom Cucumber formatters and helpers.
|
6
|
+
#@since 0.1.0
|
7
|
+
module Formatter
|
8
|
+
#Helper module to manage formatters based on QAT::Logger
|
9
|
+
#@since 0.1.0
|
10
|
+
module Loggable
|
11
|
+
include QAT::Logger
|
12
|
+
include Mdc
|
13
|
+
|
14
|
+
def check_outputter name
|
15
|
+
return if name.respond_to? :write #Is an IO
|
16
|
+
|
17
|
+
add_outputter_with name
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def ensure_outputter name
|
22
|
+
raise ArgumentError.new "No outputter configured for formatter #{self.class.name}" if name.respond_to? :write
|
23
|
+
|
24
|
+
add_outputter_with name
|
25
|
+
end
|
26
|
+
|
27
|
+
#Parses a test step and determines it's type: after step, before scenario or before step.
|
28
|
+
#Allows a block to be used to execute in the middle of the processing
|
29
|
+
#@param step [Cucumber::Core::Test::Step] Step to parse
|
30
|
+
#@yield [type] Block to execute in the middle of processing
|
31
|
+
#@yieldparam [Symbol] type Type of the test step
|
32
|
+
#@return [Symbol] type Type of the test step
|
33
|
+
#@since 0.1.0
|
34
|
+
def begin_test_step step
|
35
|
+
#World: step.location = /usr/local/rvm/gems/ruby-2.2.3/gems/cucumber-2.0.2/lib/cucumber/filters/prepare_world.rb:27
|
36
|
+
# step.name = "Before hook"
|
37
|
+
|
38
|
+
#Hooks: step.location = /home/mgomes/Projects/qat/src/qat/lib/qat/cucumber/hooks.rb:53
|
39
|
+
# step.name = "Before hook"
|
40
|
+
|
41
|
+
#Stepdef: step.location = features/formatter.feature:8
|
42
|
+
# step.name = step name
|
43
|
+
|
44
|
+
type = set_type(step)
|
45
|
+
|
46
|
+
yield type if block_given? and type
|
47
|
+
|
48
|
+
set_step_status(type)
|
49
|
+
|
50
|
+
type
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def add_outputter_with(name)
|
56
|
+
require_relative '../cucumber'
|
57
|
+
|
58
|
+
outputter = Log4r::Outputter[name]
|
59
|
+
|
60
|
+
raise ArgumentError.new "No outputter in loaded configuration file with name #{name}" unless outputter
|
61
|
+
|
62
|
+
return if log.outputters.map(&:name).include? name
|
63
|
+
|
64
|
+
log.add outputter
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_type(step)
|
68
|
+
location = step.location.file.to_s
|
69
|
+
step_name = step.name
|
70
|
+
|
71
|
+
if step_name == "After hook"
|
72
|
+
:after_step
|
73
|
+
elsif step_name == "Before hook" and location.end_with? 'prepare_world.rb'
|
74
|
+
@current_scenario = step.source[1]
|
75
|
+
:before_scenario
|
76
|
+
elsif File.extname(location.to_s) == '.feature'
|
77
|
+
:before_step
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_step_status(type)
|
82
|
+
if type == :after_step
|
83
|
+
@step_running = false
|
84
|
+
elsif type == :before_scenario
|
85
|
+
@step_running = false
|
86
|
+
elsif type == :before_step
|
87
|
+
@step_running = true
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'cucumber/formatter/io'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module QAT
|
5
|
+
module Formatter
|
6
|
+
module Scenario
|
7
|
+
class Name
|
8
|
+
include Cucumber::Formatter::Io
|
9
|
+
|
10
|
+
def initialize(runtime, path_or_io, options)
|
11
|
+
@runtime = runtime
|
12
|
+
@io = ensure_io(path_or_io)
|
13
|
+
@to_file = (@io != $stdout)
|
14
|
+
@options = options
|
15
|
+
@scenarios = {}
|
16
|
+
@repeated = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def scenario_name(keyword, name, file_colon_line, source_indent)
|
20
|
+
if @to_file
|
21
|
+
if @scenarios.values.include?(name)
|
22
|
+
@repeated[name] ||= []
|
23
|
+
@repeated[name] << file_colon_line
|
24
|
+
end
|
25
|
+
@scenarios[file_colon_line] = name
|
26
|
+
else
|
27
|
+
puts "#{name}: #{file_colon_line}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def after_features(features)
|
32
|
+
if @to_file
|
33
|
+
content = {
|
34
|
+
scenarios: @scenarios,
|
35
|
+
repeated: @repeated
|
36
|
+
}
|
37
|
+
@io.puts(content.to_json({
|
38
|
+
indent: ' ',
|
39
|
+
space: ' ',
|
40
|
+
object_nl: "\n"
|
41
|
+
}))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'cucumber/formatter/io'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module QAT
|
5
|
+
module Formatter
|
6
|
+
# This formatter prints test scenarios tags information to a JSON format.
|
7
|
+
# Information includes:
|
8
|
+
# - untagged test scenarios
|
9
|
+
# - list of unique tags used
|
10
|
+
# - total number of tags used
|
11
|
+
#
|
12
|
+
# Note: Generated test ids are omitted.
|
13
|
+
#
|
14
|
+
class Tags
|
15
|
+
include Cucumber::Formatter::Io
|
16
|
+
|
17
|
+
#@api private
|
18
|
+
def initialize(runtime, path_or_io, options)
|
19
|
+
@io = ensure_io(path_or_io)
|
20
|
+
@tags = []
|
21
|
+
@scenario_tags = []
|
22
|
+
@total_scenarios = 0
|
23
|
+
@total_scenarios_without_tags = 0
|
24
|
+
@scenarios_without_tags = {}
|
25
|
+
@options = options
|
26
|
+
end
|
27
|
+
|
28
|
+
#@api private
|
29
|
+
def after_features(features)
|
30
|
+
publish_result
|
31
|
+
end
|
32
|
+
|
33
|
+
#@api private
|
34
|
+
def before_feature(feature)
|
35
|
+
@feature_tags = []
|
36
|
+
@in_scenarios = false
|
37
|
+
end
|
38
|
+
|
39
|
+
#@api private
|
40
|
+
def tag_name(tag_name)
|
41
|
+
if @in_scenarios
|
42
|
+
@scenario_tags << tag_name unless tag_name.match(/@test#(\d+)/)
|
43
|
+
else
|
44
|
+
@feature_tags << tag_name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#@api private
|
49
|
+
def after_tags(tags)
|
50
|
+
@in_scenarios = true unless @in_scenarios
|
51
|
+
end
|
52
|
+
|
53
|
+
#@api private
|
54
|
+
def scenario_name(keyword, name, file_colon_line, source_indent)
|
55
|
+
scenario_tags = @scenario_tags + @feature_tags
|
56
|
+
@tags += scenario_tags
|
57
|
+
@total_scenarios += 1
|
58
|
+
unless scenario_tags.any?
|
59
|
+
@scenarios_without_tags[name] = file_colon_line
|
60
|
+
@total_scenarios_without_tags += 1
|
61
|
+
end
|
62
|
+
@scenario_tags = []
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def publish_result
|
67
|
+
content = {
|
68
|
+
untagged: @scenarios_without_tags,
|
69
|
+
tags:
|
70
|
+
{ unique: @tags.uniq.sort,
|
71
|
+
total: @tags.size }
|
72
|
+
}
|
73
|
+
@io.puts(content.to_json({
|
74
|
+
indent: ' ',
|
75
|
+
space: ' ',
|
76
|
+
object_nl: "\n"
|
77
|
+
}))
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|