blinka-reporter 0.7.1 → 0.8.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 +4 -4
- data/.github/workflows/main.yml +1 -1
- data/.husky/pre-commit +4 -0
- data/CHANGELOG.md +9 -0
- data/README.md +59 -36
- data/blinka_reporter.gemspec +26 -28
- data/lib/blinka_reporter/cli.rb +6 -35
- data/lib/blinka_reporter/client.rb +19 -22
- data/lib/blinka_reporter/error.rb +2 -1
- data/lib/blinka_reporter/minitest_adapter.rb +9 -6
- data/lib/blinka_reporter/tap.rb +8 -8
- data/lib/blinka_reporter/version.rb +1 -1
- data/lib/blinka_reporter.rb +4 -3
- data/lib/minitest/blinka_plugin.rb +20 -9
- data/package.json +8 -6
- data/yarn.lock +4 -11
- metadata +6 -21
- data/lib/blinka_reporter/blinka.rb +0 -172
- data/lib/blinka_reporter/config.rb +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e38a0d8af21650a7cfb551b735e8431b5b41ac746d370a894d506cd3a73e619
|
4
|
+
data.tar.gz: 43476fae029f71235e2cca909385a14a4b9ea85b712dc0182c26c4bd91471752
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c5ab57ba4038477fd56fffb5f8628cee862b973db2b5bb9aa828dd5edb5f75c7a32209b625f262fbce4463c86df11927a0dd818a3c163dde7c48c2c87edb203
|
7
|
+
data.tar.gz: a63ce0796100d73fb7fd48689f7a799b84a321a39e92487e207b123bce30970f66c30b5679a72975aab84fdf99b583e5c8ebf25f8d5f4e03b04b0d4ee97a4c31
|
data/.github/workflows/main.yml
CHANGED
data/.husky/pre-commit
ADDED
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [0.8.0] - 2023-03-04
|
11
|
+
|
12
|
+
- Removes support for reporting to Blinka, removing the need for httparty.
|
13
|
+
- Makes `Capybara.save_path` relative to the current working directory for images
|
14
|
+
|
15
|
+
## [0.7.2] - 2023-02-19
|
16
|
+
|
17
|
+
- Adds support for `BLINKA_APPEND=true` to append to existing JSON-files.
|
18
|
+
|
10
19
|
## [0.7.1] - 2023-02-19
|
11
20
|
|
12
21
|
- Handles empty test results.
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ gem install blinka-reporter
|
|
16
16
|
or add to your Gemfile
|
17
17
|
|
18
18
|
```ruby
|
19
|
-
gem 'blinka-reporter', '~> 0.7.
|
19
|
+
gem 'blinka-reporter', '~> 0.7.2'
|
20
20
|
```
|
21
21
|
|
22
22
|
## Which ruby testing frameworks are supported?
|
@@ -48,11 +48,6 @@ Make sure [rspec_junit_formatter](https://github.com/sj26/rspec_junit_formatter)
|
|
48
48
|
bundle exec rspec --formatter RspecJunitFormatter --out ./rspec.xml
|
49
49
|
```
|
50
50
|
|
51
|
-
## How to send report to Blinka?
|
52
|
-
|
53
|
-
1. Output your test results as described [above](#how-to-generate-test-report-in-the-right-format).
|
54
|
-
1. `bundle exec blinka_reporter --path {./blinka_results.json,./rspec.xml} --blinka --team-id <BLINKA_TEAM_ID> --team-secret <BLINKA_TEAM_SECRET> --repository davidwessman/blinka_reporter`
|
55
|
-
|
56
51
|
## How can I send report in Github Action?
|
57
52
|
|
58
53
|
Add a step to your Github Action Workflow after running tests:
|
@@ -60,36 +55,47 @@ Add a step to your Github Action Workflow after running tests:
|
|
60
55
|
```yaml
|
61
56
|
- name: Minitest
|
62
57
|
env:
|
63
|
-
|
58
|
+
BLINKA_PATH: ./results.json
|
64
59
|
run: bundle exec rake test
|
65
60
|
|
66
|
-
|
61
|
+
// Add a tag to be able to separate multiple jobs, e.g. "ruby-${{ matrix.ruby }}".
|
62
|
+
// This is optional.
|
63
|
+
- name: Export Blinka-metadata
|
64
|
+
if: always()
|
67
65
|
run: |
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
66
|
+
echo "ruby gem" > ./blinka_tag
|
67
|
+
|
68
|
+
// Archive all files required by Blinka, json, the tag and any images.
|
69
|
+
// Blinka will automatically fetch the results when the Github Action Workflow is finished.
|
70
|
+
- name: Archive results for Blinka
|
71
|
+
if: always()
|
72
|
+
uses: actions/upload-artifact@v3
|
73
|
+
with:
|
74
|
+
name: blinka-${{ strategy.job-index }}
|
75
|
+
path: |
|
76
|
+
./results.json
|
77
|
+
./blinka_tag
|
75
78
|
```
|
76
79
|
|
77
80
|
```yaml
|
78
81
|
- name: Rspec
|
79
82
|
run: bundle exec rspec --formatter RspecJunitFormatter --out ./rspec.xml
|
80
|
-
|
83
|
+
|
84
|
+
- name: Export Blinka-metadata
|
85
|
+
if: always()
|
81
86
|
run: |
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
87
|
+
echo "ruby gem" > ./blinka_tag
|
88
|
+
|
89
|
+
- name: Archive results for Blinka
|
90
|
+
if: always()
|
91
|
+
uses: actions/upload-artifact@v3
|
92
|
+
with:
|
93
|
+
name: blinka-${{ strategy.job-index }}
|
94
|
+
path: |
|
95
|
+
./rspec.xml
|
96
|
+
./blinka_tag
|
89
97
|
```
|
90
98
|
|
91
|
-
`--tag` is optional and can be used to separate different reports, for example when using a build matrix.
|
92
|
-
|
93
99
|
## How to make multiple test runs into one report?
|
94
100
|
|
95
101
|
For example when running tests in parallel you might need to run system tests separately.
|
@@ -104,19 +110,36 @@ Output the test results to different paths with `BLINKA_PATH`.
|
|
104
110
|
|
105
111
|
- name: Tests
|
106
112
|
env:
|
107
|
-
|
113
|
+
BLINKA_PATH: ./tests.json
|
108
114
|
run: bundle exec rails test
|
109
115
|
|
110
|
-
- name:
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
116
|
+
- name: Archive results for Blinka
|
117
|
+
if: always()
|
118
|
+
uses: actions/upload-artifact@v3
|
119
|
+
with:
|
120
|
+
name: blinka-${{ strategy.job-index }}
|
121
|
+
path: |
|
122
|
+
./tests.json
|
123
|
+
./system_tests.json
|
124
|
+
./blinka_tag
|
125
|
+
```
|
126
|
+
|
127
|
+
## How can I run multiple test runs to one file?
|
128
|
+
|
129
|
+
For Minitest this can be done by setting `BLINKA_APPEND=true`, make sure to clean the `BLINKA_PATH` file before running the tests.
|
130
|
+
|
131
|
+
```yaml
|
132
|
+
- name: Tests 1
|
133
|
+
env:
|
134
|
+
BLINKA_PATH: ./tests.json
|
135
|
+
BLINKA_APPEND: true
|
136
|
+
run: bundle exec rails test:system
|
137
|
+
|
138
|
+
- name: Tests 2
|
139
|
+
env:
|
140
|
+
BLINKA_PATH: ./tests.json
|
141
|
+
BLINKA_APPEND: true
|
142
|
+
run: bundle exec rails test
|
120
143
|
```
|
121
144
|
|
122
145
|
## How can I report tests in TAP-format?
|
data/blinka_reporter.gemspec
CHANGED
@@ -1,41 +1,39 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative "lib/blinka_reporter/version"
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
gem.authors = [
|
4
|
+
gem.authors = ["David Wessman"]
|
5
5
|
gem.description =
|
6
|
-
|
7
|
-
gem.email =
|
8
|
-
gem.homepage =
|
9
|
-
gem.license =
|
10
|
-
gem.summary =
|
6
|
+
"Use to format test results from Minitest to use with Blinka."
|
7
|
+
gem.email = "david@wessman.co"
|
8
|
+
gem.homepage = "https://github.com/davidwessman/blinka_reporter"
|
9
|
+
gem.license = "MIT"
|
10
|
+
gem.summary = "Format tests for Blinka"
|
11
11
|
|
12
12
|
gem.metadata = {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
"homepage_uri" => "https://github.com/davidwessman/blinka_reporter",
|
14
|
+
"bug_tracker_uri" =>
|
15
|
+
"https://github.com/davidwessman/blinka_reporter/issues",
|
16
|
+
"documentation_uri" => "https://github.com/davidwessman/blinka_reporter",
|
17
|
+
"changelog_uri" =>
|
18
|
+
"https://github.com/davidwessman/blinka_reporter/main/CHANGELOG.md",
|
19
|
+
"source_code_uri" => "https://github.com/davidwessman/blinka_reporter",
|
20
|
+
"rubygems_mfa_required" => "true"
|
21
21
|
}
|
22
22
|
|
23
23
|
gem.files =
|
24
|
-
Dir.chdir(File.expand_path(
|
25
|
-
`git ls-files -z
|
26
|
-
.split("\x0")
|
24
|
+
Dir.chdir(File.expand_path("..", __FILE__)) do
|
25
|
+
`git ls-files -z`.split("\x0")
|
27
26
|
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
28
27
|
end
|
29
|
-
gem.name =
|
28
|
+
gem.name = "blinka-reporter"
|
30
29
|
gem.version = BlinkaReporter::VERSION
|
31
|
-
gem.executables = [
|
32
|
-
gem.require_path = [
|
30
|
+
gem.executables = ["blinka_reporter"]
|
31
|
+
gem.require_path = ["lib"]
|
33
32
|
|
34
|
-
gem.add_dependency(
|
35
|
-
gem.
|
36
|
-
gem.add_development_dependency(
|
37
|
-
gem.add_development_dependency(
|
38
|
-
gem.add_development_dependency(
|
39
|
-
gem.add_development_dependency(
|
40
|
-
gem.add_development_dependency('webmock', '~> 3.11')
|
33
|
+
gem.add_dependency("ox", "~> 2")
|
34
|
+
gem.add_development_dependency("dotenv", "~> 2.8.0")
|
35
|
+
gem.add_development_dependency("minitest", "~> 5.0")
|
36
|
+
gem.add_development_dependency("mocha", "~> 2.0")
|
37
|
+
gem.add_development_dependency("rake", "~> 13")
|
38
|
+
gem.add_development_dependency("syntax_tree", "~> 6.0")
|
41
39
|
end
|
data/lib/blinka_reporter/cli.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "blinka_reporter/client"
|
2
|
+
require "blinka_reporter/version"
|
3
3
|
|
4
4
|
module BlinkaReporter
|
5
5
|
class Cli
|
6
6
|
def self.run(argv)
|
7
|
-
if (argv.index(
|
7
|
+
if (argv.index("--help") || -1) >= 0
|
8
8
|
puts(<<~EOS)
|
9
9
|
blinka_reporter version #{BlinkaReporter::VERSION}
|
10
10
|
|
@@ -14,46 +14,17 @@ module BlinkaReporter
|
|
14
14
|
- ./rspec.xml from https://github.com/sj26/rspec_junit_formatter
|
15
15
|
|
16
16
|
--tap: Flag for outputting test results in TAP-protocol, helpful on Heroku CI
|
17
|
-
--blinka: Flag for reporting test results to blinka.app, requires also supplying:
|
18
|
-
- --team-id
|
19
|
-
- --team-secret
|
20
|
-
- --repository
|
21
|
-
- --commit
|
22
|
-
--team-id <team-id>: Blinka team id, only used with --blinka
|
23
|
-
--team-secret <team-secret>: Blinka team secret, only used with --blinka
|
24
|
-
--commit <commit>: The commit hash to report
|
25
|
-
--tag <tag>: The tag for the run, for example to separate a test matrix
|
26
|
-
--repository <repository>: The Github repository
|
27
|
-
--host <host>: Override Blink host to send report
|
28
|
-
|
29
17
|
EOS
|
30
18
|
return 0
|
31
19
|
end
|
32
20
|
|
33
|
-
tap = (argv.index(
|
34
|
-
|
35
|
-
paths = argv_value_for(argv, '--path')
|
21
|
+
tap = (argv.index("--tap") || -1) >= 0
|
36
22
|
|
37
|
-
|
38
|
-
commit = argv_value_for(argv, '--commit')&.first
|
39
|
-
repository = argv_value_for(argv, '--repository')&.first
|
40
|
-
tag = argv_value_for(argv, '--tag')&.first
|
41
|
-
team_id = argv_value_for(argv, '--team-id')&.first
|
42
|
-
team_secret = argv_value_for(argv, '--team-secret')&.first
|
43
|
-
host = argv_value_for(argv, '--host')&.first
|
23
|
+
paths = argv_value_for(argv, "--path")
|
44
24
|
|
45
25
|
client = BlinkaReporter::Client.new
|
46
26
|
data = client.parse(paths: paths)
|
47
|
-
|
48
|
-
BlinkaReporter::Config.new(
|
49
|
-
tag: tag,
|
50
|
-
commit: commit,
|
51
|
-
team_id: team_id,
|
52
|
-
team_secret: team_secret,
|
53
|
-
repository: repository,
|
54
|
-
host: host
|
55
|
-
)
|
56
|
-
client.report(data: data, config: config, tap: tap, blinka: blinka)
|
27
|
+
client.report(data: data, tap: tap)
|
57
28
|
end
|
58
29
|
|
59
30
|
def self.argv_value_for(argv, option_name)
|
@@ -1,15 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "ox"
|
2
|
+
require "json"
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require 'blinka_reporter/error'
|
7
|
-
require 'blinka_reporter/tap'
|
4
|
+
require "blinka_reporter/error"
|
5
|
+
require "blinka_reporter/tap"
|
8
6
|
|
9
7
|
module BlinkaReporter
|
10
8
|
class Client
|
11
9
|
def parse(paths: nil)
|
12
|
-
paths ||= [
|
10
|
+
paths ||= ["./blinka_results.json"]
|
13
11
|
paths = Array(paths)
|
14
12
|
paths.each do |path|
|
15
13
|
unless File.exist?(path)
|
@@ -22,9 +20,9 @@ module BlinkaReporter
|
|
22
20
|
|
23
21
|
merge_results(
|
24
22
|
paths.map do |path|
|
25
|
-
if path.end_with?(
|
23
|
+
if path.end_with?(".xml")
|
26
24
|
parse_xml(path: path)
|
27
|
-
elsif path.end_with?(
|
25
|
+
elsif path.end_with?(".json")
|
28
26
|
parse_json(path: path)
|
29
27
|
else
|
30
28
|
raise(
|
@@ -36,9 +34,8 @@ module BlinkaReporter
|
|
36
34
|
)
|
37
35
|
end
|
38
36
|
|
39
|
-
def report(data:,
|
37
|
+
def report(data:, tap: false)
|
40
38
|
BlinkaReporter::Tap.report(data) if tap
|
41
|
-
BlinkaReporter::Blinka.report(config: config, data: data) if blinka
|
42
39
|
0
|
43
40
|
end
|
44
41
|
|
@@ -62,12 +59,12 @@ module BlinkaReporter
|
|
62
59
|
def parse_xml(path:)
|
63
60
|
data = Ox.load_file(path, { symbolize_keys: true, skip: :skip_none })
|
64
61
|
test_suite = data.root
|
65
|
-
unless test_suite.name ==
|
62
|
+
unless test_suite.name == "testsuite"
|
66
63
|
raise("Root element is not <testsuite>, instead #{test_suite.name}")
|
67
64
|
end
|
68
65
|
|
69
|
-
properties = test_suite.nodes.select { |node| node.name ==
|
70
|
-
test_cases = test_suite.nodes.select { |node| node.name ==
|
66
|
+
properties = test_suite.nodes.select { |node| node.name == "properties" }
|
67
|
+
test_cases = test_suite.nodes.select { |node| node.name == "testcase" }
|
71
68
|
{
|
72
69
|
nbr_tests: Integer(test_suite.tests || 0),
|
73
70
|
total_time: Float(test_suite.time),
|
@@ -79,7 +76,7 @@ module BlinkaReporter
|
|
79
76
|
def xml_seed(ox_properties)
|
80
77
|
ox_properties.each do |property|
|
81
78
|
property.nodes.each do |node|
|
82
|
-
return node.attributes[:value] if node.attributes[:name] ==
|
79
|
+
return node.attributes[:value] if node.attributes[:name] == "seed"
|
83
80
|
end
|
84
81
|
end
|
85
82
|
nil
|
@@ -89,18 +86,18 @@ module BlinkaReporter
|
|
89
86
|
def xml_test_cases(test_cases)
|
90
87
|
test_cases.map do |test_case|
|
91
88
|
result = {
|
92
|
-
kind: Array(test_case.attributes[:classname]&.split(
|
89
|
+
kind: Array(test_case.attributes[:classname]&.split("."))[1],
|
93
90
|
name: test_case.attributes[:name],
|
94
|
-
path: test_case.attributes[:file]&.delete_prefix(
|
91
|
+
path: test_case.attributes[:file]&.delete_prefix("./"),
|
95
92
|
time: Float(test_case.attributes[:time] || 0)
|
96
93
|
}
|
97
94
|
if test_case.nodes.any?
|
98
|
-
skipped = test_case.nodes.any? { |node| node.name ==
|
99
|
-
result[:result] =
|
95
|
+
skipped = test_case.nodes.any? { |node| node.name == "skipped" }
|
96
|
+
result[:result] = "skip" if skipped
|
100
97
|
failure =
|
101
|
-
test_case.nodes.select { |node| node.name ==
|
98
|
+
test_case.nodes.select { |node| node.name == "failure" }.first
|
102
99
|
if failure
|
103
|
-
result[:result] =
|
100
|
+
result[:result] = "fail"
|
104
101
|
|
105
102
|
# Needs to be double quotation marks to work properly
|
106
103
|
result[:backtrace] = failure.text.split("\n")
|
@@ -108,7 +105,7 @@ module BlinkaReporter
|
|
108
105
|
result[:message] = failure.attributes[:message]
|
109
106
|
end
|
110
107
|
else
|
111
|
-
result[:result] =
|
108
|
+
result[:result] = "pass"
|
112
109
|
end
|
113
110
|
result
|
114
111
|
end
|
@@ -5,7 +5,7 @@ module BlinkaReporter
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def path
|
8
|
-
@path ||= source_location.first.gsub(Dir.getwd,
|
8
|
+
@path ||= source_location.first.gsub(Dir.getwd, "").delete_prefix("/")
|
9
9
|
end
|
10
10
|
|
11
11
|
def line
|
@@ -24,8 +24,8 @@ module BlinkaReporter
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def kind
|
27
|
-
parts = self.path.gsub(
|
28
|
-
parts.length > 1 ? parts.first :
|
27
|
+
parts = self.path.gsub("test/", "").split("/")
|
28
|
+
parts.length > 1 ? parts.first : "general"
|
29
29
|
end
|
30
30
|
|
31
31
|
def message
|
@@ -60,14 +60,17 @@ module BlinkaReporter
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def image
|
63
|
-
return unless kind ==
|
63
|
+
return unless kind == "system"
|
64
64
|
|
65
65
|
image_path =
|
66
66
|
if defined?(Capybara) && Capybara.respond_to?(:save_path) &&
|
67
67
|
Capybara.save_path.present?
|
68
|
-
"#{Capybara.save_path}/failures_#{name}.png"
|
68
|
+
"#{Capybara.save_path}/failures_#{name}.png".gsub(
|
69
|
+
Dir.getwd,
|
70
|
+
""
|
71
|
+
).delete_prefix("/")
|
69
72
|
else
|
70
|
-
"
|
73
|
+
"tmp/screenshots/failures_#{name}.png"
|
71
74
|
end
|
72
75
|
|
73
76
|
return unless File.exist?(image_path)
|
data/lib/blinka_reporter/tap.rb
CHANGED
@@ -23,22 +23,22 @@ module BlinkaReporter
|
|
23
23
|
def test_results(results)
|
24
24
|
report = []
|
25
25
|
results.each_with_index do |test, index|
|
26
|
-
test_str = "#{test[:path]} - #{test[:name].tr(
|
26
|
+
test_str = "#{test[:path]} - #{test[:name].tr("#", "_")}"
|
27
27
|
result = test[:result]
|
28
|
-
if result ==
|
28
|
+
if result == "pass"
|
29
29
|
report << "ok #{index + 1} - #{test_str}"
|
30
|
-
elsif result ==
|
30
|
+
elsif result == "skip"
|
31
31
|
report << "ok #{index + 1} # skip: #{test_str}"
|
32
|
-
elsif result ==
|
32
|
+
elsif result == "fail"
|
33
33
|
report << "not ok #{index + 1} - failed: #{test_str}"
|
34
34
|
test[:message].split('\n') do |line|
|
35
|
-
report << "##{
|
35
|
+
report << "##{" " * TAP_COMMENT_PAD + line}"
|
36
36
|
end
|
37
|
-
report <<
|
37
|
+
report << "#"
|
38
38
|
Array(test[:backtrace]).each do |line|
|
39
|
-
report << "##{
|
39
|
+
report << "##{" " * TAP_COMMENT_PAD + line}"
|
40
40
|
end
|
41
|
-
report <<
|
41
|
+
report << ""
|
42
42
|
end
|
43
43
|
end
|
44
44
|
report.join("\n")
|
data/lib/blinka_reporter.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "minitest"
|
2
|
+
require "json"
|
3
|
+
require "blinka_reporter/minitest_adapter"
|
4
|
+
require "blinka_reporter/client"
|
5
5
|
|
6
6
|
module Minitest
|
7
7
|
def self.plugin_blinka_init(options)
|
8
8
|
reporter.reporters << BlinkaPlugin::Reporter.new(options[:io], options)
|
9
9
|
end
|
10
10
|
|
11
|
-
def plugin_blinka_options(opts, options)
|
11
|
+
def plugin_blinka_options(opts, options)
|
12
|
+
end
|
12
13
|
|
13
14
|
module BlinkaPlugin
|
14
15
|
class Reporter < Minitest::StatisticsReporter
|
@@ -31,8 +32,8 @@ module Minitest
|
|
31
32
|
private
|
32
33
|
|
33
34
|
def json_report
|
34
|
-
report_path = ENV[
|
35
|
-
return if report_path.nil? || report_path.eql?(
|
35
|
+
report_path = ENV["BLINKA_PATH"]
|
36
|
+
return if report_path.nil? || report_path.eql?("")
|
36
37
|
|
37
38
|
result = {
|
38
39
|
total_time: total_time,
|
@@ -42,10 +43,20 @@ module Minitest
|
|
42
43
|
results:
|
43
44
|
tests&.map do |test_result|
|
44
45
|
BlinkaReporter::MinitestAdapter.new(test_result).report
|
45
|
-
end
|
46
|
+
end || []
|
46
47
|
}
|
47
48
|
|
48
|
-
File.
|
49
|
+
if ENV["BLINKA_APPEND"] == "true" && File.exist?(report_path)
|
50
|
+
existing =
|
51
|
+
JSON.parse(File.open(report_path).read, symbolize_names: true)
|
52
|
+
result[:results] = existing[:results] + result[:results]
|
53
|
+
result[:nbr_tests] = existing[:nbr_tests] + result[:nbr_tests]
|
54
|
+
result[:nbr_assertions] = existing[:nbr_assertions] +
|
55
|
+
result[:nbr_assertions]
|
56
|
+
result[:total_time] = existing[:total_time] + result[:total_time]
|
57
|
+
end
|
58
|
+
|
59
|
+
File.open(report_path, "w+") do |file|
|
49
60
|
file.write(JSON.pretty_generate(result))
|
50
61
|
end
|
51
62
|
|
data/package.json
CHANGED
@@ -4,19 +4,21 @@
|
|
4
4
|
"author": "David Wessman <david@wessman.co>",
|
5
5
|
"license": "MIT",
|
6
6
|
"devDependencies": {
|
7
|
-
"@prettier/plugin-ruby": "^3.2.2",
|
8
7
|
"husky": "^8.0.3",
|
9
|
-
"lint-staged": "^13.1.2"
|
10
|
-
|
11
|
-
"scripts": {
|
12
|
-
"pretty": "./node_modules/.bin/prettier --write ."
|
8
|
+
"lint-staged": "^13.1.2",
|
9
|
+
"prettier": "^2.8.4"
|
13
10
|
},
|
14
11
|
"husky": {
|
15
12
|
"hooks": {
|
16
13
|
"pre-commit": "lint-staged"
|
17
14
|
}
|
18
15
|
},
|
16
|
+
"scripts": {
|
17
|
+
"pretty": "./node_modules/.bin/prettier --write . && stree write './**/*.rb'",
|
18
|
+
"prepare": "husky install"
|
19
|
+
},
|
19
20
|
"lint-staged": {
|
20
|
-
"*.{
|
21
|
+
"*.{rb,gemspec}": "stree write",
|
22
|
+
"*.{js,css,md,json,yml}": "./node_modules/.bin/prettier --write"
|
21
23
|
}
|
22
24
|
}
|
data/yarn.lock
CHANGED
@@ -2,13 +2,6 @@
|
|
2
2
|
# yarn lockfile v1
|
3
3
|
|
4
4
|
|
5
|
-
"@prettier/plugin-ruby@^3.2.2":
|
6
|
-
version "3.2.2"
|
7
|
-
resolved "https://registry.yarnpkg.com/@prettier/plugin-ruby/-/plugin-ruby-3.2.2.tgz#43c9d85349032f74d34c4f57e6a77487d5c5bdc1"
|
8
|
-
integrity sha512-Vc7jVE39Fgswl517ET4kPtpnoRWE6XTi1Sivd84rZyomYnHYUmvUsEeoOf6tVhzTuIXE5XVQB1YCG2hulrwR3Q==
|
9
|
-
dependencies:
|
10
|
-
prettier ">=2.3.0"
|
11
|
-
|
12
5
|
aggregate-error@^3.0.0:
|
13
6
|
version "3.1.0"
|
14
7
|
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
|
@@ -335,10 +328,10 @@ pidtree@^0.6.0:
|
|
335
328
|
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c"
|
336
329
|
integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==
|
337
330
|
|
338
|
-
prettier
|
339
|
-
version "2.4
|
340
|
-
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.
|
341
|
-
integrity sha512-
|
331
|
+
prettier@^2.8.4:
|
332
|
+
version "2.8.4"
|
333
|
+
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3"
|
334
|
+
integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==
|
342
335
|
|
343
336
|
restore-cursor@^3.1.0:
|
344
337
|
version "3.1.0"
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blinka-reporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Wessman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: httparty
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.18'
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0.18'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: ox
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,19 +81,19 @@ dependencies:
|
|
95
81
|
- !ruby/object:Gem::Version
|
96
82
|
version: '13'
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
84
|
+
name: syntax_tree
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - "~>"
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version: '
|
89
|
+
version: '6.0'
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - "~>"
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
96
|
+
version: '6.0'
|
111
97
|
description: Use to format test results from Minitest to use with Blinka.
|
112
98
|
email: david@wessman.co
|
113
99
|
executables:
|
@@ -119,6 +105,7 @@ files:
|
|
119
105
|
- ".github/release.yml"
|
120
106
|
- ".github/workflows/main.yml"
|
121
107
|
- ".gitignore"
|
108
|
+
- ".husky/pre-commit"
|
122
109
|
- ".ruby-version"
|
123
110
|
- CHANGELOG.md
|
124
111
|
- Gemfile
|
@@ -129,10 +116,8 @@ files:
|
|
129
116
|
- bin/setup
|
130
117
|
- blinka_reporter.gemspec
|
131
118
|
- lib/blinka_reporter.rb
|
132
|
-
- lib/blinka_reporter/blinka.rb
|
133
119
|
- lib/blinka_reporter/cli.rb
|
134
120
|
- lib/blinka_reporter/client.rb
|
135
|
-
- lib/blinka_reporter/config.rb
|
136
121
|
- lib/blinka_reporter/error.rb
|
137
122
|
- lib/blinka_reporter/minitest_adapter.rb
|
138
123
|
- lib/blinka_reporter/tap.rb
|
@@ -1,172 +0,0 @@
|
|
1
|
-
require 'httparty'
|
2
|
-
require 'blinka_reporter/error'
|
3
|
-
|
4
|
-
module BlinkaReporter
|
5
|
-
class Blinka
|
6
|
-
SUPPORTED_MIME_TYPES = {
|
7
|
-
jpg: 'image/jpeg',
|
8
|
-
jpeg: 'image/jpeg',
|
9
|
-
png: 'image/png'
|
10
|
-
}
|
11
|
-
|
12
|
-
include HTTParty
|
13
|
-
|
14
|
-
def self.report(data:, config:)
|
15
|
-
Blinka.new(data: data, config: config).report
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(data:, config:)
|
19
|
-
@data = data
|
20
|
-
@config = config
|
21
|
-
self.class.base_uri("#{@config.host}/api/v1")
|
22
|
-
end
|
23
|
-
|
24
|
-
def report
|
25
|
-
if ENV.fetch('BLINKA_ALLOW_WEBMOCK_DISABLE', 'true') == 'true' &&
|
26
|
-
defined?(WebMock) && WebMock.respond_to?(:disable!)
|
27
|
-
WebMock.disable!
|
28
|
-
end
|
29
|
-
|
30
|
-
@config.validate_blinka
|
31
|
-
self.authenticate
|
32
|
-
|
33
|
-
results =
|
34
|
-
@data
|
35
|
-
.fetch(:results, [])
|
36
|
-
.map do |result|
|
37
|
-
if !result[:image].nil?
|
38
|
-
result[:image] = Blinka.upload_image(filepath: result[:image])
|
39
|
-
result
|
40
|
-
else
|
41
|
-
result
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
body = {
|
46
|
-
report: {
|
47
|
-
repository: @config.repository,
|
48
|
-
tag: @config.tag,
|
49
|
-
commit: @config.commit,
|
50
|
-
metadata: {
|
51
|
-
total_time: @data[:total_time],
|
52
|
-
nbr_tests: @data[:nbr_tests],
|
53
|
-
nbr_assertions: @data[:nbr_assertions],
|
54
|
-
seed: @data[:seed]
|
55
|
-
}.compact,
|
56
|
-
results: results
|
57
|
-
}
|
58
|
-
}
|
59
|
-
|
60
|
-
response =
|
61
|
-
self.class.post(
|
62
|
-
'/report',
|
63
|
-
body: body.to_json,
|
64
|
-
headers: {
|
65
|
-
'Content-Type' => 'application/json',
|
66
|
-
'Authorization' => "Bearer #{@jwt_token}"
|
67
|
-
}
|
68
|
-
)
|
69
|
-
case response.code
|
70
|
-
when 200
|
71
|
-
puts "Reported #{@data[:nbr_tests]} tests of commit #{@config.commit}!"
|
72
|
-
else
|
73
|
-
raise(
|
74
|
-
BlinkaReporter::Error,
|
75
|
-
"Could not report, got response code #{response.code}"
|
76
|
-
)
|
77
|
-
end
|
78
|
-
rescue => error
|
79
|
-
raise(BlinkaReporter::Error, <<-EOS)
|
80
|
-
BLINKA:
|
81
|
-
Failed to create report because of #{error.class} with message:
|
82
|
-
#{error.message}
|
83
|
-
EOS
|
84
|
-
ensure
|
85
|
-
WebMock.enable! if defined?(WebMock) && WebMock.respond_to?(:enable!)
|
86
|
-
end
|
87
|
-
|
88
|
-
def authenticate
|
89
|
-
response =
|
90
|
-
self.class.post(
|
91
|
-
'/authentication',
|
92
|
-
body: {
|
93
|
-
token_id: @config.team_id,
|
94
|
-
token_secret: @config.team_secret
|
95
|
-
}.to_json,
|
96
|
-
headers: { 'Content-Type' => 'application/json' }
|
97
|
-
)
|
98
|
-
case response.code
|
99
|
-
when 200
|
100
|
-
@jwt_token = JSON.parse(response.body).dig('auth_token')
|
101
|
-
else
|
102
|
-
raise(
|
103
|
-
BlinkaReporter::Error,
|
104
|
-
"Could not authenticate to API #{response.code}"
|
105
|
-
)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def self.upload_image(filepath:)
|
110
|
-
return unless File.exist?(filepath)
|
111
|
-
|
112
|
-
file = File.open(filepath)
|
113
|
-
filename = File.basename(filepath)
|
114
|
-
extension = File.extname(filepath).delete('.').to_sym
|
115
|
-
content_type = SUPPORTED_MIME_TYPES[extension]
|
116
|
-
return if content_type.nil?
|
117
|
-
|
118
|
-
presigned_post =
|
119
|
-
Blinka.presign_image(filename: filename, content_type: content_type)
|
120
|
-
Blinka.upload_to_storage(presigned_post: presigned_post, file: file)
|
121
|
-
|
122
|
-
puts "Uploaded: #{filename}"
|
123
|
-
Blinka.to_shrine_object(
|
124
|
-
presigned_post: presigned_post,
|
125
|
-
file: file,
|
126
|
-
filename: filename
|
127
|
-
)
|
128
|
-
end
|
129
|
-
|
130
|
-
def self.presign_image(filename:, content_type:)
|
131
|
-
response =
|
132
|
-
self.get(
|
133
|
-
'/presign',
|
134
|
-
body: { filename: filename, content_type: content_type }
|
135
|
-
)
|
136
|
-
|
137
|
-
case response.code
|
138
|
-
when 200
|
139
|
-
JSON.parse(response.body)
|
140
|
-
else
|
141
|
-
raise(BlinkaReporter::Error, 'Could not presign file')
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def self.upload_to_storage(presigned_post:, file:)
|
146
|
-
url = URI.parse(presigned_post.fetch('url'))
|
147
|
-
|
148
|
-
body = presigned_post['fields'].merge({ 'file' => file.read })
|
149
|
-
response = HTTParty.post(url, multipart: true, body: body)
|
150
|
-
|
151
|
-
case response.code
|
152
|
-
when 204
|
153
|
-
true
|
154
|
-
else
|
155
|
-
raise(BlinkaReporter::Error, 'Could not upload file to storage')
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
def self.to_shrine_object(presigned_post:, file:, filename:)
|
160
|
-
storage, idx = presigned_post.dig('fields', 'key').split('/')
|
161
|
-
{
|
162
|
-
"id": idx,
|
163
|
-
"storage": storage,
|
164
|
-
"metadata": {
|
165
|
-
"size": file.size,
|
166
|
-
"filename": filename,
|
167
|
-
"mime_type": presigned_post.dig('fields', 'Content-Type')
|
168
|
-
}
|
169
|
-
}
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'blinka_reporter/error'
|
2
|
-
|
3
|
-
module BlinkaReporter
|
4
|
-
class Config
|
5
|
-
attr_reader(:commit, :host, :repository, :tag, :team_id, :team_secret)
|
6
|
-
DEFAULT_HOST = 'https://www.blinka.app'
|
7
|
-
|
8
|
-
def initialize(
|
9
|
-
tag:,
|
10
|
-
commit:,
|
11
|
-
repository:,
|
12
|
-
host: nil,
|
13
|
-
team_id:,
|
14
|
-
team_secret:
|
15
|
-
)
|
16
|
-
@commit = commit || find_commit
|
17
|
-
@host = host || DEFAULT_HOST
|
18
|
-
@repository = repository
|
19
|
-
@tag = tag
|
20
|
-
@team_id = team_id
|
21
|
-
@team_secret = team_secret
|
22
|
-
end
|
23
|
-
|
24
|
-
def validate_blinka
|
25
|
-
required = [@team_id, @team_secret, @repository]
|
26
|
-
if required.include?(nil) || required.include?('')
|
27
|
-
raise(BlinkaReporter::Error, <<~EOS)
|
28
|
-
Missing configuration, make sure to set --team-id, --team-secret, --repository
|
29
|
-
EOS
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def find_commit
|
34
|
-
ENV.fetch('HEROKU_TEST_RUN_COMMIT_VERSION', `git rev-parse HEAD`.chomp)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|