UNPKG

cypress-terminal-report

Version:

Better terminal and file output for cypress test logs.

201 lines (200 loc) 7.34 kB
"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;