UNPKG

creevey

Version:

Cross-browser screenshot testing tool for Storybook with fancy UI Runner

130 lines 6.19 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TeamcityReporter = exports.CreeveyReporter = void 0; const chalk_1 = __importDefault(require("chalk")); const loglevel_1 = __importDefault(require("loglevel")); const loglevel_plugin_prefix_1 = __importDefault(require("loglevel-plugin-prefix")); const mocha_1 = require("mocha"); const types_js_1 = require("../../types.js"); const testLevels = { INFO: chalk_1.default.green('PASS'), WARN: chalk_1.default.yellow('START'), ERROR: chalk_1.default.red('FAIL'), }; class CreeveyReporter extends mocha_1.reporters.Base { // TODO Output in better way, like vitest, maybe constructor(runner, options) { super(runner); const { sessionId, topLevelSuite } = options.reporterOptions; const testLogger = loglevel_1.default.getLogger(sessionId); loglevel_plugin_prefix_1.default.apply(testLogger, { format(level) { return `[${topLevelSuite}:${chalk_1.default.gray(process.pid)}] ${testLevels[level]} => ${chalk_1.default.gray(sessionId)}`; }, }); runner.on('test', (test) => { testLogger.warn(chalk_1.default.cyan(test.titlePath().join('/'))); }); runner.on('pass', (test) => { testLogger.info(chalk_1.default.cyan(test.titlePath().join('/'))); }); runner.on('fail', (test, error) => { testLogger.error(chalk_1.default.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${chalk_1.default.bold(imageName ?? topLevelSuite)}:${error}`, (error) => error.stack ?? error.message).join('\n ')); }); } } exports.CreeveyReporter = CreeveyReporter; class TeamcityReporter extends mocha_1.reporters.Base { constructor(runner, options) { super(runner); const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite); const reporterOptions = options.reporterOptions; runner.on('suite', (suite) => { if (suite.root) console.log(`##teamcity[testSuiteStarted name='${topLevelSuite}' flowId='${process.pid}']`); else console.log(`##teamcity[testSuiteStarted name='${this.escape(suite.title)}' flowId='${process.pid}']`); }); runner.on('test', (test) => { console.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${process.pid}']`); }); runner.on('fail', (test, error) => { Object.entries(reporterOptions.images).forEach(([name, image]) => { if (!image) return; const filePath = test .titlePath() .concat(name == topLevelSuite ? [] : [topLevelSuite]) .map(this.escape) .join('/'); const { error: _, ...rest } = image; Object.values(rest) .filter(types_js_1.isDefined) .forEach((fileName) => { console.log(`##teamcity[publishArtifacts '${reporterOptions.reportDir}/${filePath}/${fileName} => report/${filePath}']`); console.log(`##teamcity[testMetadata testName='${this.escape(test.title)}' type='image' value='report/${filePath}/${fileName}' flowId='${process.pid}']`); }); }); // Output failed test as passed due TC don't support retry mechanic // https://teamcity-support.jetbrains.com/hc/en-us/community/posts/207216829-Count-test-as-successful-if-at-least-one-try-is-successful?page=1#community_comment_207394125 if (reporterOptions.willRetry) console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`); else console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape(error.stack ?? '')}' flowId='${process.pid}']`); }); runner.on('pending', (test) => { console.log(`##teamcity[testIgnored name='${this.escape(test.title)}' message='${this.escape(typeof test.skipReason == 'boolean' ? test.title : test.skipReason)}' flowId='${process.pid}']`); }); runner.on('test end', (test) => { console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`); }); runner.on('suite end', (suite) => { if (!suite.root) console.log(`##teamcity[testSuiteFinished name='${this.escape(suite.title)}' flowId='${process.pid}']`); }); runner.on('end', () => { console.log(`##teamcity[testSuiteFinished name='${topLevelSuite}' flowId='${process.pid}']`); }); } escape = (str) => { if (!str) return ''; return (str .toString() // eslint-disable-next-line no-control-regex .replace(/\x1B.*?m/g, '') .replace(/\|/g, '||') .replace(/\n/g, '|n') .replace(/\r/g, '|r') .replace(/\[/g, '|[') .replace(/\]/g, '|]') .replace(/\u0085/g, '|x') .replace(/\u2028/g, '|l') .replace(/\u2029/g, '|p') .replace(/'/g, "|'")); }; } exports.TeamcityReporter = TeamcityReporter; function getErrors(error, imageErrorToString, errorToString) { const errors = []; if (!(error instanceof Error)) { errors.push(error); } else if (!(0, types_js_1.isImageError)(error)) { errors.push(errorToString(error)); } else if (typeof error.images == 'string') { errors.push(imageErrorToString(error.images)); } else { const imageErrors = error.images; Object.keys(imageErrors).forEach((imageName) => { errors.push(imageErrorToString(imageErrors[imageName] ?? '', imageName)); }); } return errors; } //# sourceMappingURL=reporter.js.map