intern
Version:
Intern. A next-generation code testing stack for JavaScript.
439 lines • 17.7 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "tslib", "charm", "istanbul-lib-coverage", "util", "@theintern/common", "../RemoteSuite", "./Reporter", "./TextCoverage"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Result = exports.Report = void 0;
var tslib_1 = require("tslib");
var charm_1 = tslib_1.__importDefault(require("charm"));
var istanbul_lib_coverage_1 = require("istanbul-lib-coverage");
var util_1 = require("util");
var common_1 = require("@theintern/common");
var RemoteSuite_1 = tslib_1.__importDefault(require("../RemoteSuite"));
var Reporter_1 = require("./Reporter");
var TextCoverage_1 = tslib_1.__importDefault(require("./TextCoverage"));
var eventHandler = Reporter_1.createEventHandler();
var Pretty = (function (_super) {
tslib_1.__extends(Pretty, _super);
function Pretty(executor, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this, executor, options) || this;
_this._spinnerOffset = 0;
_this.dimensions = options.dimensions || {};
_this.titleWidth = options.titleWidth || 12;
_this.maxProgressBarWidth = options.maxProgressBarWidth || 40;
_this.colorReplacement = Object.assign({
0: 'green',
1: 'magenta',
2: 'red',
'✓': 'green',
'!': 'red',
'×': 'red',
'~': 'magenta',
'⚠': 'yelow',
}, options.colorReplacement || {});
_this._header = '';
_this._reports = {};
_this._log = [];
_this.tunnelState = '';
_this._total = new Report();
return _this;
}
Pretty.prototype.close = function () {
if (this._renderTimeout) {
clearTimeout(this._renderTimeout);
}
};
Pretty.prototype.runStart = function () {
var _this = this;
this._header = this.executor.config.name;
this._charm = this._charm || this._newCharm();
var resize = function () {
_this.dimensions.width = common_1.global.process.stdout.columns || 80;
_this.dimensions.height = common_1.global.process.stdout.rows || 24;
};
resize();
common_1.global.process.stdout.on('resize', resize);
var rerender = function () {
_this._charm.erase('screen').position(0, 0);
_this._render();
_this._renderTimeout = common_1.global.setTimeout(rerender, 200);
};
rerender();
};
Pretty.prototype.runEnd = function () {
var _this = this;
var charm = this._charm;
common_1.global.clearTimeout(this._renderTimeout);
charm.erase('screen').position(0, 0);
var ERROR_LOG_WEIGHT = {
'✓': 0,
'⚠': 1,
'~': 2,
'×': 3,
'!': 4,
};
this._log
.sort(function (a, b) {
a = ERROR_LOG_WEIGHT[a.charAt(0)] || 0;
b = ERROR_LOG_WEIGHT[b.charAt(0)] || 0;
return a - b;
})
.forEach(function (line) {
var color = _this._getColor(line);
if (color == null) {
charm.display('reset');
}
else {
charm.foreground(color);
}
charm.write(line + "\n");
});
charm.display('reset');
charm.write('\n');
this._render(true);
if (this._total.coverageMap.files().length > 0) {
charm.write('\n');
this.createCoverageReport('text', this._total.coverageMap);
}
};
Pretty.prototype.coverage = function (data) {
var report = this._reports[data.sessionId || ''];
report && report.coverageMap.merge(data.coverage);
this._total.coverageMap.merge(data.coverage);
};
Pretty.prototype.suiteStart = function (suite) {
if (!suite.hasParent || suite instanceof RemoteSuite_1.default) {
var numTests = suite.numTests;
this._total.numTotal += numTests;
if (suite.sessionId) {
var report = this._getReport(suite);
report.numTotal += numTests;
report.suiteInfo[suite.id] = {
parentId: suite.parentId,
numToReport: suite.numTests,
};
}
}
};
Pretty.prototype.suiteEnd = function (suite) {
if (suite.error) {
var info = this._getReport(suite).suiteInfo[suite.id];
this._record(suite, Result.SKIP, info.numToReport);
var message = '! ' + suite.id;
this._log.push(message + '\n' + this.formatError(suite.error));
}
};
Pretty.prototype.testEnd = function (test) {
if (test.skipped) {
this._record(test, Result.SKIP);
this._log.push('~ ' + test.id + ': ' + (test.skipped || 'skipped'));
}
else if (test.error) {
var message = '× ' + test.id;
this._record(test, Result.FAIL);
this._log.push(message + '\n' + this.formatError(test.error));
}
else {
this._record(test, Result.PASS);
this._log.push('✓ ' + test.id);
}
};
Pretty.prototype.tunnelDownloadProgress = function (message) {
var progress = message.progress;
this.tunnelState =
'Downloading ' +
((progress.received / progress.total) * 100).toFixed(2) +
'%';
};
Pretty.prototype.tunnelStatus = function (message) {
this.tunnelState = message.status;
};
Pretty.prototype.error = function (error) {
var message = '! ' + error.message;
this._log.push(message + '\n' + this.formatError(error));
common_1.global.clearTimeout(this._renderTimeout);
};
Pretty.prototype.deprecated = function (message) {
var text = '⚠ ' + message.original + ' is deprecated.';
if (message.replacement) {
text += ' Use ' + message.replacement + ' instead.';
}
if (message.message) {
text += ' ' + message.message;
}
this._log.push(text);
};
Pretty.prototype._getReport = function (suiteOrTest) {
var id = suiteOrTest.sessionId || '';
if (!this._reports[id]) {
this._reports[id] = new Report(suiteOrTest.remote && suiteOrTest.remote.environmentType);
}
return this._reports[id];
};
Pretty.prototype._newCharm = function () {
var c = charm_1.default();
c.pipe(common_1.global.process.stdout);
return c;
};
Pretty.prototype._record = function (suiteOrTest, result, count) {
if (count === void 0) { count = 1; }
var report = this._reports[suiteOrTest.sessionId];
this._total.record(result, count);
if (report) {
report.record(result, count);
var suiteInfo = report.suiteInfo;
var info = suiteInfo[suiteOrTest.id];
if (!info && suiteOrTest.parentId) {
info = suiteInfo[suiteOrTest.parentId];
}
while (info) {
info.numToReport -= count;
if (info.parentId) {
info = suiteInfo[info.parentId];
}
else {
info = undefined;
}
}
}
};
Pretty.prototype._drawProgressBar = function (report, width) {
var _this = this;
var spinnerCharacter = SPINNER_STATES[this._spinnerOffset];
var charm = this._charm;
if (!report.numTotal) {
charm.write('Pending');
return;
}
var totalTextSize = String(report.numTotal).length;
var remainingWidth = Math.max(width - 4 - totalTextSize * 2, 1);
var barSize = Math.min(remainingWidth, report.numTotal, this.maxProgressBarWidth);
var results = report.getCompressedResults(barSize);
charm.write('[');
results.forEach(function (value) {
var color = _this._getColor(value);
if (color == null) {
charm.display('reset');
}
else {
charm.foreground(color);
}
charm.write(symbols[value]);
});
charm.display('reset');
charm.write(fit(spinnerCharacter, barSize - results.length) +
'] ' +
fit(report.finished, totalTextSize, true) +
'/' +
report.numTotal);
};
Pretty.prototype._drawSessionReport = function (report) {
var charm = this._charm;
var titleWidth = this.titleWidth;
var leftOfBar = fit(this._abbreviateEnvironment(report.environment).slice(0, titleWidth - 2) +
': ', titleWidth);
var rightOfBar = '' +
(report.numFailed ? ', ' + report.numFailed + ' fail' : '') +
(report.numSkipped ? ', ' + report.numSkipped + ' skip' : '');
var barWidth = this.dimensions.width - rightOfBar.length - titleWidth;
charm.write(leftOfBar);
this._drawProgressBar(report, barWidth);
charm.write(rightOfBar + '\n');
};
Pretty.prototype._abbreviateEnvironment = function (env) {
var browser = BROWSERS[env.browserName.toLowerCase()] ||
env.browserName.slice(0, 4);
var result = [browser];
if (env.version) {
var version = String(env.version);
if (version.indexOf('.') > -1) {
version = version.slice(0, version.indexOf('.'));
}
result.push(version);
}
if (env.platform) {
result.push(env.platform.slice(0, 3));
}
return result.join(' ');
};
Pretty.prototype._render = function (omitLogs) {
var _this = this;
if (omitLogs === void 0) { omitLogs = false; }
var charm = this._charm;
var numReports = Object.keys(this._reports).length;
var logLength = this.dimensions.height -
numReports -
4 -
(this.tunnelState ? 2 : 0) -
(numReports ? 1 : 0) -
(this._header ? 1 : 0);
this._spinnerOffset = ++this._spinnerOffset % SPINNER_STATES.length;
charm.display('reset');
if (this._header) {
charm.display('bright');
charm.write(this._header + '\n');
charm.display('reset');
}
this.tunnelState && charm.write('Tunnel: ' + this.tunnelState + '\n\n');
this._drawTotalReport(this._total);
if (numReports) {
charm.write('\n');
for (var key in this._reports) {
this._drawSessionReport(this._reports[key]);
}
}
if (!omitLogs && logLength > 0 && this._log.length) {
var allowed_1 = { '×': true, '⚠': true, '!': true };
charm.write('\n');
this._log
.filter(function (line) {
return allowed_1[line.charAt(0)];
})
.slice(-logLength)
.forEach(function (line) {
var color = _this._getColor(line);
if (color) {
charm.foreground(color);
}
line = line.split('\n', 1)[0];
charm.write(line.slice(0, _this.dimensions.width) + "\n");
charm.display('reset');
});
}
};
Pretty.prototype._drawTotalReport = function (report) {
var charm = this._charm;
var title = 'Total: ';
var totalTextSize = String(report.numTotal).length;
charm.write(title);
this._drawProgressBar(report, this.dimensions.width - title.length);
charm.write(util_1.format('\nPassed: %s Failed: %s Skipped: %d\n', fit(report.numPassed, totalTextSize), fit(report.numFailed, totalTextSize), report.numSkipped));
};
Pretty.prototype._getColor = function (value) {
if (typeof value === 'string') {
value = value[0];
}
return this.colorReplacement[value] || null;
};
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "runStart", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "runEnd", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "coverage", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "suiteStart", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "suiteEnd", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "testEnd", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "tunnelDownloadProgress", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "tunnelStatus", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "error", null);
tslib_1.__decorate([
eventHandler()
], Pretty.prototype, "deprecated", null);
return Pretty;
}(TextCoverage_1.default));
exports.default = Pretty;
var Report = (function () {
function Report(environment, sessionId) {
this.numTotal = 0;
this.numPassed = 0;
this.numFailed = 0;
this.numSkipped = 0;
this.results = [];
this.environment = environment;
this.sessionId = sessionId;
this.coverageMap = istanbul_lib_coverage_1.createCoverageMap();
this.suiteInfo = {};
}
Object.defineProperty(Report.prototype, "finished", {
get: function () {
return this.results.length;
},
enumerable: false,
configurable: true
});
Report.prototype.record = function (result, count) {
if (count === void 0) { count = 1; }
for (var i = 0; i < count; i++) {
this.results.push(result);
}
switch (result) {
case Result.PASS:
this.numPassed += count;
break;
case Result.SKIP:
this.numSkipped += count;
break;
case Result.FAIL:
this.numFailed += count;
break;
}
};
Report.prototype.getCompressedResults = function (maxWidth) {
var total = Math.max(this.numTotal, this.results.length);
var width = Math.min(maxWidth, total);
var resultList = [];
for (var i = 0; i < this.results.length; ++i) {
var pos = Math.floor((i / total) * width);
resultList[pos] = Math.max(resultList[pos] || Result.PASS, this.results[i]);
}
return resultList;
};
return Report;
}());
exports.Report = Report;
var Result;
(function (Result) {
Result[Result["PASS"] = 0] = "PASS";
Result[Result["SKIP"] = 1] = "SKIP";
Result[Result["FAIL"] = 2] = "FAIL";
})(Result = exports.Result || (exports.Result = {}));
var symbols = ['✓', '~', '×'];
var PAD = new Array(100).join(' ');
var SPINNER_STATES = ['/', '-', '\\', '|'];
var BROWSERS = {
chrome: 'Chr',
firefox: 'Fx',
opera: 'O',
safari: 'Saf',
'internet explorer': 'IE',
phantomjs: 'Phan',
};
function pad(width) {
return PAD.slice(0, Math.max(width, 0));
}
function fit(text, width, padLeft) {
if (padLeft === void 0) { padLeft = false; }
text = String(text);
if (text.length < width) {
if (padLeft) {
return pad(width - text.length) + text;
}
return text + pad(width - text.length);
}
return text.slice(0, width);
}
});
//# sourceMappingURL=Pretty.js.map