cypress-terminal-report
Version:
Better terminal and file output for cypress test logs.
201 lines (200 loc) • 7.34 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const constants_1 = __importDefault(require("../constants"));
class LogCollectorState extends EventTarget {
constructor(config) {
super();
this.config = config;
this.logProcessors = [];
this.listeners = {};
// @ts-ignore gets initialized to the correct state anyways
this.currentTest = null;
this.logStacks = [];
this.beforeHookIndexes = [];
this.afterHookIndexes = [];
this.isStrict = false;
this.suiteStartTime = null;
if (this.config.commandTimings == 'timestamp') {
this.logProcessors.push((log) => {
log.timeString = Date.now() + '';
});
}
else if (this.config.commandTimings == 'seconds') {
this.logProcessors.push((log) => {
var _a;
log.timeString = (Date.now() - (((_a = this.suiteStartTime) === null || _a === void 0 ? void 0 : _a.getTime()) || 0)) / 1000 + 's';
});
}
if (Cypress.config('isInteractive')) {
Cypress.mocha.getRunner().on('suite end', () => {
const currentLength = this.logStacks.length;
setTimeout(() => {
this.cleanup(currentLength);
}, 10000);
});
}
}
setStrict() {
this.isStrict = true;
}
addNewLogStack() {
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX + 'adding new log stack, new size ' + (this.logStacks.length + 1));
}
this.logStacks.push([]);
}
ensureLogStack() {
if (!this.hasLogsInCurrentStack()) {
this.addNewLogStack();
}
}
getCurrentLogStackIndex() {
return this.logStacks.length - 1;
}
getCurrentLogStack() {
return this.logStacks[this.getCurrentLogStackIndex()];
}
consumeLogStacks(index) {
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX + 'consuming log stack at ' + index);
}
const stack = this.logStacks[index];
stack === null || stack === void 0 ? void 0 : stack.forEach((log) => {
delete log.chainId;
});
this.logStacks[index] = null;
return stack;
}
hasLogsInCurrentStack() {
var _a;
return this.getCurrentLogStack() && !!((_a = this.getCurrentLogStack()) === null || _a === void 0 ? void 0 : _a.length);
}
getCurrentTest() {
// @TODO: The alternative is to prevent issues with multi domain tests.
// This is probably not a final and proof solution. All context is lost as cypress
// reloads the whole window and all state data is lost.
return this.currentTest || Cypress.mocha.getRunner().currentRunnable;
}
trimMessage(msg) {
var _a;
const maxLen = (_a = this.config.maxLogLength) !== null && _a !== void 0 ? _a : 15000;
if (typeof msg !== 'string')
return msg;
if (maxLen > 0 && msg.length > maxLen) {
const trimmedCount = msg.length - maxLen;
const suffix = ` ... [${trimmedCount} chars trimmed]`;
const sliceLen = Math.max(0, maxLen - suffix.length);
return msg.substring(0, sliceLen) + suffix;
}
return msg;
}
addLog(entry, chainId) {
const currentStack = this.getCurrentLogStack();
if (!currentStack) {
if (this.isStrict) {
console.warn('cypress-terminal-report: Attempted to collect logs while no stack was defined.');
}
return;
}
const structuredEntry = {
type: entry[0],
message: this.trimMessage(entry[1]),
severity: entry[2] || constants_1.default.SEVERITY.SUCCESS,
chainId,
};
this.logProcessors.forEach((processor) => processor(structuredEntry));
currentStack.push(structuredEntry);
this.dispatchEvent(new Event('log'));
}
updateLog(log, severity, id) {
const entry = this.findReversed(id);
if (entry) {
entry.message = this.trimMessage(log);
entry.severity = severity;
}
this.dispatchEvent(new Event('log'));
}
updateLogStatus(id, state = constants_1.default.SEVERITY.ERROR) {
const entry = this.findReversed(id);
if (entry) {
entry.severity = state;
}
}
findReversed(id) {
if (!id) {
return null;
}
for (let i = this.logStacks.length - 1; i >= 0; i--) {
const logStack = this.logStacks[i];
if (logStack) {
for (let j = logStack.length - 1; j >= 0; j--) {
if (logStack[j].chainId === id) {
return logStack[j];
}
}
}
}
return null;
}
markCurrentStackFromBeforeEach() {
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX +
'current log stack is before each at ' +
this.getCurrentLogStackIndex());
}
let stack = this.getCurrentLogStack();
if (stack) {
stack._ctr_before_each = 1;
}
}
incrementBeforeHookIndex() {
++this.beforeHookIndexes[0];
}
incrementAfterHookIndex() {
++this.afterHookIndexes[0];
}
getBeforeHookTestTile() {
return constants_1.default.HOOK_TITLES.BEFORE.replace('{index}', `#${this.beforeHookIndexes[0]}`);
}
getAfterHookTestTile() {
return constants_1.default.HOOK_TITLES.AFTER.replace('{index}', `#${this.afterHookIndexes[0]}`);
}
startSuite() {
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX + 'starting suite');
}
this.suiteStartTime = new Date();
this.beforeHookIndexes.unshift(0);
this.afterHookIndexes.unshift(0);
}
endSuite() {
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX + 'ending suite');
}
this.beforeHookIndexes.shift();
this.afterHookIndexes.shift();
}
startTest(test) {
var _a;
if (this.config.debug) {
console.log(constants_1.default.DEBUG_LOG_PREFIX + 'starting test: ' + test.title);
}
this.currentTest = test;
this.addNewLogStack();
const currentIndex = this.getCurrentLogStackIndex();
const previousIndex = currentIndex - 1;
// Merge together before each log.
if (((_a = this.logStacks[currentIndex]) === null || _a === void 0 ? void 0 : _a._ctr_before_each) && this.logStacks[previousIndex]) {
this.logStacks[currentIndex] = this.logStacks[previousIndex].concat(this.logStacks[currentIndex]);
}
}
cleanup(beforeIndex) {
for (let i = 0; i < beforeIndex && i < this.logStacks.length; i++) {
this.logStacks[i] = null;
}
}
}
exports.default = LogCollectorState;