cucumber-report-format 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 47778d25b6cc4b829087a094e7f5faabdcaefd20
4
+ data.tar.gz: abb639d264d8e3c8051363270c2ff04eb81555f3
5
+ SHA512:
6
+ metadata.gz: 494dcde596471f0013cc5ba024e0998ce7264347fca5c1c199fffcd48bd25cb45cb346fbd7898a9d00e2c2f3de572d1331ede8f56403f11eeca63c57143f36b0
7
+ data.tar.gz: ef1e81c71e49c98e5424bfcf7118052250018646aa6d47fdf7728ce9d2c2b16379cc8ff52053ceb3afbef422c8bf5a6922130ba1851a57c62cf09b89b5ea94d9
@@ -0,0 +1 @@
1
+ cucumber-report-format*gem
@@ -0,0 +1,14 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2017-01-16 21:03:27 +0100 using RuboCop version 0.44.1.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ Style/Documentation:
11
+ Exclude:
12
+ - 'spec/**/*'
13
+ - 'test/**/*'
14
+ - 'bin/cucumber-report-format'
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gem 'multi_json'
3
+ gem 'rake'
4
+ gem 'rubocop'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Funkwerk AG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ # cucumber-report-format
2
+ Formats Cucumber Reports
@@ -0,0 +1,18 @@
1
+ task default: :build
2
+
3
+ desc 'Builds the Gem.'
4
+ task build: :audit do
5
+ sh 'gem build cucumber-report-format.gemspec'
6
+ end
7
+
8
+ desc 'Publishes the Gem'
9
+ task :push do
10
+ sh 'gem push cucumber-report-format-0.0.1.gem'
11
+ end
12
+
13
+ task audit: :rubocop
14
+
15
+ desc 'Checks ruby style'
16
+ task :rubocop do
17
+ sh 'rubocop bin/*'
18
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'multi_json'
3
+
4
+ puts MultiJson.dump ARGV.map { |file| MultiJson.load File.read file }.flatten
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'stringio'
4
+ require 'multi_json'
5
+ require 'erb'
6
+
7
+ class Format
8
+ def render(template, file)
9
+ content = File.read file
10
+
11
+ render_content(template, content)
12
+ end
13
+
14
+ def render_content(template, content)
15
+ behave_output = BehaveOutput.new MultiJson.load(content)
16
+
17
+ renderer = ERB.new File.read template
18
+ puts renderer.result behave_output.binding_reference
19
+ end
20
+
21
+ # container class for erb variable
22
+ class BehaveOutput
23
+ attr_accessor :features
24
+
25
+ def initialize(features)
26
+ @features = features
27
+ end
28
+
29
+ def binding_reference
30
+ binding
31
+ end
32
+ end
33
+ end
34
+
35
+ options = {}
36
+ OptionParser.new do |opts|
37
+ opts.banner = 'Usage: format [files]'
38
+ opts.on('--template [TEMPLATE]', 'Renders into template') do |template|
39
+ options[:template] = template
40
+ end
41
+ opts.on('-', 'Reads from stdin') do
42
+ options[:stdin] = true
43
+ end
44
+ end.parse!
45
+
46
+ formatter = Format.new
47
+
48
+ exit 1 unless options.key? :template
49
+
50
+ if options.key? :stdin
51
+ formatter.render_content(options[:template], STDIN.read)
52
+ else
53
+ ARGV.each { |file| formatter.render(options[:template], file) }
54
+ end
@@ -0,0 +1,12 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'cucumber-report-format'
3
+ s.version = '0.0.1'
4
+ s.date = '2017-01-16'
5
+ s.summary = 'Format Cucumber Reports'
6
+ s.description = 'Template Engine for Cucumber Reports'
7
+ s.authors = ['Stefan Rohe']
8
+ s.homepage = 'http://github.com/funkwerk/cucumber-report-format/'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.executables = s.files.grep(%r{^bin/}) { |file| File.basename(file) }.sort.reverse
11
+ s.add_runtime_dependency 'multi_json', ['>= 1.11.2']
12
+ end
@@ -0,0 +1,131 @@
1
+ <%
2
+ def background(feature)
3
+ return {} unless feature.key? 'elements'
4
+ backgrounds = feature['elements'].select { |element| element['keyword'] == 'Background' }
5
+ return {} if backgrounds.length == 0
6
+ backgrounds.first
7
+ end
8
+
9
+ def output_background(background)
10
+ return '' if background == {}
11
+ result = '#### Background'
12
+ result += " (#{background['name']})" if background.key? 'name'
13
+ result += "\n\n"
14
+ result + output_steps(background)
15
+ end
16
+
17
+ def output_steps(element)
18
+ result = ''
19
+ steps = []
20
+ steps = element['steps'] if element.key? 'steps'
21
+ steps.each do |step|
22
+ result += "#{step['keyword']} #{step['name']}"
23
+ result += output_html_table(step)
24
+ result += output_text(step)
25
+ result += "\n"
26
+ end
27
+ result
28
+ end
29
+
30
+ def output_html_table(step)
31
+ return '' unless step.key? 'table'
32
+ result = "\n<table><tr><td>#{step['table']['headings'].join '</td><td>'}</td></tr>"
33
+ step['table']['rows'].each do |row|
34
+ result += "<tr><td>#{row.join '</td><td>'}</td></tr>"
35
+ end
36
+ result += '</table>'
37
+ result
38
+ end
39
+
40
+ def output_table(step)
41
+ return '' unless step.key? 'table'
42
+ result = "\n| #{step['table']['headings'].join ' | '} |"
43
+ step['table']['rows'].each do |row|
44
+ result += "\n| #{row.join ' | '} |"
45
+ end
46
+ result
47
+ end
48
+
49
+
50
+ def output_text(step)
51
+ return '' unless step.key? 'text'
52
+ return "\n > " + step['text'] if step['text'].instance_of? String
53
+ "\n > " + step['text'].join("\n> ")
54
+ end
55
+
56
+
57
+ def is_automatic?(scenario)
58
+ tags = []
59
+ tags = scenario['tags'] if scenario.key? 'tags'
60
+ tags.each do |tag|
61
+ return false if tag == '@manual'
62
+ end
63
+ true
64
+ end
65
+
66
+ def scenarios(feature)
67
+ return [] unless feature.key? 'elements'
68
+ feature['elements'].select { |element| element['keyword'] != 'Background' }
69
+ end
70
+
71
+ def test_result(test)
72
+ status = 'passed'
73
+ duration = 0
74
+ error = []
75
+
76
+ steps = []
77
+ steps = test['steps'] if test.key? 'steps'
78
+ steps.each do |step|
79
+ next unless step.key? 'result'
80
+ duration += step['result']['duration'] if step['result'].key? 'duration'
81
+ next if status == 'failed'
82
+ status = step['result']['status'] if step['result'].key? 'status'
83
+ step['result']['error_message'].each { |a| error.push a } if step['result'].key? 'error_message'
84
+ end
85
+ # TODO: symbols as keys, not strings
86
+ {'status' => status, 'duration' => duration, 'error' => error}
87
+ end
88
+
89
+ def hover_div(scenario)
90
+ result = "<div class='outer'><div>#{@scenario['name']}</div><div class='inner'>#{output_steps(@scenario).gsub("\n", '<br>').gsub('|','')}</div></div>"
91
+
92
+ result
93
+ end
94
+
95
+ def test_comment(scenario)
96
+ errors = test_result(scenario)['error']
97
+ return '' if errors.empty?
98
+ errors.last
99
+ end
100
+
101
+ %>
102
+
103
+ ## Features
104
+
105
+ <style>
106
+ .inner {
107
+ display: none;
108
+ }
109
+
110
+ .outer:hover .inner {
111
+ display: block;
112
+ }
113
+ </style>
114
+
115
+ <%
116
+ number = 0
117
+ %>
118
+ <% for @feature in @features %>### <%= @feature['name'] %>
119
+
120
+ #### Description
121
+
122
+ > <%= @feature['description'].join "\n> " %>
123
+
124
+ <%= output_background(background(@feature)) %>
125
+ #### Testscenarios and Results
126
+
127
+ | No | Scenario | Type | Result | Comment |
128
+ |----|----------|------|--------|---------|
129
+ <% for @scenario in scenarios(@feature) %><% number += 1 %>| <%= number %> | <%= hover_div(@scenario) %> | <%= is_automatic?(@scenario) ? 'automatic' : 'manual' %> | <%= test_result(@scenario)['status'] %> | <%= test_comment(@scenario) %> |
130
+ <% end %>
131
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <%
2
+ def all_tests(features)
3
+ tests = []
4
+ features.each do |feature|
5
+ next unless feature.key? 'elements'
6
+ feature['elements'].select { |element| element["keyword"] != 'Background' }.each do |element|
7
+ tests.push element
8
+ end
9
+ end
10
+ tests
11
+ end
12
+
13
+ def test_result(test)
14
+ status = 'passed'
15
+ duration = 0
16
+
17
+ steps = []
18
+ steps = test['steps'] if test.key? 'steps'
19
+ steps.each do |step|
20
+ next unless step.key? 'result'
21
+ result = step['result']
22
+ duration += result['duration'] if result.key? 'duration'
23
+ next if status == 'failed'
24
+ status = result['status'] if result.key? 'status'
25
+ end
26
+ {'status' => status, 'duration' => duration}
27
+ end
28
+
29
+ def is_executed?(test)
30
+ test['tags'].each do |tag|
31
+ return false if tag == '@skip'
32
+ end
33
+ true
34
+ end
35
+ %><%= all_tests(@features).length %> | <%= all_tests(@features).select { |test| test_result(test)['status'] == 'passed' }.length %> | <%= all_tests(@features).select { |test| test_result(test)['status'] == 'failed' }.length %> | <%= all_tests(@features).select { |test| !is_executed? test }.length %>
@@ -0,0 +1,42 @@
1
+ <%
2
+ def all_tests(features)
3
+ tests = []
4
+ features.each do |feature|
5
+ next unless feature.key? 'elements'
6
+ feature['elements'].select { |element| element["keyword"] != 'Background' }.each do |element|
7
+ tests.push element
8
+ end
9
+ end
10
+ tests
11
+ end
12
+
13
+ def test_result(test)
14
+ status = 'passed'
15
+ duration = 0
16
+
17
+ steps = []
18
+ steps = test['steps'] if test.key? 'steps'
19
+ steps.each do |step|
20
+ next unless step.key? 'result'
21
+ result = step['result']
22
+ duration += result['duration'] if result.key? 'duration'
23
+ next if status == 'failed'
24
+ status = result['status'] if result.key? 'status'
25
+ end
26
+ {'status' => status, 'duration' => duration}
27
+ end
28
+
29
+ def is_executed?(test)
30
+ test['tags'].each do |tag|
31
+ return false if tag == '@skip'
32
+ end
33
+ true
34
+ end
35
+ %>
36
+ ## Summary
37
+
38
+ | Tests | <%= all_tests(@features).length %> |
39
+ | - | - |
40
+ | Passed | <%= all_tests(@features).select { |test| test_result(test)['status'] == 'passed' }.length %> |
41
+ | Failed | <%= all_tests(@features).select { |test| test_result(test)['status'] == 'failed' }.length %> |
42
+ | Not Executed | <%= all_tests(@features).select { |test| !is_executed? test }.length %> |
@@ -0,0 +1,34 @@
1
+ <%
2
+ def extract_used_tags(features)
3
+ count features.map { |feature| extract_feature_tags feature }.flatten
4
+ end
5
+
6
+ def extract_feature_tags(feature)
7
+ tags = []
8
+
9
+ tags += feature['tags'] if feature.key? 'tags'
10
+ feature['elements'].each { |e| tags += extract_element_tags(e) } if feature.key? 'elements'
11
+ tags
12
+ end
13
+
14
+ def extract_element_tags(feature)
15
+ tags = []
16
+
17
+ tags += feature['tags'] if feature.key? 'tags'
18
+ tags
19
+ end
20
+
21
+ def count(list)
22
+ tags = {}
23
+
24
+ list.each do |a|
25
+ tags[a] = 0 unless tags.key? a
26
+ tags[a] += 1
27
+ end
28
+ tags
29
+ end
30
+ %>
31
+ | Tag | Amount |
32
+ | - | - |
33
+ <% for @key, @amount in extract_used_tags(@features).sort_by {|_, v| v }.reverse %>| <%= @key %> | <%= @amount %> |
34
+ <% end %>
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cucumber-report-format
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Stefan Rohe
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.11.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.11.2
27
+ description: Template Engine for Cucumber Reports
28
+ email:
29
+ executables:
30
+ - cucumber-report-format
31
+ - combine-cucumber-reports
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rubocop.yml"
37
+ - ".travis.yml"
38
+ - Gemfile
39
+ - LICENSE
40
+ - README.md
41
+ - Rakefile
42
+ - bin/combine-cucumber-reports
43
+ - bin/cucumber-report-format
44
+ - cucumber-report-format.gemspec
45
+ - templates/markdown.erb
46
+ - templates/overall_summary.erb
47
+ - templates/summary.erb
48
+ - templates/tag_overview.erb
49
+ homepage: http://github.com/funkwerk/cucumber-report-format/
50
+ licenses: []
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.2.2
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Format Cucumber Reports
72
+ test_files: []