Skip to content

Commit 6b64ab2

Browse files
authored
Revert "Drone: readable test report with a permalink test status page url (#6…"
This reverts commit 3d463e4.
1 parent 3d463e4 commit 6b64ab2

4 files changed

Lines changed: 236 additions & 305 deletions

File tree

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/**
2+
* @file Dynamic status icon generator
3+
* @author Brad Buchanan <bradley.c.buchanan@gmail.com>
4+
*
5+
* Loosely based on https://gist.github.com/mathiasbynens/428626
6+
*
7+
* @example
8+
* // Set tab icon to green for passing
9+
* setTabStatusIcon('pass');
10+
*
11+
* // Set tab icon to a custom color
12+
* setTabStatusIcon('#62a938');
13+
*/
14+
/* global define, module */ // Be AMD and CommonJS-friendly without bothering linter.
15+
(function (root, factory) {
16+
if (typeof define === 'function' && define.amd) {
17+
define([], factory);
18+
} else if (typeof module === 'object' && module.exports) {
19+
module.exports = factory();
20+
} else {
21+
root.setTabStatusIcon = factory();
22+
}
23+
}(this, function () {
24+
var GRAY = '#aaa';
25+
var BLUE = '#3A84CB';
26+
var GREEN = '#7FBA00';
27+
var RED = '#C40000';
28+
var DEFAULT_COLOR = GRAY;
29+
var STATUS_COLORS = {
30+
'fail': RED,
31+
'in-progress': BLUE,
32+
'not-started': GRAY,
33+
'pass': GREEN
34+
};
35+
var STATUS_ICONS = {
36+
'fail': drawX,
37+
'pass': drawCheckmark
38+
};
39+
40+
var LINK_ELEMENT_ID = 'tab-status-icon-link';
41+
42+
/**
43+
* Replace the favicon reference in the document head with a new one.
44+
*/
45+
function setStatusIcon(imageUrl) {
46+
var head = document.getElementsByTagName('head')[0];
47+
48+
var oldLink = document.getElementById(LINK_ELEMENT_ID);
49+
if (oldLink) {
50+
head.removeChild(oldLink);
51+
}
52+
53+
var newLink = document.createElement('link');
54+
newLink.id = LINK_ELEMENT_ID;
55+
newLink.rel = 'shortcut icon';
56+
newLink.href = imageUrl;
57+
head.appendChild(newLink);
58+
}
59+
60+
/**
61+
* Generates a PNG dataURL for a status icon displaying the
62+
* given color and progress.
63+
* @param {string} [typeOrColor] Any valid HTML color string, or a
64+
* status string ('pass', 'fail', 'in-progress', 'not-started').
65+
* Defaults to gray (not started).
66+
*/
67+
function makeStatusIcon(typeOrColor) {
68+
if (typeof typeOrColor !== 'string') {
69+
typeOrColor = DEFAULT_COLOR;
70+
}
71+
var color = STATUS_COLORS.hasOwnProperty(typeOrColor) ? STATUS_COLORS[typeOrColor] : typeOrColor;
72+
73+
var canvas = document.createElement('canvas');
74+
canvas.width = canvas.height = 32;
75+
var ctx = canvas.getContext('2d');
76+
77+
drawBackground(ctx, color);
78+
if (STATUS_ICONS.hasOwnProperty(typeOrColor)) {
79+
STATUS_ICONS[typeOrColor](ctx, color);
80+
} else {
81+
drawHighlight(ctx);
82+
}
83+
84+
return canvas.toDataURL();
85+
}
86+
87+
/**
88+
* Draw a bordered circular background in the given color
89+
* @param ctx
90+
* @param color
91+
*/
92+
function drawBackground(ctx, color) {
93+
// Border
94+
ctx.beginPath();
95+
ctx.ellipse(16, 16, 16, 16, 0, 0, 2 * Math.PI);
96+
ctx.fillStyle = color;
97+
ctx.fill();
98+
99+
ctx.beginPath();
100+
ctx.ellipse(16, 16, 14, 14, 0, 0, 2 * Math.PI);
101+
ctx.fillStyle = 'white';
102+
ctx.fill();
103+
104+
// Fill
105+
ctx.beginPath();
106+
ctx.ellipse(16, 16, 13, 13, 0, 0, 2 * Math.PI);
107+
ctx.fillStyle = color;
108+
ctx.fill();
109+
}
110+
111+
/**
112+
* Draw a checkmark (success) icon
113+
* @param ctx
114+
* @param color
115+
*/
116+
function drawCheckmark(ctx, color) {
117+
ctx.beginPath();
118+
ctx.moveTo(8, 16);
119+
ctx.lineTo(15, 19);
120+
ctx.lineTo(29, 6);
121+
ctx.lineTo(30, 7);
122+
ctx.lineTo(15, 24);
123+
ctx.lineTo(7, 17);
124+
ctx.closePath();
125+
ctx.strokeStyle = color;
126+
ctx.lineWidth = 3;
127+
ctx.stroke();
128+
ctx.fillStyle = 'white';
129+
ctx.fill();
130+
}
131+
132+
function drawX(ctx, color) {
133+
ctx.beginPath();
134+
ctx.moveTo(6, 7);
135+
ctx.lineTo(11, 7);
136+
ctx.lineTo(17, 15);
137+
ctx.lineTo(23, 7);
138+
ctx.lineTo(28, 7);
139+
ctx.lineTo(18, 16);
140+
ctx.lineTo(28, 25);
141+
ctx.lineTo(23, 25);
142+
ctx.lineTo(17, 17);
143+
ctx.lineTo(11, 25);
144+
ctx.lineTo(6, 25);
145+
ctx.lineTo(16, 16);
146+
ctx.closePath();
147+
ctx.strokeStyle = color;
148+
ctx.lineWidth = 3;
149+
ctx.stroke();
150+
ctx.fillStyle = 'white';
151+
ctx.fill();
152+
}
153+
154+
/**
155+
* Draw a "specular highlight."
156+
* Used as a default if we don't know what icon to draw.
157+
* @param ctx
158+
*/
159+
function drawHighlight(ctx) {
160+
ctx.beginPath();
161+
ctx.ellipse(22, 10, 4, 4, 0, 0, 2 * Math.PI);
162+
ctx.fillStyle = 'white';
163+
ctx.fill();
164+
}
165+
166+
/**
167+
* Changes the icon in your browser tab (replacing the favicon)
168+
* to a dynamically-generated status icon of the given color
169+
* and progress info.
170+
* @param {string} [typeOrColor] Any valid HTML color string, or a
171+
* status string ('pass', 'fail', 'in-progress', 'not-started').
172+
* Defaults to gray (not started).
173+
*/
174+
return function setTabStatusIcon(typeOrColor) {
175+
setStatusIcon(makeStatusIcon(typeOrColor));
176+
};
177+
}));
178+

dashboard/test/ui/runner.rb

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
require 'cdo/git_utils'
1616
require 'cdo/rake_utils'
1717
require 'cdo/test_flakiness'
18-
require 'cdo/ci_utils'
1918

2019
require 'haml'
2120
require 'json'
@@ -63,7 +62,7 @@ def main(options)
6362
open_log_files
6463
configure_for_eyes if eyes?
6564
report_tests_starting
66-
run_status_page_url = generate_status_page(start_time) if options.with_status_page
65+
generate_status_page(start_time) if options.with_status_page
6766

6867
run_results = Parallel.map(browser_feature_generator, parallel_config(options.parallel_limit)) do |browser, feature|
6968
run_feature browser, feature, options
@@ -87,7 +86,7 @@ def main(options)
8786
return 1001
8887
end
8988

90-
report_tests_finished start_time, run_results, run_status_page_url
89+
report_tests_finished start_time, run_results
9190
run_results.count {|feature_succeeded, _, _| !feature_succeeded}
9291
ensure
9392
close_log_files
@@ -414,7 +413,7 @@ def report_tests_starting
414413
end
415414
end
416415

417-
def report_tests_finished(start_time, run_results, run_status_page_url = nil)
416+
def report_tests_finished(start_time, run_results)
418417
suite_duration = Time.now - start_time
419418

420419
# How many flaky test reruns occurred across all tests (ignoring the initial attempt).
@@ -441,22 +440,28 @@ def report_tests_finished(start_time, run_results, run_status_page_url = nil)
441440
Infrastructure::Logger.put('runner_feature_tests_successful_flaky_reruns', total_flaky_successful_reruns, extra_dimensions)
442441
Infrastructure::Logger.put('runner_feature_tests_count', run_results.count, extra_dimensions)
443442
Infrastructure::Logger.flush
444-
445-
test_report = "\n#{test_type.upcase} TEST REPORT: #{failures.any? ? "*❌ FAILED*" : "*✅ PASSED*"}\n"
446-
test_report += "\n#{failures.count}x failed features:\n" + failures.map {|failure| "• #{failure}\n"}.join if failures.any?
447-
test_report += "\n"
448-
test_report += "Applitools Eyes Results:\n#{applitools_batch_url}\n\n" if applitools_batch_url
449-
test_report += "#{test_type} Test Status Page (permalink for this run):\n#{run_status_page_url}\n\n" if run_status_page_url
450-
test_report += "#{test_type} Test Status Page (for this server, *if you're lost start here*):\n#{server_status_page_url}\n\n" unless CI::Utils.running_on_ci?
451-
test_report += "\n"
452-
test_report += "#{suite_success_count} passed. #{failures.count} failed. Test count: #{run_results.count}. Duration: #{RakeUtils.format_duration(suite_duration)}. Total successful reruns of flaky tests: #{total_flaky_successful_reruns}.\n"
453-
test_report += "\n"
454-
test_report += "\n*#{test_type.upcase}* TESTS #{failures.any? ? "FAILED" : "PASSED"}\n\n"
455-
456-
ChatClient.log test_report, color: 'purple'
443+
ChatClient.log "#{suite_success_count} succeeded. #{failures.count} failed. " \
444+
"Test count: #{run_results.count}. " \
445+
"Total duration: #{RakeUtils.format_duration(suite_duration)}. " \
446+
"Total reruns of flaky tests: #{total_flaky_reruns}. " \
447+
"Total successful reruns of flaky tests: #{total_flaky_successful_reruns}." \
448+
+ (status_page_url ? " <a href=\"#{status_page_url}\">#{test_type} test status page</a>." : '') \
449+
+ (applitools_batch_url ? " <a href=\"#{applitools_batch_url}\">Applitools results</a>." : '')
450+
451+
a_status_page = status_page_url ? "<a href=\"#{status_page_url}\">" : ''
452+
end_a = status_page_url ? "</a>" : ''
453+
454+
if failures.empty?
455+
ChatClient.log "*#{a_status_page}SUMMARY, #{suite_success_count} DASHBOARD #{test_type.upcase} TESTS PASSED#{end_a}*", color: 'purple'
456+
else
457+
ChatClient.log "*#{a_status_page}SUMMARY, #{failures.count} DASHBOARD #{test_type.upcase} TESTS FAILED#{end_a}:*", color: 'purple'
458+
failures.each do |failure|
459+
ChatClient.log "\t#{failure}", color: 'purple'
460+
end
461+
end
457462
end
458463

459-
def server_status_page_url
464+
def status_page_url
460465
return nil unless $options.with_status_page
461466
CDO.studio_url('/ui_test/' + status_page_filename, scheme_for_environment)
462467
end
@@ -465,30 +470,15 @@ def status_page_filename
465470
"test_status_#{test_type}.html"
466471
end
467472

468-
# Returns a permalink URL for the Test Status Page, assuming we can upload it to S3
469-
def upload_status_page_to_s3(status_page_path = File.join(UI_TEST_DIR, status_page_filename))
470-
LOG_UPLOADER.upload_file(File.join(UI_TEST_DIR, 'test_status.css'), {content_type: 'text/css'})
471-
LOG_UPLOADER.upload_file(File.join(UI_TEST_DIR, 'test_status.js'), {content_type: 'text/javascript'})
472-
473-
return LOG_UPLOADER.upload_file(status_page_path, {content_type: 'text/html'})
474-
rescue Aws::Sigv4::Errors::MissingCredentialsError
475-
ChatClient.log "No AWS credentials set, skipping upload of the '#{test_type} Test Status Page' to S3"
476-
nil
477-
rescue Exception => exception
478-
ChatClient.log "WARNING: exception raised while attempting to upload the '#{test_type} Test Status Page' to S3:\n#{exception.class}: #{exception}\n#{exception.backtrace&.first(5)&.join("\n")}"
479-
nil
480-
end
481-
482473
def scheme_for_environment
483474
(rack_env?(:development) && !CDO.https_development) ? 'http:' : 'https:'
484475
end
485476

486477
def generate_status_page(suite_start_time)
487478
test_status_template = File.read(File.join(UI_TEST_DIR, 'test_status.haml'))
488479
haml_engine = Haml::Engine.new(test_status_template)
489-
status_page_path = File.join(UI_TEST_DIR, status_page_filename)
490480
File.write(
491-
status_page_path,
481+
File.join(UI_TEST_DIR, status_page_filename),
492482
haml_engine.render(
493483
Object.new,
494484
{
@@ -503,10 +493,7 @@ def generate_status_page(suite_start_time)
503493
}
504494
)
505495
)
506-
run_status_page_url = upload_status_page_to_s3(status_page_path)
507-
ChatClient.log "#{test_type} Test Status Page (permalink for this run):\n#{run_status_page_url}\n\n" if run_status_page_url
508-
ChatClient.log "#{test_type} Test Status Page (for this server):\n#{server_status_page_url}\n\n" unless CI::Utils.running_on_ci?
509-
return run_status_page_url
496+
ChatClient.log "A <a href=\"#{status_page_url}\">status page</a> has been generated for this #{test_type} test run."
510497
end
511498

512499
def test_run_identifier(browser, feature)

dashboard/test/ui/test_status.haml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
%link{:rel => :stylesheet, :type => :"text/css", :href => "test_status.css"}
77
%script{src: 'https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js'}
88
%script{src: 'https://cdn.jsdelivr.net/clipboard.js/1.5.13/clipboard.min.js'}
9+
%script{src: './js/set-tab-status-icon.js'}
910
%body
1011
.centered-column
1112
%div#refresh-controls

0 commit comments

Comments
 (0)