UNPKG

17.7 kBJavaScriptView Raw
1(function (factory) {
2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
5 }
6 else if (typeof define === "function" && define.amd) {
7 define(["require", "exports", "tslib", "charm", "istanbul-lib-coverage", "util", "@theintern/common", "../RemoteSuite", "./Reporter", "./TextCoverage"], factory);
8 }
9})(function (require, exports) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 exports.Result = exports.Report = void 0;
13 var tslib_1 = require("tslib");
14 var charm_1 = tslib_1.__importDefault(require("charm"));
15 var istanbul_lib_coverage_1 = require("istanbul-lib-coverage");
16 var util_1 = require("util");
17 var common_1 = require("@theintern/common");
18 var RemoteSuite_1 = tslib_1.__importDefault(require("../RemoteSuite"));
19 var Reporter_1 = require("./Reporter");
20 var TextCoverage_1 = tslib_1.__importDefault(require("./TextCoverage"));
21 var eventHandler = Reporter_1.createEventHandler();
22 var Pretty = (function (_super) {
23 tslib_1.__extends(Pretty, _super);
24 function Pretty(executor, options) {
25 if (options === void 0) { options = {}; }
26 var _this = _super.call(this, executor, options) || this;
27 _this._spinnerOffset = 0;
28 _this.dimensions = options.dimensions || {};
29 _this.titleWidth = options.titleWidth || 12;
30 _this.maxProgressBarWidth = options.maxProgressBarWidth || 40;
31 _this.colorReplacement = Object.assign({
32 0: 'green',
33 1: 'magenta',
34 2: 'red',
35 '✓': 'green',
36 '!': 'red',
37 '×': 'red',
38 '~': 'magenta',
39 '⚠': 'yelow',
40 }, options.colorReplacement || {});
41 _this._header = '';
42 _this._reports = {};
43 _this._log = [];
44 _this.tunnelState = '';
45 _this._total = new Report();
46 return _this;
47 }
48 Pretty.prototype.close = function () {
49 if (this._renderTimeout) {
50 clearTimeout(this._renderTimeout);
51 }
52 };
53 Pretty.prototype.runStart = function () {
54 var _this = this;
55 this._header = this.executor.config.name;
56 this._charm = this._charm || this._newCharm();
57 var resize = function () {
58 _this.dimensions.width = common_1.global.process.stdout.columns || 80;
59 _this.dimensions.height = common_1.global.process.stdout.rows || 24;
60 };
61 resize();
62 common_1.global.process.stdout.on('resize', resize);
63 var rerender = function () {
64 _this._charm.erase('screen').position(0, 0);
65 _this._render();
66 _this._renderTimeout = common_1.global.setTimeout(rerender, 200);
67 };
68 rerender();
69 };
70 Pretty.prototype.runEnd = function () {
71 var _this = this;
72 var charm = this._charm;
73 common_1.global.clearTimeout(this._renderTimeout);
74 charm.erase('screen').position(0, 0);
75 var ERROR_LOG_WEIGHT = {
76 '✓': 0,
77 '⚠': 1,
78 '~': 2,
79 '×': 3,
80 '!': 4,
81 };
82 this._log
83 .sort(function (a, b) {
84 a = ERROR_LOG_WEIGHT[a.charAt(0)] || 0;
85 b = ERROR_LOG_WEIGHT[b.charAt(0)] || 0;
86 return a - b;
87 })
88 .forEach(function (line) {
89 var color = _this._getColor(line);
90 if (color == null) {
91 charm.display('reset');
92 }
93 else {
94 charm.foreground(color);
95 }
96 charm.write(line + "\n");
97 });
98 charm.display('reset');
99 charm.write('\n');
100 this._render(true);
101 if (this._total.coverageMap.files().length > 0) {
102 charm.write('\n');
103 this.createCoverageReport('text', this._total.coverageMap);
104 }
105 };
106 Pretty.prototype.coverage = function (data) {
107 var report = this._reports[data.sessionId || ''];
108 report && report.coverageMap.merge(data.coverage);
109 this._total.coverageMap.merge(data.coverage);
110 };
111 Pretty.prototype.suiteStart = function (suite) {
112 if (!suite.hasParent || suite instanceof RemoteSuite_1.default) {
113 var numTests = suite.numTests;
114 this._total.numTotal += numTests;
115 if (suite.sessionId) {
116 var report = this._getReport(suite);
117 report.numTotal += numTests;
118 report.suiteInfo[suite.id] = {
119 parentId: suite.parentId,
120 numToReport: suite.numTests,
121 };
122 }
123 }
124 };
125 Pretty.prototype.suiteEnd = function (suite) {
126 if (suite.error) {
127 var info = this._getReport(suite).suiteInfo[suite.id];
128 this._record(suite, Result.SKIP, info.numToReport);
129 var message = '! ' + suite.id;
130 this._log.push(message + '\n' + this.formatError(suite.error));
131 }
132 };
133 Pretty.prototype.testEnd = function (test) {
134 if (test.skipped) {
135 this._record(test, Result.SKIP);
136 this._log.push('~ ' + test.id + ': ' + (test.skipped || 'skipped'));
137 }
138 else if (test.error) {
139 var message = '× ' + test.id;
140 this._record(test, Result.FAIL);
141 this._log.push(message + '\n' + this.formatError(test.error));
142 }
143 else {
144 this._record(test, Result.PASS);
145 this._log.push('✓ ' + test.id);
146 }
147 };
148 Pretty.prototype.tunnelDownloadProgress = function (message) {
149 var progress = message.progress;
150 this.tunnelState =
151 'Downloading ' +
152 ((progress.received / progress.total) * 100).toFixed(2) +
153 '%';
154 };
155 Pretty.prototype.tunnelStatus = function (message) {
156 this.tunnelState = message.status;
157 };
158 Pretty.prototype.error = function (error) {
159 var message = '! ' + error.message;
160 this._log.push(message + '\n' + this.formatError(error));
161 common_1.global.clearTimeout(this._renderTimeout);
162 };
163 Pretty.prototype.deprecated = function (message) {
164 var text = '⚠ ' + message.original + ' is deprecated.';
165 if (message.replacement) {
166 text += ' Use ' + message.replacement + ' instead.';
167 }
168 if (message.message) {
169 text += ' ' + message.message;
170 }
171 this._log.push(text);
172 };
173 Pretty.prototype._getReport = function (suiteOrTest) {
174 var id = suiteOrTest.sessionId || '';
175 if (!this._reports[id]) {
176 this._reports[id] = new Report(suiteOrTest.remote && suiteOrTest.remote.environmentType);
177 }
178 return this._reports[id];
179 };
180 Pretty.prototype._newCharm = function () {
181 var c = charm_1.default();
182 c.pipe(common_1.global.process.stdout);
183 return c;
184 };
185 Pretty.prototype._record = function (suiteOrTest, result, count) {
186 if (count === void 0) { count = 1; }
187 var report = this._reports[suiteOrTest.sessionId];
188 this._total.record(result, count);
189 if (report) {
190 report.record(result, count);
191 var suiteInfo = report.suiteInfo;
192 var info = suiteInfo[suiteOrTest.id];
193 if (!info && suiteOrTest.parentId) {
194 info = suiteInfo[suiteOrTest.parentId];
195 }
196 while (info) {
197 info.numToReport -= count;
198 if (info.parentId) {
199 info = suiteInfo[info.parentId];
200 }
201 else {
202 info = undefined;
203 }
204 }
205 }
206 };
207 Pretty.prototype._drawProgressBar = function (report, width) {
208 var _this = this;
209 var spinnerCharacter = SPINNER_STATES[this._spinnerOffset];
210 var charm = this._charm;
211 if (!report.numTotal) {
212 charm.write('Pending');
213 return;
214 }
215 var totalTextSize = String(report.numTotal).length;
216 var remainingWidth = Math.max(width - 4 - totalTextSize * 2, 1);
217 var barSize = Math.min(remainingWidth, report.numTotal, this.maxProgressBarWidth);
218 var results = report.getCompressedResults(barSize);
219 charm.write('[');
220 results.forEach(function (value) {
221 var color = _this._getColor(value);
222 if (color == null) {
223 charm.display('reset');
224 }
225 else {
226 charm.foreground(color);
227 }
228 charm.write(symbols[value]);
229 });
230 charm.display('reset');
231 charm.write(fit(spinnerCharacter, barSize - results.length) +
232 '] ' +
233 fit(report.finished, totalTextSize, true) +
234 '/' +
235 report.numTotal);
236 };
237 Pretty.prototype._drawSessionReport = function (report) {
238 var charm = this._charm;
239 var titleWidth = this.titleWidth;
240 var leftOfBar = fit(this._abbreviateEnvironment(report.environment).slice(0, titleWidth - 2) +
241 ': ', titleWidth);
242 var rightOfBar = '' +
243 (report.numFailed ? ', ' + report.numFailed + ' fail' : '') +
244 (report.numSkipped ? ', ' + report.numSkipped + ' skip' : '');
245 var barWidth = this.dimensions.width - rightOfBar.length - titleWidth;
246 charm.write(leftOfBar);
247 this._drawProgressBar(report, barWidth);
248 charm.write(rightOfBar + '\n');
249 };
250 Pretty.prototype._abbreviateEnvironment = function (env) {
251 var browser = BROWSERS[env.browserName.toLowerCase()] ||
252 env.browserName.slice(0, 4);
253 var result = [browser];
254 if (env.version) {
255 var version = String(env.version);
256 if (version.indexOf('.') > -1) {
257 version = version.slice(0, version.indexOf('.'));
258 }
259 result.push(version);
260 }
261 if (env.platform) {
262 result.push(env.platform.slice(0, 3));
263 }
264 return result.join(' ');
265 };
266 Pretty.prototype._render = function (omitLogs) {
267 var _this = this;
268 if (omitLogs === void 0) { omitLogs = false; }
269 var charm = this._charm;
270 var numReports = Object.keys(this._reports).length;
271 var logLength = this.dimensions.height -
272 numReports -
273 4 -
274 (this.tunnelState ? 2 : 0) -
275 (numReports ? 1 : 0) -
276 (this._header ? 1 : 0);
277 this._spinnerOffset = ++this._spinnerOffset % SPINNER_STATES.length;
278 charm.display('reset');
279 if (this._header) {
280 charm.display('bright');
281 charm.write(this._header + '\n');
282 charm.display('reset');
283 }
284 this.tunnelState && charm.write('Tunnel: ' + this.tunnelState + '\n\n');
285 this._drawTotalReport(this._total);
286 if (numReports) {
287 charm.write('\n');
288 for (var key in this._reports) {
289 this._drawSessionReport(this._reports[key]);
290 }
291 }
292 if (!omitLogs && logLength > 0 && this._log.length) {
293 var allowed_1 = { '×': true, '⚠': true, '!': true };
294 charm.write('\n');
295 this._log
296 .filter(function (line) {
297 return allowed_1[line.charAt(0)];
298 })
299 .slice(-logLength)
300 .forEach(function (line) {
301 var color = _this._getColor(line);
302 if (color) {
303 charm.foreground(color);
304 }
305 line = line.split('\n', 1)[0];
306 charm.write(line.slice(0, _this.dimensions.width) + "\n");
307 charm.display('reset');
308 });
309 }
310 };
311 Pretty.prototype._drawTotalReport = function (report) {
312 var charm = this._charm;
313 var title = 'Total: ';
314 var totalTextSize = String(report.numTotal).length;
315 charm.write(title);
316 this._drawProgressBar(report, this.dimensions.width - title.length);
317 charm.write(util_1.format('\nPassed: %s Failed: %s Skipped: %d\n', fit(report.numPassed, totalTextSize), fit(report.numFailed, totalTextSize), report.numSkipped));
318 };
319 Pretty.prototype._getColor = function (value) {
320 if (typeof value === 'string') {
321 value = value[0];
322 }
323 return this.colorReplacement[value] || null;
324 };
325 tslib_1.__decorate([
326 eventHandler()
327 ], Pretty.prototype, "runStart", null);
328 tslib_1.__decorate([
329 eventHandler()
330 ], Pretty.prototype, "runEnd", null);
331 tslib_1.__decorate([
332 eventHandler()
333 ], Pretty.prototype, "coverage", null);
334 tslib_1.__decorate([
335 eventHandler()
336 ], Pretty.prototype, "suiteStart", null);
337 tslib_1.__decorate([
338 eventHandler()
339 ], Pretty.prototype, "suiteEnd", null);
340 tslib_1.__decorate([
341 eventHandler()
342 ], Pretty.prototype, "testEnd", null);
343 tslib_1.__decorate([
344 eventHandler()
345 ], Pretty.prototype, "tunnelDownloadProgress", null);
346 tslib_1.__decorate([
347 eventHandler()
348 ], Pretty.prototype, "tunnelStatus", null);
349 tslib_1.__decorate([
350 eventHandler()
351 ], Pretty.prototype, "error", null);
352 tslib_1.__decorate([
353 eventHandler()
354 ], Pretty.prototype, "deprecated", null);
355 return Pretty;
356 }(TextCoverage_1.default));
357 exports.default = Pretty;
358 var Report = (function () {
359 function Report(environment, sessionId) {
360 this.numTotal = 0;
361 this.numPassed = 0;
362 this.numFailed = 0;
363 this.numSkipped = 0;
364 this.results = [];
365 this.environment = environment;
366 this.sessionId = sessionId;
367 this.coverageMap = istanbul_lib_coverage_1.createCoverageMap();
368 this.suiteInfo = {};
369 }
370 Object.defineProperty(Report.prototype, "finished", {
371 get: function () {
372 return this.results.length;
373 },
374 enumerable: false,
375 configurable: true
376 });
377 Report.prototype.record = function (result, count) {
378 if (count === void 0) { count = 1; }
379 for (var i = 0; i < count; i++) {
380 this.results.push(result);
381 }
382 switch (result) {
383 case Result.PASS:
384 this.numPassed += count;
385 break;
386 case Result.SKIP:
387 this.numSkipped += count;
388 break;
389 case Result.FAIL:
390 this.numFailed += count;
391 break;
392 }
393 };
394 Report.prototype.getCompressedResults = function (maxWidth) {
395 var total = Math.max(this.numTotal, this.results.length);
396 var width = Math.min(maxWidth, total);
397 var resultList = [];
398 for (var i = 0; i < this.results.length; ++i) {
399 var pos = Math.floor((i / total) * width);
400 resultList[pos] = Math.max(resultList[pos] || Result.PASS, this.results[i]);
401 }
402 return resultList;
403 };
404 return Report;
405 }());
406 exports.Report = Report;
407 var Result;
408 (function (Result) {
409 Result[Result["PASS"] = 0] = "PASS";
410 Result[Result["SKIP"] = 1] = "SKIP";
411 Result[Result["FAIL"] = 2] = "FAIL";
412 })(Result = exports.Result || (exports.Result = {}));
413 var symbols = ['✓', '~', '×'];
414 var PAD = new Array(100).join(' ');
415 var SPINNER_STATES = ['/', '-', '\\', '|'];
416 var BROWSERS = {
417 chrome: 'Chr',
418 firefox: 'Fx',
419 opera: 'O',
420 safari: 'Saf',
421 'internet explorer': 'IE',
422 phantomjs: 'Phan',
423 };
424 function pad(width) {
425 return PAD.slice(0, Math.max(width, 0));
426 }
427 function fit(text, width, padLeft) {
428 if (padLeft === void 0) { padLeft = false; }
429 text = String(text);
430 if (text.length < width) {
431 if (padLeft) {
432 return pad(width - text.length) + text;
433 }
434 return text + pad(width - text.length);
435 }
436 return text.slice(0, width);
437 }
438});
439//# sourceMappingURL=Pretty.js.map
\No newline at end of file