qat-cucumber 6.0.0 → 7.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/qat/cucumber/core_ext/formatter/html.rb +45 -45
- data/lib/qat/cucumber/core_ext/formatter/junit.rb +53 -53
- data/lib/qat/cucumber/core_ext/result.rb +16 -16
- data/lib/qat/cucumber/hooks/scenario.rb +34 -32
- data/lib/qat/cucumber/version.rb +1 -1
- data/lib/qat/formatter/builder.rb +86 -0
- data/lib/qat/formatter/console.rb +16 -77
- data/lib/qat/formatter/dashboard.rb +15 -59
- data/lib/qat/formatter/helper.rb +91 -0
- data/lib/qat/formatter/loggable.rb +4 -4
- data/lib/qat/formatter/scenario/name.rb +38 -19
- data/lib/qat/formatter/tags.rb +28 -31
- data/lib/qat/formatter/test_ids.rb +43 -34
- data/lib/qat/formatter/utility_function.rb +65 -0
- data/lib/qat/project/Gemfile +2 -11
- data/lib/qat/project/config/env-dummy/time.yml +1 -1
- data/lib/qat/project/features/support/hooks.rb +1 -1
- data/lib/qat/tasks/tags/test_ids/helpers.rb +5 -5
- metadata +16 -12
@@ -4,6 +4,8 @@ require 'cucumber/formatter/io'
|
|
4
4
|
require 'cucumber/gherkin/formatter/escaping'
|
5
5
|
require 'qat/logger'
|
6
6
|
require_relative 'loggable'
|
7
|
+
require 'cucumber/core/gherkin/writer'
|
8
|
+
require_relative 'helper'
|
7
9
|
|
8
10
|
module QAT
|
9
11
|
module Formatter
|
@@ -14,71 +16,25 @@ module QAT
|
|
14
16
|
include ::FileUtils
|
15
17
|
include ::Cucumber::Formatter::Io
|
16
18
|
include ::Cucumber::Gherkin::Formatter::Escaping
|
19
|
+
include ::Cucumber::Core::Gherkin::Writer
|
17
20
|
include QAT::Formatter::Loggable
|
18
21
|
include QAT::Logger
|
22
|
+
include QAT::Formatter::Helper
|
19
23
|
|
20
24
|
#@api private
|
21
|
-
def initialize(
|
22
|
-
@
|
23
|
-
|
24
|
-
ensure_outputter
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
25
|
+
def initialize(config)
|
26
|
+
@config = config
|
27
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
28
|
+
ensure_outputter config.out_stream
|
29
|
+
@ast_lookup = ::Cucumber::Formatter::AstLookup.new(config)
|
30
|
+
@feature_hashes = []
|
31
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
32
|
+
config.on_event :test_case_finished, &method(:on_test_case_finished)
|
33
|
+
config.on_event :test_step_started, &method(:on_test_step_started)
|
34
|
+
config.on_event :test_step_finished, &method(:on_test_step_finished)
|
35
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
76
36
|
end
|
77
37
|
|
78
|
-
# #@api private
|
79
|
-
# def exception e, _
|
80
|
-
# log.error e
|
81
|
-
# end
|
82
38
|
end
|
83
39
|
end
|
84
40
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative 'builder'
|
2
|
+
require_relative 'utility_function'
|
3
|
+
|
4
|
+
module QAT
|
5
|
+
module Formatter
|
6
|
+
# Helper for Formatters , most of the main methods are done to reduce code duplication
|
7
|
+
module Helper
|
8
|
+
include QAT::Formatter::Builder
|
9
|
+
include QAT::Formatter::UtilityFuction
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
def on_test_case_started event
|
14
|
+
return if @config.dry_run?
|
15
|
+
@row_number = nil
|
16
|
+
test_case = event.test_case
|
17
|
+
build(test_case, @ast_lookup)
|
18
|
+
assign_print_feature unless @current_feature
|
19
|
+
@current_scenario = @scenario
|
20
|
+
scenario_name = @current_scenario[:name]
|
21
|
+
print_scenario_start @current_scenario[:keyword], scenario_name
|
22
|
+
mdc_before_scenario! scenario_name, @current_scenario[:tags], @row_number, @examples_values
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def on_test_case_finished event
|
27
|
+
return if @config.dry_run?
|
28
|
+
_test_case, result = *event.attributes
|
29
|
+
@current_feature = nil
|
30
|
+
if result.failed?
|
31
|
+
mdc_add_step! @mdc_text
|
32
|
+
mdc_add_status_failed!
|
33
|
+
log.error { result.exception }
|
34
|
+
else
|
35
|
+
print_scenario_results @current_scenario[:keyword], @current_scenario[:name], result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def on_test_step_started(event)
|
40
|
+
return if @config.dry_run?
|
41
|
+
test_step = event.test_step
|
42
|
+
return if internal_hook?(test_step)
|
43
|
+
return if support_hook?(test_step)
|
44
|
+
step_source = @ast_lookup.step_source(test_step).step
|
45
|
+
print_assign_step test_step, step_source
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def on_test_step_finished(event)
|
50
|
+
return if @config.dry_run?
|
51
|
+
test_step, result = *event.attributes
|
52
|
+
return if internal_hook?(test_step)
|
53
|
+
return if support_hook?(test_step)
|
54
|
+
log.info "Step Done!"
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_test_run_finished _event
|
58
|
+
return if @config.dry_run?
|
59
|
+
print_scenario_results @feature_hash[:keyword], @feature_hash[:name]
|
60
|
+
mdc_after_feature!
|
61
|
+
end
|
62
|
+
|
63
|
+
def assign_print_feature
|
64
|
+
@current_feature = @feature_hash
|
65
|
+
feature_name = @current_feature[:name]
|
66
|
+
print_scenario_start @current_feature[:keyword], feature_name
|
67
|
+
mdc_before_feature! feature_name
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def print_assign_step test_step, step_source
|
72
|
+
test_step_text = test_step.text
|
73
|
+
log.info { "Step \"#{test_step_text}\"" }
|
74
|
+
@mdc_text = "#{step_source.keyword}#{test_step_text}"
|
75
|
+
mdc_add_step! @mdc_text
|
76
|
+
end
|
77
|
+
|
78
|
+
def print_scenario_results keyword, name, result = nil
|
79
|
+
if result
|
80
|
+
log.info { "Finished #{keyword}: \"#{name}\" - #{result}\n" }
|
81
|
+
else
|
82
|
+
log.info { "Finished #{keyword}: \"#{name}\"" }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def print_scenario_start keyword, name
|
87
|
+
log.info { "Running #{keyword}: \"#{name}\"" }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -33,13 +33,13 @@ module QAT
|
|
33
33
|
#@since 0.1.0
|
34
34
|
def begin_test_step step
|
35
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.
|
36
|
+
# step.to_s = "Before hook"
|
37
37
|
|
38
38
|
#Hooks: step.location = /home/mgomes/Projects/qat/src/qat/lib/qat/cucumber/hooks.rb:53
|
39
|
-
# step.
|
39
|
+
# step.to_s = "Before hook"
|
40
40
|
|
41
41
|
#Stepdef: step.location = features/formatter.feature:8
|
42
|
-
# step.
|
42
|
+
# step.to_s = step name
|
43
43
|
|
44
44
|
type = set_type(step)
|
45
45
|
|
@@ -66,7 +66,7 @@ module QAT
|
|
66
66
|
|
67
67
|
def set_type(step)
|
68
68
|
location = step.location.file.to_s
|
69
|
-
step_name = step.
|
69
|
+
step_name = step.to_s
|
70
70
|
|
71
71
|
if step_name == "After hook"
|
72
72
|
:after_step
|
@@ -1,46 +1,65 @@
|
|
1
1
|
require 'cucumber/formatter/io'
|
2
2
|
require 'json'
|
3
|
+
require_relative '../helper'
|
3
4
|
|
4
5
|
module QAT
|
5
6
|
module Formatter
|
6
7
|
module Scenario
|
7
8
|
class Name
|
8
9
|
include Cucumber::Formatter::Io
|
10
|
+
include QAT::Formatter::Helper
|
9
11
|
|
10
|
-
def initialize(
|
11
|
-
@
|
12
|
-
@io
|
13
|
-
@to_file = (@io != $stdout)
|
14
|
-
@
|
15
|
-
@scenarios
|
16
|
-
@repeated
|
12
|
+
def initialize(config)
|
13
|
+
@config = config
|
14
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
15
|
+
# @to_file = (@io != $stdout)
|
16
|
+
@to_file = @io
|
17
|
+
@scenarios = {}
|
18
|
+
@repeated = {}
|
19
|
+
@ast_lookup = ::Cucumber::Formatter::AstLookup.new(config)
|
20
|
+
@feature_hashes = []
|
21
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
22
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
17
23
|
end
|
18
24
|
|
19
|
-
|
25
|
+
|
26
|
+
def on_test_case_started event
|
27
|
+
@examples_values = []
|
28
|
+
build(event.test_case, @ast_lookup)
|
29
|
+
@current_feature = @feature_hash
|
30
|
+
scenario_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def scenario_name
|
20
34
|
if @to_file
|
21
|
-
if @scenarios.values.include?(name)
|
22
|
-
@
|
23
|
-
@
|
35
|
+
if @scenarios.values.include?(@scenario[:name])
|
36
|
+
file_colon_line = "#{@current_feature[:uri]}:#{@scenario[:line]}"
|
37
|
+
unless @scenarios.keys.include?(file_colon_line)
|
38
|
+
@repeated[@scenario[:name]] ||= []
|
39
|
+
@repeated[@scenario[:name]] << "#{@current_feature[:uri]}:#{@scenario[:line]}"
|
40
|
+
end
|
24
41
|
end
|
25
|
-
@
|
42
|
+
file_colon_line = "#{@current_feature[:uri]}:#{@scenario[:line]}"
|
43
|
+
@scenarios[file_colon_line] = @scenario[:name]
|
26
44
|
else
|
27
|
-
puts "#{name}: #{file_colon_line}"
|
45
|
+
Kernel.puts "#{@scenario[:name]}: #{file_colon_line}"
|
28
46
|
end
|
29
47
|
end
|
30
48
|
|
31
|
-
def
|
49
|
+
def on_test_run_finished(_event)
|
32
50
|
if @to_file
|
33
51
|
content = {
|
34
52
|
scenarios: @scenarios,
|
35
53
|
repeated: @repeated
|
36
54
|
}
|
37
|
-
@io.
|
38
|
-
|
39
|
-
space: ' ',
|
40
|
-
object_nl: "\n"
|
41
|
-
}))
|
55
|
+
@io.write (JSON.pretty_generate(content))
|
56
|
+
@io.flush
|
42
57
|
end
|
43
58
|
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
44
63
|
end
|
45
64
|
end
|
46
65
|
end
|
data/lib/qat/formatter/tags.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cucumber/formatter/io'
|
2
2
|
require 'json'
|
3
|
+
require_relative 'helper'
|
3
4
|
|
4
5
|
module QAT
|
5
6
|
module Formatter
|
@@ -13,50 +14,47 @@ module QAT
|
|
13
14
|
#
|
14
15
|
class Tags
|
15
16
|
include Cucumber::Formatter::Io
|
17
|
+
include QAT::Formatter::Helper
|
16
18
|
|
17
19
|
#@api private
|
18
|
-
def initialize(
|
19
|
-
@
|
20
|
+
def initialize(config)
|
21
|
+
@config = config
|
22
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
20
23
|
@tags = []
|
21
24
|
@scenario_tags = []
|
22
25
|
@total_scenarios = 0
|
23
26
|
@total_scenarios_without_tags = 0
|
24
27
|
@scenarios_without_tags = {}
|
25
|
-
@
|
28
|
+
@ast_lookup = ::Cucumber::Formatter::AstLookup.new(config)
|
29
|
+
@feature_hashes = []
|
30
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
31
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
26
32
|
end
|
27
33
|
|
28
|
-
#@api private
|
29
|
-
def after_features(features)
|
30
|
-
publish_result
|
31
|
-
end
|
32
34
|
|
33
|
-
|
34
|
-
def
|
35
|
+
|
36
|
+
def on_test_case_started event
|
35
37
|
@feature_tags = []
|
36
|
-
@
|
38
|
+
@examples_values = []
|
39
|
+
test_case = event.test_case
|
40
|
+
build(test_case, @ast_lookup)
|
41
|
+
@current_feature = @feature_hash
|
42
|
+
@test_id_tags = true
|
43
|
+
scenario_name
|
37
44
|
end
|
38
45
|
|
39
|
-
|
40
|
-
|
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
|
+
def on_test_run_finished(_event)
|
47
|
+
publish_result
|
46
48
|
end
|
47
49
|
|
48
|
-
#@api private
|
49
|
-
def after_tags(tags)
|
50
|
-
@in_scenarios = true unless @in_scenarios
|
51
|
-
end
|
52
50
|
|
53
51
|
#@api private
|
54
|
-
def scenario_name
|
55
|
-
scenario_tags = @
|
56
|
-
@tags += scenario_tags
|
52
|
+
def scenario_name
|
53
|
+
scenario_tags = @scenario[:tags] + @feature_hash[:tags] if @scenario[:tags] && @feature_hash[:tags] rescue nil
|
54
|
+
@tags += scenario_tags unless scenario_tags.nil?
|
57
55
|
@total_scenarios += 1
|
58
|
-
unless scenario_tags.any?
|
59
|
-
@scenarios_without_tags[name] =
|
56
|
+
unless scenario_tags.try(:any?)
|
57
|
+
@scenarios_without_tags[@scenario[:name]] = "#{@current_feature[:uri]}:#{@scenario[:line]}"
|
60
58
|
@total_scenarios_without_tags += 1
|
61
59
|
end
|
62
60
|
@scenario_tags = []
|
@@ -70,12 +68,11 @@ module QAT
|
|
70
68
|
{ unique: @tags.uniq.sort,
|
71
69
|
total: @tags.size }
|
72
70
|
}
|
73
|
-
@io.
|
74
|
-
indent: ' ',
|
75
|
-
space: ' ',
|
76
|
-
object_nl: "\n"
|
77
|
-
}))
|
71
|
+
@io.write (JSON.pretty_generate(content))
|
78
72
|
end
|
73
|
+
|
74
|
+
|
75
|
+
|
79
76
|
end
|
80
77
|
end
|
81
78
|
end
|
@@ -1,64 +1,74 @@
|
|
1
1
|
require 'cucumber/formatter/io'
|
2
2
|
require 'json'
|
3
|
+
require_relative 'helper'
|
3
4
|
|
4
5
|
module QAT
|
5
6
|
module Formatter
|
6
|
-
|
7
|
+
# Formatter to get duplicate test ids and get scenarios untagged
|
8
|
+
class TestIds
|
7
9
|
include Cucumber::Formatter::Io
|
10
|
+
include QAT::Formatter::Helper
|
8
11
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@tags = []
|
12
|
-
@scenario_tags = []
|
12
|
+
def initialize(config)
|
13
|
+
@config = config
|
13
14
|
@no_test_id = {}
|
14
15
|
@max_test_id = 0
|
15
16
|
@duplicate_test_ids = {}
|
16
17
|
@test_id_mapping = {}
|
17
|
-
@
|
18
|
-
|
18
|
+
@io = ensure_io(config.out_stream, config.error_stream)
|
19
|
+
@ast_lookup = ::Cucumber::Formatter::AstLookup.new(@config)
|
20
|
+
config.on_event :test_case_started, &method(:on_test_case_started)
|
21
|
+
config.on_event :test_run_finished, &method(:on_test_run_finished)
|
19
22
|
|
20
|
-
def before_feature(feature)
|
21
|
-
@in_scenarios = false
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
|
26
|
+
#@api private
|
27
|
+
def on_test_case_started event
|
28
|
+
@feature_hashes = []
|
29
|
+
@tags = []
|
30
|
+
@scenario_tags = []
|
31
|
+
@examples_values = []
|
32
|
+
build(event.test_case, @ast_lookup)
|
33
|
+
@current_feature = @feature_hash
|
34
|
+
scenario_name
|
26
35
|
end
|
27
36
|
|
28
|
-
def
|
29
|
-
|
37
|
+
def on_test_run_finished(_event)
|
38
|
+
publish_result
|
39
|
+
@io.flush
|
30
40
|
end
|
31
41
|
|
32
|
-
def scenario_name
|
33
|
-
|
34
|
-
|
42
|
+
def scenario_name
|
43
|
+
path = "#{@current_feature[:uri]}:#{@scenario[:line]}"
|
44
|
+
scenario_tags= @scenario[:tags]
|
45
|
+
if scenario_tags.any? { |tag| tag.match(/@test#(\d+)/) }
|
46
|
+
id = scenario_tags.map { |tag| tag.match(/@test#(\d+)/) }.compact.first.captures.first.to_i
|
35
47
|
@max_test_id = id if id > @max_test_id
|
36
48
|
|
37
|
-
test_id_info = { name: name,
|
38
|
-
path:
|
49
|
+
test_id_info = { name: @scenario[:name],
|
50
|
+
path: path}
|
39
51
|
|
40
52
|
if @test_id_mapping[id]
|
41
53
|
if @duplicate_test_ids[id]
|
42
|
-
@duplicate_test_ids[id]
|
54
|
+
@duplicate_test_ids[id].find do |dup|
|
55
|
+
@exist = true if dup[:path]== test_id_info[:path]
|
56
|
+
end
|
57
|
+
@duplicate_test_ids[id] << test_id_info unless @exist
|
43
58
|
else
|
44
|
-
@duplicate_test_ids[id] = [@test_id_mapping[id], test_id_info]
|
59
|
+
@duplicate_test_ids[id] = [@test_id_mapping[id], test_id_info] unless @test_id_mapping[id][:path] == test_id_info[:path]
|
45
60
|
end
|
46
61
|
else
|
47
62
|
@test_id_mapping[id] = test_id_info
|
48
63
|
end
|
49
|
-
|
50
64
|
else
|
51
|
-
@no_test_id[name] =
|
65
|
+
@no_test_id[@scenario[:name]] = path unless scenario_tags.include?('@dummy_test')
|
52
66
|
end
|
53
|
-
@
|
54
|
-
end
|
55
|
-
|
56
|
-
def after_features(features)
|
57
|
-
publish_result
|
58
|
-
@io.flush
|
67
|
+
@scenario[:tags] = []
|
59
68
|
end
|
60
69
|
|
61
70
|
private
|
71
|
+
|
62
72
|
def publish_result
|
63
73
|
content = {
|
64
74
|
max: @max_test_id,
|
@@ -79,15 +89,14 @@ module QAT
|
|
79
89
|
------------------------------------
|
80
90
|
#{dups_info.join("\n")}
|
81
91
|
TXT
|
82
|
-
puts duplicates_info
|
92
|
+
Kernel.puts duplicates_info
|
83
93
|
end
|
84
94
|
|
85
|
-
@io.
|
86
|
-
indent: ' ',
|
87
|
-
space: ' ',
|
88
|
-
object_nl: "\n"
|
89
|
-
}))
|
95
|
+
@io.write (JSON.pretty_generate(content))
|
90
96
|
end
|
97
|
+
|
98
|
+
|
99
|
+
|
91
100
|
end
|
92
101
|
end
|
93
102
|
end
|