creevey
Version:
Cross-browser screenshot testing tool for Storybook with fancy UI Runner
124 lines (96 loc) • 5.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.TeamcityReporter = exports.CreeveyReporter = void 0;
var _chalk = _interopRequireDefault(require("chalk"));
var _mocha = require("mocha");
var _loglevelPluginPrefix = _interopRequireDefault(require("loglevel-plugin-prefix"));
var _types = require("../../types");
var _logger = require("../logger");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const testLevels = {
INFO: _chalk.default.green('PASS'),
WARN: _chalk.default.yellow('START'),
ERROR: _chalk.default.red('FAIL')
};
class CreeveyReporter extends _mocha.reporters.Base {
constructor(runner, options) {
super(runner);
const {
sessionId,
topLevelSuite
} = options.reporterOptions;
const testLogger = (0, _logger.getLogger)(topLevelSuite);
_loglevelPluginPrefix.default.apply(testLogger, {
format(level) {
return `${testLevels[level]} => (${topLevelSuite}:${_chalk.default.gray(sessionId)})`;
}
});
runner.on('test', test => testLogger.warn(_chalk.default.cyan(test.titlePath().join('/'))));
runner.on('pass', test => testLogger.info(_chalk.default.cyan(test.titlePath().join('/'))));
runner.on('fail', (test, error) => testLogger.error(_chalk.default.cyan(test.titlePath().join('/')), '\n ', getErrors(error, (error, imageName) => `${_chalk.default.bold(imageName !== null && imageName !== void 0 ? imageName : topLevelSuite)}:${error}`, error => {
var _error$stack;
return `${(_error$stack = error.stack) !== null && _error$stack !== void 0 ? _error$stack : error.message}`;
}).join('\n ')));
}
}
exports.CreeveyReporter = CreeveyReporter;
class TeamcityReporter extends _mocha.reporters.Base {
constructor(runner, options) {
super(runner);
_defineProperty(this, "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, "|'");
});
const topLevelSuite = this.escape(options.reporterOptions.topLevelSuite);
const {
reportDir,
willRetry,
images
} = options.reporterOptions;
runner.on('suite', suite => suite.root ? console.log(`##teamcity[testSuiteStarted name='${topLevelSuite}' flowId='${process.pid}']`) : 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) => {
var _error$stack2;
Object.entries(images).forEach(([name, image]) => {
if (!image) return;
const filePath = test.titlePath().concat(name == topLevelSuite ? [] : [topLevelSuite]).map(this.escape).join('/'); // eslint-disable-next-line @typescript-eslint/no-unused-vars
const {
error,
...rest
} = image;
Object.values(rest).filter(_types.isDefined).forEach(fileName => {
console.log(`##teamcity[publishArtifacts '${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
willRetry ? console.log(`##teamcity[testFinished name='${this.escape(test.title)}' flowId='${process.pid}']`) : console.log(`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape(error.message)}' details='${this.escape((_error$stack2 = error.stack) !== null && _error$stack2 !== void 0 ? _error$stack2 : '')}' 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 => 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}']`));
}
}
exports.TeamcityReporter = TeamcityReporter;
function getErrors(error, imageErrorToString, errorToString) {
const errors = [];
if (!(error instanceof Error)) {
errors.push(error);
} else if (!(0, _types.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 => {
var _imageErrors$imageNam;
errors.push(imageErrorToString((_imageErrors$imageNam = imageErrors[imageName]) !== null && _imageErrors$imageNam !== void 0 ? _imageErrors$imageNam : '', imageName));
});
}
return errors;
}