rspec_tesults_formatter 1.0.1 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40f6f7cf08acd616e7dc6f4c871ff6c00246334242962195e98b7d9bc66f25ec
4
- data.tar.gz: 3893baa02e5de01980fc3f09e6a76633dbefb23504296724217b1f18ce8e778b
3
+ metadata.gz: 201197e6528781ab2dd686a59df2f23b25fad36a8adf3689d9ae7e7eadb56404
4
+ data.tar.gz: 12d131612fbe6f1c63474c04719237440ec8748b277851c06032001797d5a3c5
5
5
  SHA512:
6
- metadata.gz: 6709b833360f19d90759645729c9023f5050ec5d364ef81efd83ca0b8ec278e58075e1a3d282690634ea87d1c8548b33556e82943427fe226b52a961509c904d
7
- data.tar.gz: 19e2a3d39a3782c308c226d4899173aaaee7796973289b113663eb8e1acf1d9a8276676c51261b2a2a932d8449fb0d4bc581af853971c4ee436f7e8e8d5f6a50
6
+ metadata.gz: 37aac9ed077de613d4750f84705481951aba5f0bef11734d78df6f7ae3246dd44d506be662241403379014963b9a4a95ccac42d783fe72cf544ff5245b93e733
7
+ data.tar.gz: dd7d4d2ac57360c3fe2345677e5e453bbb978487daebbda79a5d41a83892f106cbd1f827f510f153eb94deca3fd689b56e4b85f9a7f1cfd9aea3c251196ed381
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Tesults
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Tesults
2
+
3
+ Tesults is a test automation results reporting service. https://www.tesults.com
4
+
5
+ RSpec Tesults Formatter makes it easy to push test results data to Tesults from your RSpec tests.
6
+
7
+ ## Installation
8
+
9
+ `gem install rspec_tesults_formatter`
10
+
11
+ ## Configuration
12
+
13
+ ```rb
14
+ rspec --format TesultsFormatter spec
15
+ ```
16
+
17
+ ## Documentation
18
+
19
+ View https://www.tesults.com/docs/rspec for comprehensive documentation on the RSpec Tesults Formatter including detailed usage instructions and explanations on the arguments that you can supply.
20
+
21
+ ## GitHub Actions
22
+
23
+ `rspec_tesults_formatter` can produce a local results file for the Tesults Test
24
+ Automation Reporting action. No Tesults target token is required for this mode.
25
+
26
+ Install `rspec_tesults_formatter` 1.2.0 or later, add the action before the test
27
+ step, and run RSpec with the formatter as usual:
28
+
29
+ ```yaml
30
+ - uses: tesults/test-automation-reporting@v1
31
+ - run: rspec --format TesultsFormatter spec
32
+ ```
33
+
34
+ The action sets `TESULTS_OUTPUT_FILE` automatically. You can also set a path in
35
+ RSpec configuration with `tesults_output_file`; the environment variable takes
36
+ precedence when both are present:
37
+
38
+ ```rb
39
+ RSpec.configure do |config|
40
+ config.add_setting :tesults_output_file, :default => "/path/to/results.json"
41
+ end
42
+ ```
43
+
44
+ If both local output and `tesults_target` are configured, the formatter writes
45
+ the local results file and uploads the same run to Tesults.
46
+
47
+ ## Support
48
+
49
+ help@tesults.com
@@ -0,0 +1,3 @@
1
+ class TesultsFormatter
2
+ VERSION = '1.2.0'.freeze
3
+ end
@@ -1,141 +1,160 @@
1
+ require 'fileutils'
2
+ require 'json'
1
3
  require 'tesults'
4
+ require_relative 'rspec_tesults_formatter/version'
2
5
 
3
6
  class TesultsFormatter
4
- RSpec::Core::Formatters.register self, :example_finished, :dump_summary
7
+ RSpec::Core::Formatters.register self, :example_started, :example_finished, :dump_summary
5
8
 
6
9
  def filesForCase(suite, name)
7
10
  files = []
8
- if (@files == nil)
9
- return files
10
- end
11
+ return files if @files.nil?
12
+
11
13
  path = File.join(@files, suite, name)
12
- if (File.directory?(path) != true)
13
- return files
14
- else
15
- Dir.foreach(path) do |filename|
16
- next if filename == '.' or filename == '..' or filename == '.DS_Store'
17
- files.push(File.join(path, filename))
18
- end
14
+ return files unless File.directory?(path)
15
+
16
+ Dir.foreach(path) do |filename|
17
+ next if filename == '.' || filename == '..' || filename == '.DS_Store'
18
+
19
+ files.push(File.expand_path(File.join(path, filename)))
19
20
  end
20
- return files
21
+ files
21
22
  end
22
23
 
23
24
  def initialize(output)
24
25
  @output = output
25
26
 
26
- # args
27
- @disabled = true
28
- begin
29
- @target = RSpec.configuration.tesults_target
30
- rescue
31
- @target = nil
32
- end
33
- begin
34
- @files = RSpec.configuration.tesults_files
35
- rescue
36
- @files = nil
37
- end
38
- begin
39
- @buildName = RSpec.configuration.tesults_build_name
40
- rescue
41
- @buildName = nil
42
- end
43
- begin
44
- @buildDesc = RSpec.configuration.tesults_build_desc
45
- rescue
46
- @buildDesc = nil
47
- end
48
- begin
49
- @buildResult = RSpec.configuration.tesults_build_result
50
- if (@buildResult != "pass" && @buildResult != "fail")
51
- @buildResult = "unknown"
52
- end
53
- rescue
54
- @buildResult = "unknown"
55
- end
56
- begin
57
- @buildReason = RSpec.configuration.tesults_build_reason
58
- rescue
59
- @buildReason = nil
60
- end
27
+ @target = configuration_value(:tesults_target)
28
+ @files = configuration_value(:tesults_files)
29
+ @buildName = configuration_value(:tesults_build_name)
30
+ @buildDesc = configuration_value(:tesults_build_desc)
31
+ @buildResult = configuration_value(:tesults_build_result, 'unknown')
32
+ @buildResult = 'unknown' unless ['pass', 'fail'].include?(@buildResult)
33
+ @buildReason = configuration_value(:tesults_build_reason)
34
+ @outputFile = configuration_value(:tesults_output_file)
61
35
 
62
- if (@target != nil)
63
- @disabled = false
64
- end
65
- if (@disabled == true)
66
- puts 'Tesults disabled. No target supplied.'
67
- end
36
+ environmentOutputFile = ENV['TESULTS_OUTPUT_FILE']
37
+ @outputFile = environmentOutputFile unless blank?(environmentOutputFile)
38
+
39
+ @disabled = @target.nil? && blank?(@outputFile)
40
+ puts 'Tesults disabled. No target supplied.' if @disabled
68
41
 
69
42
  @data = {
70
43
  :target => @target,
71
44
  :results => {
72
45
  :cases => []
46
+ },
47
+ :metadata => {
48
+ :integration_name => 'rspec_tesults_formatter',
49
+ :integration_version => TesultsFormatter::VERSION,
50
+ :test_framework => 'rspec'
73
51
  }
74
52
  }
53
+
54
+ @starttimes = {}
55
+ end
56
+
57
+ def example_started(notification)
58
+ return if @disabled
59
+
60
+ example = notification.example
61
+ @starttimes[example.id] = (Time.now.to_f * 1000).to_i
75
62
  end
76
63
 
77
64
  def example_finished(notification)
78
- if (@disabled == true)
79
- return
80
- end
65
+ return if @disabled
66
+
81
67
  example = notification.example
82
68
  result = example.execution_result.status.to_s
83
- if result == "passed"
84
- result = "pass"
85
- elsif result == "failed"
86
- result = "fail"
69
+ if result == 'passed'
70
+ result = 'pass'
71
+ elsif result == 'failed'
72
+ result = 'fail'
87
73
  else
88
- result = "unknown"
74
+ result = 'unknown'
89
75
  end
90
76
 
91
- name = example.description
92
- desc = example.metadata[:example_group][:description]
93
- suite = example.metadata[:example_group][:parent_example_group][:description]
94
- reason = example.exception
95
-
96
- if reason == nil
97
- reason = ""
98
- else
99
- reason = reason.to_s
100
- end
77
+ group = example.metadata[:example_group] || {}
78
+ parentGroup = group[:parent_example_group] || {}
79
+ desc = group[:description]
80
+ suite = parentGroup[:description] || ''
81
+ reason = example.exception.nil? ? '' : example.exception.to_s
101
82
 
102
- @data[:results][:cases].push({
83
+ testCase = {
103
84
  :name => example.description,
104
85
  :result => result,
105
86
  :desc => desc,
106
87
  :suite => suite,
107
88
  :reason => reason,
108
- :files => filesForCase(suite, example.description)
109
- })
89
+ :files => filesForCase(suite, example.description),
90
+ :start => @starttimes[example.id],
91
+ :end => (Time.now.to_f * 1000).to_i
92
+ }
93
+
94
+ source = example.metadata[:file_path]
95
+ line = example.metadata[:line_number]
96
+ unless source.nil?
97
+ location = { :file => File.expand_path(source) }
98
+ location[:line] = line.to_i unless line.nil?
99
+ testCase[:_Location] = JSON.generate(location)
100
+ end
110
101
 
111
- #@output.puts name + ": " + result
102
+ @data[:results][:cases].push(testCase)
112
103
  end
113
104
 
114
- def dump_summary (message)
115
- if (@disabled == true)
116
- return
117
- end
118
- if (@buildName != nil && @buildResult != nil)
105
+ def dump_summary(_message)
106
+ return if @disabled
107
+
108
+ if !@buildName.nil? && !@buildResult.nil?
119
109
  buildCase = {
120
110
  :name => @buildName,
121
- :suite => "[build]",
111
+ :suite => '[build]',
122
112
  :result => @buildResult
123
113
  }
124
- if (@buildDesc != nil)
125
- buildCase[:desc] = @buildDesc
126
- end
127
- if (@buildReason != nil)
128
- buildCase[:reason] = @buildReason
129
- end
130
- buildCase[:files] = filesForCase("[build]", @buildName)
114
+ buildCase[:desc] = @buildDesc unless @buildDesc.nil?
115
+ buildCase[:reason] = @buildReason unless @buildReason.nil?
116
+ buildCase[:files] = filesForCase('[build]', @buildName)
131
117
  @data[:results][:cases].push(buildCase)
132
118
  end
133
- # Use this puts for debugging: puts(@data)
119
+
120
+ writeOutputFile
121
+ return if @target.nil?
122
+
134
123
  puts 'Uploading results to Tesults...'
135
124
  res = Tesults.upload(@data)
136
- puts 'Success: ' + (res[:success] ? "true" : "false")
125
+ puts 'Success: ' + (res[:success] ? 'true' : 'false')
137
126
  puts 'Message: ' + res[:message]
138
127
  puts 'Warnings: ' + res[:warnings].length.to_s
139
128
  puts 'Errors: ' + res[:errors].length.to_s
140
129
  end
141
- end
130
+
131
+ private
132
+
133
+ def blank?(value)
134
+ value.nil? || value.to_s.empty?
135
+ end
136
+
137
+ def configuration_value(name, default = nil)
138
+ RSpec.configuration.public_send(name)
139
+ rescue StandardError
140
+ default
141
+ end
142
+
143
+ def writeOutputFile
144
+ return false if blank?(@outputFile)
145
+
146
+ begin
147
+ outputFile = File.expand_path(@outputFile)
148
+ FileUtils.mkdir_p(File.dirname(outputFile))
149
+ localData = @data.merge(:target => '')
150
+ File.open(outputFile, 'w') do |file|
151
+ file.write(JSON.generate(localData))
152
+ end
153
+ puts 'Tesults results written to ' + outputFile
154
+ true
155
+ rescue StandardError => error
156
+ puts 'Error writing Tesults results file: ' + error.to_s
157
+ false
158
+ end
159
+ end
160
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec_tesults_formatter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Ajeet Dhaliwal
8
- autorequire:
7
+ - ajeetd
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2020-05-07 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: tesults
@@ -24,6 +23,40 @@ dependencies:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
25
  version: 1.1.1
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '3.9'
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '4'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '3.9'
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '4'
46
+ - !ruby/object:Gem::Dependency
47
+ name: minitest
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: 5.25.0
53
+ type: :development
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: 5.25.0
27
60
  - !ruby/object:Gem::Dependency
28
61
  name: tesults
29
62
  requirement: !ruby/object:Gem::Requirement
@@ -46,12 +79,14 @@ executables: []
46
79
  extensions: []
47
80
  extra_rdoc_files: []
48
81
  files:
82
+ - LICENSE.txt
83
+ - README.md
49
84
  - lib/rspec_tesults_formatter.rb
50
- homepage: https://www.tesults.com
85
+ - lib/rspec_tesults_formatter/version.rb
86
+ homepage: https://www.tesults.com/docs/rspec
51
87
  licenses:
52
88
  - MIT
53
89
  metadata: {}
54
- post_install_message:
55
90
  rdoc_options: []
56
91
  require_paths:
57
92
  - lib
@@ -66,9 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
66
101
  - !ruby/object:Gem::Version
67
102
  version: '0'
68
103
  requirements: []
69
- rubyforge_project:
70
- rubygems_version: 2.7.6
71
- signing_key:
104
+ rubygems_version: 3.6.9
72
105
  specification_version: 4
73
106
  summary: RSpec Tesults Formatter
74
107
  test_files: []