UNPKG

@testomatio/reporter

Version:
128 lines (124 loc) 4.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.stripColors = void 0; exports.formatLogs = formatLogs; exports.formatError = formatError; const callsite_record_1 = __importDefault(require("callsite-record")); const minimatch_1 = require("minimatch"); const picocolors_1 = __importDefault(require("picocolors")); const util_1 = require("util"); const path_1 = require("path"); const utils_js_1 = require("./utils.js"); const stripColors = util_1.stripVTControlCharacters || (str => str?.replace(/\x1b\[[0-9;]*m/g, '') || ''); exports.stripColors = stripColors; /** * Returns the formatted stack including the stack trace, steps, and logs. * @param {Object} params - Parameters for formatting logs * @param {string} params.error - Error message * @param {Array|any} params.steps - Test steps (array or other types) * @param {string} params.logs - Test logs * @returns {string} */ function formatLogs({ error, steps, logs }) { error = error?.trim(); logs = logs ?.trim() .split('\n') .map(l => (0, utils_js_1.truncate)(l)) .join('\n'); if (Array.isArray(steps)) { steps = steps .map(step => (0, utils_js_1.formatStep)(step)) .flat() .join('\n'); } else { steps = null; } let testLogs = ''; if (steps) testLogs += `${picocolors_1.default.bold(picocolors_1.default.blue('################[ Steps ]################'))}\n${steps}\n\n`; if (logs) testLogs += `${picocolors_1.default.bold(picocolors_1.default.gray('################[ Logs ]################'))}\n${logs}\n\n`; if (error) testLogs += `${picocolors_1.default.bold(picocolors_1.default.red('################[ Failure ]################'))}\n${error}`; return testLogs; } /** * Formats an error with stack trace and diff information * @param {Error & {inspect?: () => string, operator?: string, diff?: string, actual?: any, expected?: any}} error * The error object to format * @param {string} [message] - Optional error message override * @returns {string} */ function formatError(error, message) { if (!message) message = error.message; // @ts-ignore - inspect is a custom property added by some testing frameworks if (error.inspect) message = error.inspect() || ''; let stack = ''; if (error.name) stack += `${picocolors_1.default.red(error.name)}`; // @ts-ignore - operator is a custom property added by assertion libraries if (error.operator) stack += ` (${picocolors_1.default.red(error.operator)})`; // add new line if something was added to stack if (stack) stack += ': '; stack += `${message}\n`; // @ts-ignore - diff is a custom property added by vitest if (error.diff) { // diff for vitest stack += error.diff; stack += '\n\n'; } else if (error.actual && error.expected && error.actual !== error.expected) { // diffs for mocha, cypress, codeceptjs style stack += `\n\n${picocolors_1.default.bold(picocolors_1.default.green('+ expected'))} ${picocolors_1.default.bold(picocolors_1.default.red('- actual'))}`; stack += `\n${picocolors_1.default.green(`+ ${error.expected.toString().split('\n').join('\n+ ')}`)}`; stack += `\n${picocolors_1.default.red(`- ${error.actual.toString().split('\n').join('\n- ')}`)}`; stack += '\n\n'; } const customFilter = process.env.TESTOMATIO_STACK_IGNORE; try { let hasFrame = false; const record = (0, callsite_record_1.default)({ forError: error, isCallsiteFrame: frame => { if (customFilter && (0, minimatch_1.minimatch)(frame.fileName, customFilter)) return false; if (hasFrame) return false; if (isNotInternalFrame(frame)) hasFrame = true; return hasFrame; }, }); // @ts-ignore if (record && !record.filename.startsWith('http')) { stack += record.renderSync({ stackFilter: isNotInternalFrame }); } return stack; } catch (e) { console.log(e); } } /** * Checks if a stack frame is not an internal frame (node_modules or internal) * @param {Object} frame - Stack frame object * @returns {boolean} */ function isNotInternalFrame(frame) { return (frame.getFileName() && frame.getFileName().includes(path_1.sep) && !frame.getFileName().includes('node_modules') && !frame.getFileName().includes('internal')); } module.exports.formatLogs = formatLogs; module.exports.formatError = formatError; module.exports.stripColors = stripColors;