Skip to content
This repository was archived by the owner on Apr 14, 2021. It is now read-only.

Commit be22e7f

Browse files
author
Andy Earnshaw
committed
CLUI output for local sauce tests
1 parent 5a1288a commit be22e7f

File tree

2 files changed

+123
-11
lines changed

2 files changed

+123
-11
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
},
1010
"devDependencies": {
1111
"async": "^0.9.0",
12+
"cli-color": "^1.0.0",
13+
"clui": "^0.3.1",
1214
"finalhandler": "^0.4.0",
1315
"glob": "^5.0.3",
1416
"grunt": "^0.4.5",

tests/saucelabs.js

+121-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*eslint-env node*/
22
'use strict';
33
var LIBS = {
4+
clc: require('cli-color'),
5+
CLI: require('clui'),
46
Sauce: require('sauce-tunnel'),
57
http: require('http'),
68
serve: require('serve-static'),
@@ -71,10 +73,21 @@ var LIBS = {
7173
}
7274
],
7375

76+
// Fancy CLI output
77+
Line = LIBS.CLI.Line,
78+
oldConsoleLog = console.log,
79+
consoleLogAllowed = false,
80+
81+
lastTunnelMessage,
82+
lastErrorMessages = [],
83+
lastOutputLines = 0,
7484
tunnel = process.env.TRAVIS_BUILD_NUMBER ? null : new LIBS.Sauce(process.env.SAUCE_USERNAME, process.env.SAUCE_ACCESS_KEY),
7585
serveStatic = LIBS.serve(LIBS.path.resolve(__dirname, '../')),
7686
testBaseURL = 'http://localhost:8000/tests/test262/pages/',
7787

88+
// Get the tests together
89+
tests = listTests(),
90+
7891
// A list of tests that ES3 environments can't pass, either because they
7992
// use accessors or they test for behaviour achievable only in ES5 environments
8093
es3blacklist = [
@@ -88,6 +101,69 @@ LIBS.http.createServer(function(req, res) {
88101
serveStatic(req, res, done);
89102
}).listen(8000);
90103

104+
function drawStatus () {
105+
// Don't draw fancy updates in Travis' log
106+
if (process.env.TRAVIS_JOB_NUMBER) {
107+
return;
108+
}
109+
110+
var clc = LIBS.clc,
111+
maxWidth = LIBS.clc.windowSize.width,
112+
blankLine = new Line().fill();
113+
114+
if (lastOutputLines) {
115+
process.stdout.write('\x1b[' + lastOutputLines + 'A');
116+
lastOutputLines = 0;
117+
}
118+
119+
// Draw header
120+
blankLine.output();
121+
new Line()
122+
.padding(2)
123+
.column('Browser', 22, [ clc.cyan ])
124+
.column('Passed (Failed)', tests.length + 2, [ clc.cyan ])
125+
.fill()
126+
.output();
127+
128+
// Draw status
129+
blankLine.output();
130+
lastOutputLines += 3;
131+
for (var k in BROWSERS) {
132+
var results = BROWSERS[k].results || { failCount: 0, passCount: 0 };
133+
new Line()
134+
.padding(2)
135+
.column(BROWSERS[k].browserName + ' ' + BROWSERS[k].version, 22, [ clc.blue ])
136+
.column(results.passCount + ' (' + results.failCount + ') ', undefined, [ results.failCount ? clc.red : clc.green ])
137+
.column(results.currentTest || 'Waiting...', 100, [ clc.blackBright ])
138+
.fill()
139+
.output();
140+
141+
lastOutputLines++;
142+
}
143+
144+
blankLine.output();
145+
lastOutputLines++;
146+
147+
if (lastTunnelMessage) {
148+
new Line().column('Sauce Connect status:', maxWidth, [ clc.cyan ]).fill().output();
149+
new Line().padding(2).column(lastTunnelMessage).fill().output();
150+
lastOutputLines += 2;
151+
}
152+
153+
if (lastErrorMessages.length) {
154+
blankLine.output();
155+
new Line().column('Recent failures:', maxWidth, [ clc.cyan ]).fill().output();
156+
lastOutputLines += 2;
157+
158+
lastErrorMessages.forEach(function (m) {
159+
new Line().column(' ' + m.split('\n').shift(), maxWidth, [ clc.red ]).fill().output();
160+
lastOutputLines++;
161+
});
162+
}
163+
blankLine.output();
164+
lastOutputLines++;
165+
}
166+
91167
function listTests() {
92168
var tests = [],
93169
todo = ['.'],
@@ -119,7 +195,8 @@ function runTestsInBrowser(state, browserConfig, done) {
119195
browserString = LIBS.util.inspect(browserConfig, {depth: null}).replace(/\n\s*/g, ' '),
120196
browser,
121197
failures = 0;
122-
console.log('================================================ START', browserString);
198+
199+
console.log(LIBS.clc.cyan('================================================ START'), browserString);
123200

124201
Object.keys(state.capabilities).forEach(function(key) {
125202
caps[key] = state.capabilities[key];
@@ -149,12 +226,21 @@ function runTestsInBrowser(state, browserConfig, done) {
149226
browser.init(caps, taskDone);
150227
});
151228

229+
// Setup progress and results
230+
browserConfig.results = {
231+
failCount: 0,
232+
passCount: 0,
233+
errors: []
234+
};
235+
152236
// for each page, get and test page
153237
state.tests.forEach(function(test) {
154238
tasks.push(function(taskDone) {
155239
var url = testBaseURL + test,
156240
ie8 = browserConfig.browserName === 'internet explorer' && browserConfig.version === '8';
157241

242+
browserConfig.results.currentTest = test;
243+
158244
//- Skip impassable tests in IE 8
159245
if (ie8 && (test.slice(-9) === '_L15.html' || es3blacklist.indexOf(test.split('/').pop()) > -1)) {
160246
console.log('--SKIPPED--', test, browserString, 'Not passable from ES3 environments');
@@ -171,20 +257,30 @@ function runTestsInBrowser(state, browserConfig, done) {
171257
if (cookedErr.message) { cookedErr = cookedErr.message; }
172258
cookedErr = cookedErr.toString().split('\n')[0];
173259
cookedErr = cookedErr || out || 'FAILED no results';
174-
console.log('--ERROR--', err);
260+
console.log(LIBS.clc.red('--ERROR--'), LIBS.clc.red(err));
175261
}
176262
if (out) {
177263
state.results.passCount++;
264+
browserConfig.results.passCount++;
178265
console.log('--PASSED--', test, browserString);
179266
} else {
180267
failures++;
268+
browserConfig.results.failCount++;
181269
state.results.failCount++;
182270
if (!state.results.failures[test]) {
183271
state.results.failures[test] = {};
184272
}
185273
state.results.failures[test][browserString] = cookedErr;
186-
console.log('--FAILED--', test, browserString, cookedErr);
274+
if (lastErrorMessages.length > 4) {
275+
lastErrorMessages.length = 4;
276+
}
277+
lastErrorMessages.push(browserConfig.browserName + ' ' + browserConfig.version + ' – ' + cookedErr);
278+
console.log(LIBS.clc.red('--FAILED--'), LIBS.clc.red(test), LIBS.clc.red(browserString), LIBS.clc.red(cookedErr));
187279
}
280+
281+
// Update display
282+
drawStatus();
283+
188284
// This sometimes signifies a suacelabs browser that has gone awawy.
189285
if ('ERROR Internal Server Error' === cookedErr) {
190286
taskDone(err);
@@ -251,10 +347,10 @@ function runTestsInBrowser(state, browserConfig, done) {
251347
});
252348

253349
LIBS.async.series(tasks, function(err) {
254-
console.log('================================================ DONE', browserString);
350+
console.log(LIBS.clc.cyan('================================================ DONE'), browserString);
255351
if (err) {
256-
console.log('--BROWSER FAILED--');
257-
console.log(err);
352+
console.log(LIBS.clc.red('--BROWSER FAILED--'));
353+
console.log(LIBS.clc.red(err));
258354
}
259355
done(err);
260356
});
@@ -268,7 +364,7 @@ function runTests(state, done) {
268364
q = LIBS.async.queue(function(browser, browserDone) {
269365
runTestsInBrowser(state, browser, function(err) {
270366
if (err) {
271-
console.log(err.message);
367+
console.log(LIBS.clc.red(err.message));
272368
browserFailures++;
273369
}
274370
browserDone();
@@ -306,6 +402,12 @@ function main(tunnelReady) {
306402
tags: []
307403
};
308404
state.capabilities['tunnel-identifier'] = process.env.TRAVIS_JOB_NUMBER || tunnel.identifier;
405+
406+
// Override console log for local
407+
if (!process.env.TRAVIS_JOB_NUMBER) {
408+
console.log = function () {};
409+
}
410+
309411
if (process.env.TRAVIS_JOB_NUMBER) {
310412
// we only need one of these to run on travis
311413
if ('.1' !== process.env.TRAVIS_JOB_NUMBER.substr(-2)) {
@@ -319,12 +421,15 @@ function main(tunnelReady) {
319421
state.capabilities.build = process.env.TRAVIS_BUILD_NUMBER || process.pid;
320422
console.log(JSON.stringify(state.capabilities, null, 4));
321423

322-
console.log('================================================ START');
424+
console.log(LIBS.clc.cyan('================================================ START'));
323425
runTests(state, function(err) {
324426
if (tunnel) {
325427
tunnel.stop(function () {});
326428
}
327-
console.log('================================================ DONE');
429+
console.log(LIBS.clc.cyan('================================================ DONE'));
430+
431+
console.log = oldConsoleLog;
432+
328433
if (err) {
329434
console.error(err);
330435
process.exit(2);
@@ -338,10 +443,15 @@ function main(tunnelReady) {
338443
});
339444
}
340445

446+
// Save the current cursor position for redraws
447+
drawStatus();
448+
341449
if (tunnel) {
342-
console.log('Starting SauceTunnel...');
343450
tunnel.start(main);
344-
tunnel.proc.stdout.pipe(process.stdout);
451+
tunnel.proc.stdout.on('data', function (msg) {
452+
lastTunnelMessage = String(msg).split('\n').shift();
453+
drawStatus();
454+
});
345455
}
346456
else {
347457
main(true);

0 commit comments

Comments
 (0)