rspec-tracer 1.2.3 → 2.0.0.pre.2
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/CHANGELOG.md +384 -67
- data/README.md +454 -429
- data/bin/rspec-tracer +15 -0
- data/lib/rspec_tracer/cache/Rakefile +43 -0
- data/lib/rspec_tracer/cli/cache_clear.rb +111 -0
- data/lib/rspec_tracer/cli/cache_info.rb +104 -0
- data/lib/rspec_tracer/cli/doctor.rb +284 -0
- data/lib/rspec_tracer/cli/explain.rb +158 -0
- data/lib/rspec_tracer/cli/report_open.rb +82 -0
- data/lib/rspec_tracer/cli.rb +116 -0
- data/lib/rspec_tracer/configuration.rb +1196 -3
- data/lib/rspec_tracer/engine.rb +1168 -0
- data/lib/rspec_tracer/example.rb +141 -11
- data/lib/rspec_tracer/filter.rb +35 -0
- data/lib/rspec_tracer/line_stub.rb +61 -0
- data/lib/rspec_tracer/load_config.rb +2 -2
- data/lib/rspec_tracer/logger.rb +15 -0
- data/lib/rspec_tracer/rails/README.md +78 -0
- data/lib/rspec_tracer/rails/i18n_tracking.rb +137 -0
- data/lib/rspec_tracer/rails/notifications.rb +263 -0
- data/lib/rspec_tracer/rails/preset.rb +94 -0
- data/lib/rspec_tracer/rails/railtie.rb +22 -0
- data/lib/rspec_tracer/rails.rb +15 -0
- data/lib/rspec_tracer/remote_cache/README.md +140 -0
- data/lib/rspec_tracer/remote_cache/Rakefile +35 -11
- data/lib/rspec_tracer/remote_cache/archive.rb +137 -0
- data/lib/rspec_tracer/remote_cache/backend.rb +73 -0
- data/lib/rspec_tracer/remote_cache/git_ancestry.rb +241 -0
- data/lib/rspec_tracer/remote_cache/local_fs_backend.rb +439 -0
- data/lib/rspec_tracer/remote_cache/redis_backend.rb +554 -0
- data/lib/rspec_tracer/remote_cache/s3_backend.rb +712 -0
- data/lib/rspec_tracer/remote_cache/user_tasks.rb +436 -0
- data/lib/rspec_tracer/remote_cache/validator.rb +40 -62
- data/lib/rspec_tracer/remote_cache.rb +22 -0
- data/lib/rspec_tracer/reporters/README.md +103 -0
- data/lib/rspec_tracer/reporters/base.rb +87 -0
- data/lib/rspec_tracer/reporters/coverage_json_reporter.rb +338 -0
- data/lib/rspec_tracer/reporters/html/.gitignore +19 -0
- data/lib/rspec_tracer/reporters/html/.prettierignore +4 -0
- data/lib/rspec_tracer/reporters/html/.prettierrc.json +9 -0
- data/lib/rspec_tracer/reporters/html/README.md +80 -0
- data/lib/rspec_tracer/reporters/html/dist/assets/index.css +2 -0
- data/lib/rspec_tracer/reporters/html/dist/assets/index.js +1 -0
- data/lib/rspec_tracer/reporters/html/dist/index.html +24 -0
- data/lib/rspec_tracer/reporters/html/eslint.config.js +62 -0
- data/lib/rspec_tracer/reporters/html/package-lock.json +4941 -0
- data/lib/rspec_tracer/reporters/html/package.json +29 -0
- data/lib/rspec_tracer/reporters/html/src/app.jsx +130 -0
- data/lib/rspec_tracer/reporters/html/src/components/AllExamples.jsx +86 -0
- data/lib/rspec_tracer/reporters/html/src/components/DuplicateExamples.jsx +68 -0
- data/lib/rspec_tracer/reporters/html/src/components/ExamplesDependency.jsx +78 -0
- data/lib/rspec_tracer/reporters/html/src/components/FilesDependency.jsx +72 -0
- data/lib/rspec_tracer/reporters/html/src/components/FlakyExamples.jsx +42 -0
- data/lib/rspec_tracer/reporters/html/src/components/ReportTable.jsx +131 -0
- data/lib/rspec_tracer/reporters/html/src/components/SearchBar.jsx +19 -0
- data/lib/rspec_tracer/reporters/html/src/index.html +23 -0
- data/lib/rspec_tracer/reporters/html/src/main.jsx +37 -0
- data/lib/rspec_tracer/reporters/html/src/styles.css +434 -0
- data/lib/rspec_tracer/reporters/html/vite.config.js +42 -0
- data/lib/rspec_tracer/reporters/html_reporter.rb +266 -0
- data/lib/rspec_tracer/reporters/json_reporter.rb +88 -0
- data/lib/rspec_tracer/reporters/payload_builder.rb +235 -0
- data/lib/rspec_tracer/reporters/registry.rb +120 -0
- data/lib/rspec_tracer/reporters/terminal_reporter.rb +264 -0
- data/lib/rspec_tracer/rspec/README.md +73 -0
- data/lib/rspec_tracer/rspec/installation.rb +97 -0
- data/lib/rspec_tracer/rspec/metadata.rb +96 -0
- data/lib/rspec_tracer/rspec/parallel_tests.rb +459 -0
- data/lib/rspec_tracer/rspec/reporter_hook.rb +84 -0
- data/lib/rspec_tracer/rspec/runner_hook.rb +239 -0
- data/lib/rspec_tracer/source_file.rb +24 -7
- data/lib/rspec_tracer/storage/README.md +35 -0
- data/lib/rspec_tracer/storage/backend.rb +130 -0
- data/lib/rspec_tracer/storage/json_backend.rb +884 -0
- data/lib/rspec_tracer/storage/lazy_snapshot.rb +65 -0
- data/lib/rspec_tracer/storage/schema.rb +50 -0
- data/lib/rspec_tracer/storage/serializer/json.rb +41 -0
- data/lib/rspec_tracer/storage/serializer/msgpack.rb +167 -0
- data/lib/rspec_tracer/storage/snapshot.rb +141 -0
- data/lib/rspec_tracer/storage/sqlite_backend.rb +693 -0
- data/lib/rspec_tracer/time_formatter.rb +37 -18
- data/lib/rspec_tracer/tracker/README.md +36 -0
- data/lib/rspec_tracer/tracker/coverage_adapter.rb +174 -0
- data/lib/rspec_tracer/tracker/declared_globs.rb +100 -0
- data/lib/rspec_tracer/tracker/dependency_graph.rb +134 -0
- data/lib/rspec_tracer/tracker/env_matcher.rb +127 -0
- data/lib/rspec_tracer/tracker/env_snapshot.rb +77 -0
- data/lib/rspec_tracer/tracker/example_registry.rb +153 -0
- data/lib/rspec_tracer/tracker/file_digest.rb +61 -0
- data/lib/rspec_tracer/tracker/filter.rb +127 -0
- data/lib/rspec_tracer/tracker/input.rb +99 -0
- data/lib/rspec_tracer/tracker/io_hooks/file.rb +55 -0
- data/lib/rspec_tracer/tracker/io_hooks/io.rb +24 -0
- data/lib/rspec_tracer/tracker/io_hooks/json.rb +23 -0
- data/lib/rspec_tracer/tracker/io_hooks/kernel.rb +26 -0
- data/lib/rspec_tracer/tracker/io_hooks/yaml.rb +38 -0
- data/lib/rspec_tracer/tracker/io_hooks.rb +195 -0
- data/lib/rspec_tracer/tracker/loaded_files_tracker.rb +295 -0
- data/lib/rspec_tracer/tracker/new_file_detector.rb +62 -0
- data/lib/rspec_tracer/tracker/whole_suite_invalidators.rb +96 -0
- data/lib/rspec_tracer/version.rb +4 -1
- data/lib/rspec_tracer.rb +231 -491
- metadata +94 -43
- data/lib/rspec_tracer/cache.rb +0 -207
- data/lib/rspec_tracer/coverage_merger.rb +0 -42
- data/lib/rspec_tracer/coverage_reporter.rb +0 -187
- data/lib/rspec_tracer/coverage_writer.rb +0 -58
- data/lib/rspec_tracer/html_reporter/Rakefile +0 -18
- data/lib/rspec_tracer/html_reporter/assets/javascripts/application.js +0 -56
- data/lib/rspec_tracer/html_reporter/assets/javascripts/libraries/jquery.js +0 -10881
- data/lib/rspec_tracer/html_reporter/assets/javascripts/plugins/datatables.js +0 -15381
- data/lib/rspec_tracer/html_reporter/assets/stylesheets/application.css +0 -196
- data/lib/rspec_tracer/html_reporter/assets/stylesheets/plugins/datatables.css +0 -459
- data/lib/rspec_tracer/html_reporter/assets/stylesheets/plugins/jquery-ui.css +0 -436
- data/lib/rspec_tracer/html_reporter/assets/stylesheets/print.css +0 -92
- data/lib/rspec_tracer/html_reporter/assets/stylesheets/reset.css +0 -265
- data/lib/rspec_tracer/html_reporter/public/application.css +0 -5
- data/lib/rspec_tracer/html_reporter/public/application.js +0 -6
- data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_asc.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_asc_disabled.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_both.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_desc.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/datatables/images/sort_desc_disabled.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/favicon.png +0 -0
- data/lib/rspec_tracer/html_reporter/public/loading.gif +0 -0
- data/lib/rspec_tracer/html_reporter/reporter.rb +0 -242
- data/lib/rspec_tracer/html_reporter/views/duplicate_examples.erb +0 -34
- data/lib/rspec_tracer/html_reporter/views/examples.erb +0 -58
- data/lib/rspec_tracer/html_reporter/views/examples_dependency.erb +0 -36
- data/lib/rspec_tracer/html_reporter/views/files_dependency.erb +0 -36
- data/lib/rspec_tracer/html_reporter/views/flaky_examples.erb +0 -38
- data/lib/rspec_tracer/html_reporter/views/layout.erb +0 -38
- data/lib/rspec_tracer/remote_cache/aws.rb +0 -176
- data/lib/rspec_tracer/remote_cache/cache.rb +0 -75
- data/lib/rspec_tracer/remote_cache/repo.rb +0 -210
- data/lib/rspec_tracer/report_generator.rb +0 -158
- data/lib/rspec_tracer/report_merger.rb +0 -68
- data/lib/rspec_tracer/report_writer.rb +0 -141
- data/lib/rspec_tracer/reporter.rb +0 -204
- data/lib/rspec_tracer/rspec_reporter.rb +0 -41
- data/lib/rspec_tracer/rspec_runner.rb +0 -56
- data/lib/rspec_tracer/ruby_coverage.rb +0 -9
- data/lib/rspec_tracer/runner.rb +0 -278
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'erb'
|
|
4
|
-
require 'time'
|
|
5
|
-
|
|
6
|
-
module RSpecTracer
|
|
7
|
-
module HTMLReporter
|
|
8
|
-
class Reporter
|
|
9
|
-
attr_reader :last_run, :examples, :flaky_examples, :examples_dependency, :files_dependency
|
|
10
|
-
|
|
11
|
-
def initialize(report_dir, reporter)
|
|
12
|
-
@report_dir = report_dir
|
|
13
|
-
@reporter = reporter
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def generate_report
|
|
17
|
-
starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
18
|
-
|
|
19
|
-
prepare
|
|
20
|
-
|
|
21
|
-
file_name = File.join(@report_dir, 'index.html')
|
|
22
|
-
|
|
23
|
-
File.open(file_name, 'wb') do |file|
|
|
24
|
-
file.puts(template('layout').result(binding))
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
28
|
-
elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
|
|
29
|
-
|
|
30
|
-
RSpecTracer.logger.debug "RSpecTracer generated HTML report to #{file_name} (took #{elapsed})"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def prepare
|
|
36
|
-
format_last_run
|
|
37
|
-
format_examples
|
|
38
|
-
format_duplicate_examples
|
|
39
|
-
format_flaky_examples
|
|
40
|
-
format_examples_dependency
|
|
41
|
-
format_files_dependency
|
|
42
|
-
copy_assets
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def copy_assets
|
|
46
|
-
Dir[File.join(File.dirname(__FILE__), 'public/*')].each do |path|
|
|
47
|
-
FileUtils.cp_r(path, asset_output_path)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def format_last_run
|
|
52
|
-
@last_run = @reporter.last_run.slice(
|
|
53
|
-
:actual_count,
|
|
54
|
-
:duplicate_examples,
|
|
55
|
-
:failed_examples,
|
|
56
|
-
:pending_examples,
|
|
57
|
-
:skipped_examples
|
|
58
|
-
)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def format_examples
|
|
62
|
-
@examples = {}
|
|
63
|
-
|
|
64
|
-
@reporter.all_examples.each_pair do |example_id, example|
|
|
65
|
-
@examples[example_id] = {
|
|
66
|
-
id: example_id,
|
|
67
|
-
description: example[:full_description],
|
|
68
|
-
location: example_location(example[:rerun_file_name], example[:rerun_line_number]),
|
|
69
|
-
status: example[:run_reason] || 'Skipped'
|
|
70
|
-
}.merge(example_result(example_id, example))
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def example_result(example_id, example)
|
|
75
|
-
if example[:execution_result].nil?
|
|
76
|
-
{
|
|
77
|
-
result: @reporter.example_interrupted?(example_id) ? 'Interrupted' : '_',
|
|
78
|
-
last_run: '_'
|
|
79
|
-
}
|
|
80
|
-
else
|
|
81
|
-
{
|
|
82
|
-
result: example[:execution_result][:status].capitalize,
|
|
83
|
-
last_run: example_run_local_time(example[:execution_result][:finished_at])
|
|
84
|
-
}
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def format_duplicate_examples
|
|
89
|
-
@duplicate_examples = []
|
|
90
|
-
|
|
91
|
-
@reporter.duplicate_examples.each_pair do |example_id, examples|
|
|
92
|
-
examples.each do |example|
|
|
93
|
-
@duplicate_examples << {
|
|
94
|
-
id: example_id,
|
|
95
|
-
description: example[:full_description],
|
|
96
|
-
location: example_location(example[:rerun_file_name], example[:rerun_line_number])
|
|
97
|
-
}
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def format_flaky_examples
|
|
103
|
-
@flaky_examples = @examples.slice(*@reporter.flaky_examples).values
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def example_run_local_time(utc_time)
|
|
107
|
-
case utc_time
|
|
108
|
-
when Time
|
|
109
|
-
utc_time.localtime.strftime('%Y-%m-%d %H:%M:%S')
|
|
110
|
-
when String
|
|
111
|
-
Time.parse(utc_time).localtime.strftime('%Y-%m-%d %H:%M:%S')
|
|
112
|
-
else
|
|
113
|
-
utc_time.inspect
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def format_examples_dependency
|
|
118
|
-
@examples_dependency = []
|
|
119
|
-
|
|
120
|
-
@reporter.dependency.each_pair do |example_id, files|
|
|
121
|
-
@examples_dependency << {
|
|
122
|
-
example_id: example_id,
|
|
123
|
-
example: @examples[example_id][:description],
|
|
124
|
-
files_count: files.count,
|
|
125
|
-
files: files.map { |file_name| shortened_file_name(file_name) }.sort.join(', ')
|
|
126
|
-
}
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def format_files_dependency
|
|
131
|
-
@files_dependency = []
|
|
132
|
-
|
|
133
|
-
@reporter.reverse_dependency.each_pair do |main_file_name, data|
|
|
134
|
-
short_file_name = shortened_file_name(main_file_name)
|
|
135
|
-
|
|
136
|
-
@files_dependency << {
|
|
137
|
-
name: short_file_name,
|
|
138
|
-
example_count: data[:example_count],
|
|
139
|
-
file_count: data[:examples].count,
|
|
140
|
-
files: data[:examples]
|
|
141
|
-
.map { |file_name, count| "#{shortened_file_name(file_name)}: #{count}" }
|
|
142
|
-
.join(', ')
|
|
143
|
-
}
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def example_location(file_name, line_number)
|
|
148
|
-
"#{shortened_file_name(file_name)}:#{line_number}"
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def shortened_file_name(file_name)
|
|
152
|
-
file_name.sub(%r{^/}, '')
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def asset_output_path
|
|
156
|
-
@asset_output_path ||= begin
|
|
157
|
-
asset_output_path = File.join(@report_dir, 'assets', RSpecTracer::VERSION)
|
|
158
|
-
|
|
159
|
-
FileUtils.mkdir_p(asset_output_path)
|
|
160
|
-
|
|
161
|
-
asset_output_path
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def assets_path(name)
|
|
166
|
-
File.join('./assets', RSpecTracer::VERSION, name)
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
def formatted_examples(title, examples)
|
|
170
|
-
title_id = report_container_id(title)
|
|
171
|
-
current_binding = binding
|
|
172
|
-
|
|
173
|
-
current_binding.local_variable_set(:title_id, title_id)
|
|
174
|
-
template(title_id).result(current_binding)
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def formatted_duplicate_examples(title, duplicate_examples)
|
|
178
|
-
title_id = report_container_id(title)
|
|
179
|
-
current_binding = binding
|
|
180
|
-
|
|
181
|
-
current_binding.local_variable_set(:title_id, title_id)
|
|
182
|
-
template(title_id).result(current_binding)
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
def formatted_flaky_examples(title, flaky_examples)
|
|
186
|
-
title_id = report_container_id(title)
|
|
187
|
-
current_binding = binding
|
|
188
|
-
|
|
189
|
-
current_binding.local_variable_set(:title_id, title_id)
|
|
190
|
-
template(title_id).result(current_binding)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def formatted_examples_dependency(title, examples_dependency)
|
|
194
|
-
title_id = report_container_id(title)
|
|
195
|
-
current_binding = binding
|
|
196
|
-
|
|
197
|
-
current_binding.local_variable_set(:title_id, title_id)
|
|
198
|
-
template(title_id).result(current_binding)
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def formatted_files_dependency(title, files_dependency)
|
|
202
|
-
title_id = report_container_id(title)
|
|
203
|
-
current_binding = binding
|
|
204
|
-
|
|
205
|
-
current_binding.local_variable_set(:title_id, title_id)
|
|
206
|
-
template(title_id).result(current_binding)
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
def report_container_id(title)
|
|
210
|
-
title.gsub(/\s+/, ' ').downcase.tr(' ', '_')
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
def template(name)
|
|
214
|
-
ERB.new(File.read(File.join(File.dirname(__FILE__), 'views/', "#{name}.erb"), encoding: 'UTF-8'))
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def example_status_css_class(example_status)
|
|
218
|
-
case example_status.split.first
|
|
219
|
-
when 'Failed', 'Flaky', 'Interrupted'
|
|
220
|
-
'red'
|
|
221
|
-
when 'Pending'
|
|
222
|
-
'yellow'
|
|
223
|
-
else
|
|
224
|
-
'blue'
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def example_result_css_class(example_result)
|
|
229
|
-
case example_result
|
|
230
|
-
when 'Passed'
|
|
231
|
-
'green'
|
|
232
|
-
when 'Failed', 'Interrupted'
|
|
233
|
-
'red'
|
|
234
|
-
when 'Pending'
|
|
235
|
-
'yellow'
|
|
236
|
-
else
|
|
237
|
-
'blue'
|
|
238
|
-
end
|
|
239
|
-
end
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<div class="report_container" id="<%= title_id %>">
|
|
2
|
-
<h2>
|
|
3
|
-
<span class="group_name"><%= title %></span>
|
|
4
|
-
(
|
|
5
|
-
<span class="blue">
|
|
6
|
-
<strong><%= duplicate_examples.count %></strong>
|
|
7
|
-
</span> examples
|
|
8
|
-
)
|
|
9
|
-
</h2>
|
|
10
|
-
|
|
11
|
-
<a name="<%= title_id %>"></a>
|
|
12
|
-
|
|
13
|
-
<div class="report-table--responsive">
|
|
14
|
-
<table class="report-table">
|
|
15
|
-
<thead>
|
|
16
|
-
<tr>
|
|
17
|
-
<th>ID</th>
|
|
18
|
-
<th>Description</th>
|
|
19
|
-
<th>Location</th>
|
|
20
|
-
</tr>
|
|
21
|
-
</thead>
|
|
22
|
-
|
|
23
|
-
<tbody>
|
|
24
|
-
<% duplicate_examples.each do |example| %>
|
|
25
|
-
<tr>
|
|
26
|
-
<td><%= example[:id] %></td>
|
|
27
|
-
<td><%= example[:description] %></td>
|
|
28
|
-
<td><%= example[:location] %></td>
|
|
29
|
-
</tr>
|
|
30
|
-
<% end %>
|
|
31
|
-
</tbody>
|
|
32
|
-
</table>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<div class="report_container" id="<%= title_id %>">
|
|
2
|
-
<h2>
|
|
3
|
-
<span class="group_name"><%= title %></span>
|
|
4
|
-
(
|
|
5
|
-
<span class="blue">
|
|
6
|
-
<strong><%= last_run[:actual_count] %></strong>
|
|
7
|
-
</span> examples,
|
|
8
|
-
<% if last_run[:duplicate_examples].positive? %>
|
|
9
|
-
<span class="blue">
|
|
10
|
-
<strong><%= last_run[:duplicate_examples] %></strong>
|
|
11
|
-
</span> duplicates,
|
|
12
|
-
<% end %>
|
|
13
|
-
<% if last_run[:failed_examples].positive? %>
|
|
14
|
-
<span class="red">
|
|
15
|
-
<strong><%= last_run[:failed_examples] %></strong>
|
|
16
|
-
</span> failures,
|
|
17
|
-
<% end %>
|
|
18
|
-
<% if last_run[:pending_examples].positive? %>
|
|
19
|
-
<span class="yellow">
|
|
20
|
-
<strong><%= last_run[:pending_examples] %></strong>
|
|
21
|
-
</span> pending,
|
|
22
|
-
<% end %>
|
|
23
|
-
<span class="blue">
|
|
24
|
-
<strong><%= last_run[:skipped_examples] %></strong>
|
|
25
|
-
</span> skipped by rspec-tracer
|
|
26
|
-
)
|
|
27
|
-
</h2>
|
|
28
|
-
|
|
29
|
-
<a name="<%= title_id %>"></a>
|
|
30
|
-
|
|
31
|
-
<div class="report-table--responsive">
|
|
32
|
-
<table class="report-table">
|
|
33
|
-
<thead>
|
|
34
|
-
<tr>
|
|
35
|
-
<th>ID</th>
|
|
36
|
-
<th>Description</th>
|
|
37
|
-
<th>Location</th>
|
|
38
|
-
<th>Run Reason</th>
|
|
39
|
-
<th>Result</th>
|
|
40
|
-
<th>Run At</th>
|
|
41
|
-
</tr>
|
|
42
|
-
</thead>
|
|
43
|
-
|
|
44
|
-
<tbody>
|
|
45
|
-
<% examples.each do |example| %>
|
|
46
|
-
<tr>
|
|
47
|
-
<td><%= example[:id] %></td>
|
|
48
|
-
<td><%= example[:description] %></td>
|
|
49
|
-
<td><%= example[:location] %></td>
|
|
50
|
-
<td><strong class="<%= example_status_css_class(example[:status]) %>"><%= example[:status] %></strong></td>
|
|
51
|
-
<td><strong class="<%= example_result_css_class(example[:result]) %>"><%= example[:result] %></strong></td>
|
|
52
|
-
<td width="8%"><%= example[:last_run] %></td>
|
|
53
|
-
</tr>
|
|
54
|
-
<% end %>
|
|
55
|
-
</tbody>
|
|
56
|
-
</table>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<div class="report_container" id="<%= title_id %>">
|
|
2
|
-
<h2>
|
|
3
|
-
<span class="group_name"><%= title %></span>
|
|
4
|
-
(
|
|
5
|
-
<span class="blue">
|
|
6
|
-
<strong><%= examples_dependency.count %></strong>
|
|
7
|
-
</span> examples
|
|
8
|
-
)
|
|
9
|
-
</h2>
|
|
10
|
-
|
|
11
|
-
<a name="<%= title_id %>"></a>
|
|
12
|
-
|
|
13
|
-
<div class="report-table--responsive">
|
|
14
|
-
<table class="report-table">
|
|
15
|
-
<thead>
|
|
16
|
-
<tr>
|
|
17
|
-
<th>Example ID</th>
|
|
18
|
-
<th>Example</th>
|
|
19
|
-
<th>Files Count</th>
|
|
20
|
-
<th data-orderable="false">Files Name</th>
|
|
21
|
-
</tr>
|
|
22
|
-
</thead>
|
|
23
|
-
|
|
24
|
-
<tbody>
|
|
25
|
-
<% examples_dependency.each do |example_dependency| %>
|
|
26
|
-
<tr>
|
|
27
|
-
<td><%= example_dependency[:example_id] %></td>
|
|
28
|
-
<td><%= example_dependency[:example] %></td>
|
|
29
|
-
<td class="number" width="8%"><strong><%= example_dependency[:files_count] %></strong></td>
|
|
30
|
-
<td><%= example_dependency[:files] %></td>
|
|
31
|
-
</tr>
|
|
32
|
-
<% end %>
|
|
33
|
-
</tbody>
|
|
34
|
-
</table>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
<div class="report_container" id="<%= title_id %>">
|
|
2
|
-
<h2>
|
|
3
|
-
<span class="group_name"><%= title %></span>
|
|
4
|
-
(
|
|
5
|
-
<span class="blue">
|
|
6
|
-
<strong><%= files_dependency.count %></strong>
|
|
7
|
-
</span> files
|
|
8
|
-
)
|
|
9
|
-
</h2>
|
|
10
|
-
|
|
11
|
-
<a name="<%= title_id %>"></a>
|
|
12
|
-
|
|
13
|
-
<div class="report-table--responsive">
|
|
14
|
-
<table class="report-table">
|
|
15
|
-
<thead>
|
|
16
|
-
<tr>
|
|
17
|
-
<th searchable="true">File</th>
|
|
18
|
-
<th>Examples Count</th>
|
|
19
|
-
<th>Files Count</th>
|
|
20
|
-
<th data-orderable="false">Dependent Files</th>
|
|
21
|
-
</tr>
|
|
22
|
-
</thead>
|
|
23
|
-
|
|
24
|
-
<tbody>
|
|
25
|
-
<% files_dependency.each do |file_dependency| %>
|
|
26
|
-
<tr class="t-example">
|
|
27
|
-
<td><%= file_dependency[:name] %></td>
|
|
28
|
-
<td class="number" width="8%"><strong><%= file_dependency[:example_count] %></strong></td>
|
|
29
|
-
<td class="number" width="8%"><strong><%= file_dependency[:file_count] %></strong></td>
|
|
30
|
-
<td><%= file_dependency[:files] %></td>
|
|
31
|
-
</tr>
|
|
32
|
-
<% end %>
|
|
33
|
-
</tbody>
|
|
34
|
-
</table>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<div class="report_container" id="<%= title_id %>">
|
|
2
|
-
<h2>
|
|
3
|
-
<span class="group_name"><%= title %></span>
|
|
4
|
-
(
|
|
5
|
-
<span class="blue">
|
|
6
|
-
<strong><%= flaky_examples.count %></strong>
|
|
7
|
-
</span> examples
|
|
8
|
-
)
|
|
9
|
-
</h2>
|
|
10
|
-
|
|
11
|
-
<a name="<%= title_id %>"></a>
|
|
12
|
-
|
|
13
|
-
<div class="report-table--responsive">
|
|
14
|
-
<table class="report-table">
|
|
15
|
-
<thead>
|
|
16
|
-
<tr>
|
|
17
|
-
<th>ID</th>
|
|
18
|
-
<th>Description</th>
|
|
19
|
-
<th>Location</th>
|
|
20
|
-
<th>Result</th>
|
|
21
|
-
<th>Run At</th>
|
|
22
|
-
</tr>
|
|
23
|
-
</thead>
|
|
24
|
-
|
|
25
|
-
<tbody>
|
|
26
|
-
<% flaky_examples.each do |example| %>
|
|
27
|
-
<tr>
|
|
28
|
-
<td><%= example[:id] %></td>
|
|
29
|
-
<td><%= example[:description] %></td>
|
|
30
|
-
<td><%= example[:location] %></td>
|
|
31
|
-
<td><strong class="<%= example_result_css_class(example[:result]) %>"><%= example[:result] %></strong></td>
|
|
32
|
-
<td width="8%"><%= example[:last_run] %></td>
|
|
33
|
-
</tr>
|
|
34
|
-
<% end %>
|
|
35
|
-
</tbody>
|
|
36
|
-
</table>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
|
|
3
|
-
<html xmlns='http://www.w3.org/1999/xhtml'>
|
|
4
|
-
<head>
|
|
5
|
-
<title>RSpec Tracer Report for <%= RSpecTracer.project_name %></title>
|
|
6
|
-
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
|
7
|
-
<script src='<%= assets_path('application.js') %>' type='text/javascript'></script>
|
|
8
|
-
<link href='<%= assets_path('application.css') %>' media='screen, projection, print' rel='stylesheet' type='text/css' />
|
|
9
|
-
<link rel="icon" type="image/png" href="<%= assets_path('favicon.png') %>" />
|
|
10
|
-
</head>
|
|
11
|
-
|
|
12
|
-
<body>
|
|
13
|
-
<div id="loading">
|
|
14
|
-
<img src="<%= assets_path('loading.gif') %>" width="60" height="60" alt="loading" />
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
<div id="wrapper" class="hide">
|
|
18
|
-
<ul class="group_tabs"></ul>
|
|
19
|
-
|
|
20
|
-
<div id="content">
|
|
21
|
-
<%= formatted_examples('Examples', @examples.values) %>
|
|
22
|
-
<% unless @duplicate_examples.empty? %>
|
|
23
|
-
<%= formatted_duplicate_examples('Duplicate Examples', @duplicate_examples) %>
|
|
24
|
-
<% end %>
|
|
25
|
-
<% unless @flaky_examples.empty? %>
|
|
26
|
-
<%= formatted_flaky_examples('Flaky Examples', @flaky_examples) %>
|
|
27
|
-
<% end %>
|
|
28
|
-
<%= formatted_examples_dependency('Examples Dependency', @examples_dependency) %>
|
|
29
|
-
<%= formatted_files_dependency("Files Dependency", @files_dependency) %>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
<div id="footer">
|
|
33
|
-
Generated by <a href="https://github.com/avmnu-sng/rspec-tracer">rspec-tracer</a>
|
|
34
|
-
v<%= RSpecTracer::VERSION %>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</body>
|
|
38
|
-
</html>
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RSpecTracer
|
|
4
|
-
module RemoteCache
|
|
5
|
-
class Aws
|
|
6
|
-
class AwsError < StandardError; end
|
|
7
|
-
|
|
8
|
-
def initialize
|
|
9
|
-
@s3_bucket, @s3_path = setup_s3
|
|
10
|
-
@aws_cli = RSpecTracer.use_local_aws ? 'awslocal' : 'aws'
|
|
11
|
-
@use_test_suite_id_cache = ENV.fetch('USE_TEST_SUITE_ID_CACHE', nil) == 'true'
|
|
12
|
-
@test_suite_id = ENV.fetch('TEST_SUITE_ID', nil) if @use_test_suite_id_cache
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def branch_refs?(branch_name)
|
|
16
|
-
key = "#{@s3_path}/branch-refs/#{branch_name}/branch_refs.json"
|
|
17
|
-
|
|
18
|
-
system(
|
|
19
|
-
@aws_cli,
|
|
20
|
-
's3api',
|
|
21
|
-
'head-object',
|
|
22
|
-
'--bucket',
|
|
23
|
-
@s3_bucket,
|
|
24
|
-
'--key',
|
|
25
|
-
key,
|
|
26
|
-
out: File::NULL,
|
|
27
|
-
err: File::NULL
|
|
28
|
-
)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def download_branch_refs(branch_name, file_name)
|
|
32
|
-
key = "#{@s3_path}/branch-refs/#{branch_name}/branch_refs.json"
|
|
33
|
-
|
|
34
|
-
system(
|
|
35
|
-
@aws_cli,
|
|
36
|
-
's3api',
|
|
37
|
-
'get-object',
|
|
38
|
-
'--bucket',
|
|
39
|
-
@s3_bucket,
|
|
40
|
-
'--key',
|
|
41
|
-
key,
|
|
42
|
-
file_name,
|
|
43
|
-
out: File::NULL,
|
|
44
|
-
err: File::NULL
|
|
45
|
-
)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def upload_branch_refs(branch_name, file_name)
|
|
49
|
-
remote_path = "s3://#{@s3_bucket}/#{@s3_path}/branch-refs/#{branch_name}/branch_refs.json"
|
|
50
|
-
|
|
51
|
-
raise AwsError, "Failed to upload branch refs for #{branch_name} branch" unless system(
|
|
52
|
-
@aws_cli,
|
|
53
|
-
's3',
|
|
54
|
-
'cp',
|
|
55
|
-
file_name,
|
|
56
|
-
remote_path,
|
|
57
|
-
out: File::NULL,
|
|
58
|
-
err: File::NULL
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
RSpecTracer.logger.debug "Uploaded branch refs for #{branch_name} branch to #{remote_path}"
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def cache_files_list(ref)
|
|
65
|
-
prefix = if @use_test_suite_id_cache && !@test_suite_id.nil?
|
|
66
|
-
"s3://#{@s3_bucket}/#{@s3_path}/#{ref}/#{@test_suite_id}/"
|
|
67
|
-
else
|
|
68
|
-
"s3://#{@s3_bucket}/#{@s3_path}/#{ref}/"
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
`#{@aws_cli} s3 ls #{prefix} --recursive`.chomp.split("\n")
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def download_file(ref, file_name)
|
|
75
|
-
remote_path = File.join(s3_dir(ref), file_name)
|
|
76
|
-
local_path = File.join(RSpecTracer.cache_path, file_name)
|
|
77
|
-
|
|
78
|
-
raise AwsError, "Failed to download file #{remote_path}" unless system(
|
|
79
|
-
@aws_cli,
|
|
80
|
-
's3',
|
|
81
|
-
'cp',
|
|
82
|
-
remote_path,
|
|
83
|
-
local_path,
|
|
84
|
-
out: File::NULL,
|
|
85
|
-
err: File::NULL
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
RSpecTracer.logger.debug "Downloaded file #{remote_path} to #{local_path}"
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def download_dir(ref, run_id)
|
|
92
|
-
remote_dir = s3_dir(ref, run_id)
|
|
93
|
-
local_dir = File.join(RSpecTracer.cache_path, run_id)
|
|
94
|
-
|
|
95
|
-
raise AwsError, "Failed to download files from #{remote_dir}" unless system(
|
|
96
|
-
@aws_cli,
|
|
97
|
-
's3',
|
|
98
|
-
'cp',
|
|
99
|
-
remote_dir,
|
|
100
|
-
local_dir,
|
|
101
|
-
'--recursive',
|
|
102
|
-
out: File::NULL,
|
|
103
|
-
err: File::NULL
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
RSpecTracer.logger.debug "Downloaded cache files from #{remote_dir} to #{local_dir}"
|
|
107
|
-
rescue AwsError => e
|
|
108
|
-
FileUtils.rm_rf(local_dir)
|
|
109
|
-
|
|
110
|
-
raise e
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def upload_file(ref, file_name)
|
|
114
|
-
remote_path = File.join(s3_dir(ref), file_name)
|
|
115
|
-
local_path = File.join(RSpecTracer.cache_path, file_name)
|
|
116
|
-
|
|
117
|
-
raise AwsError, "Failed to upload file #{local_path}" unless system(
|
|
118
|
-
@aws_cli,
|
|
119
|
-
's3',
|
|
120
|
-
'cp',
|
|
121
|
-
local_path,
|
|
122
|
-
remote_path,
|
|
123
|
-
out: File::NULL,
|
|
124
|
-
err: File::NULL
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
RSpecTracer.logger.debug "Uploaded file #{local_path} to #{remote_path}"
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def upload_dir(ref, run_id)
|
|
131
|
-
remote_dir = s3_dir(ref, run_id)
|
|
132
|
-
local_dir = File.join(RSpecTracer.cache_path, run_id)
|
|
133
|
-
|
|
134
|
-
raise AwsError, "Failed to upload files from #{local_dir}" unless system(
|
|
135
|
-
@aws_cli,
|
|
136
|
-
's3',
|
|
137
|
-
'cp',
|
|
138
|
-
local_dir,
|
|
139
|
-
remote_dir,
|
|
140
|
-
'--recursive',
|
|
141
|
-
out: File::NULL,
|
|
142
|
-
err: File::NULL
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
RSpecTracer.logger.debug "Uploaded files from #{local_dir} to #{remote_dir}"
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
private
|
|
149
|
-
|
|
150
|
-
def setup_s3
|
|
151
|
-
s3_uri = RSpecTracer.reports_s3_path
|
|
152
|
-
|
|
153
|
-
raise AwsError, 'Invalid reports S3 path' if s3_uri.nil?
|
|
154
|
-
|
|
155
|
-
uri_parts = s3_uri[4..].split('/')
|
|
156
|
-
|
|
157
|
-
raise AwsError, "Invalid S3 URI #{s3_uri}" unless uri_parts.length >= 3 && uri_parts.first.empty?
|
|
158
|
-
|
|
159
|
-
[
|
|
160
|
-
uri_parts[1],
|
|
161
|
-
uri_parts[2..].join('/')
|
|
162
|
-
]
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
def s3_dir(ref, run_id = nil)
|
|
166
|
-
test_suite_id = ENV.fetch('TEST_SUITE_ID', nil)
|
|
167
|
-
|
|
168
|
-
if test_suite_id.nil?
|
|
169
|
-
"s3://#{@s3_bucket}/#{@s3_path}/#{ref}/#{run_id}/".sub(%r{/+$}, '/')
|
|
170
|
-
else
|
|
171
|
-
"s3://#{@s3_bucket}/#{@s3_path}/#{ref}/#{test_suite_id}/#{run_id}/".sub(%r{/+$}, '/')
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|