UNPKG

jest-allure2-reporter

Version:
253 lines 11.7 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.JestAllure2Reporter = void 0; const tslib_1 = require("tslib"); const node_path_1 = tslib_1.__importDefault(require("node:path")); const reporter_1 = tslib_1.__importDefault(require("jest-metadata/reporter")); const options_1 = require("../options"); const metadata_1 = require("../metadata"); const utils_1 = require("../utils"); const logger_1 = require("../logger"); const fallbacks = tslib_1.__importStar(require("./fallbacks")); const postProcessMetadata_1 = require("./postProcessMetadata"); const allureCommons_1 = require("./allureCommons"); const resolveTestItem_1 = require("./resolveTestItem"); const NOT_INITIALIZED = null; const __TID = (0, logger_1.optimizeForTracing)((test) => ({ tid: ['jest-allure2-reporter', test ? test.path : 'run'], })); const __TID_NAME = (0, logger_1.optimizeForTracing)((test, testCaseResult) => ({ tid: ['jest-allure2-reporter', test.path], fullName: testCaseResult.fullName, })); class JestAllure2Reporter extends reporter_1.default { _globalConfig; _options; _globalContext = NOT_INITIALIZED; _writer = NOT_INITIALIZED; _config = NOT_INITIALIZED; _globalMetadataProxy = NOT_INITIALIZED; _taskQueue = new utils_1.DeferredTaskQueue({ getThreadName: (item) => item.test.path, getPayloadKey: (item) => item.testInvocationMetadata, execute: (item) => logger_1.log.trace.complete(__TID_NAME(item.test, item.testCaseResult), item.testCaseResult.title, () => this.#writeTestResult(item)), }); constructor(globalConfig, options) { super(globalConfig); this._globalConfig = globalConfig; this._options = options; } async #init() { this._config = await (0, options_1.resolveOptions)(this._globalConfig.rootDir, this._options); this._writer = await (0, options_1.resolveWriter)(this._globalConfig.rootDir, this._config); await this._writer.init?.(); const testRunMetadata = _a.query.globalMetadata(); this._globalMetadataProxy = new metadata_1.AllureMetadataProxy(testRunMetadata); this._globalMetadataProxy.set('config', { resultsDir: this._config.resultsDir, overwrite: this._config.overwrite, attachments: this._config.attachments, injectGlobals: this._config.injectGlobals, }); } async #attempt(name, function_) { try { await function_.call(this); } catch (error) { logger_1.log.error(error, `Caught unhandled error in JestAllure2Reporter#${name}`); } } async #attemptSync(name, function_) { try { function_.call(this); } catch (error) { logger_1.log.error(error, `Caught unhandled error in JestAllure2Reporter#${name}`); } } async onRunStart(aggregatedResult, options) { await super.onRunStart(aggregatedResult, options); const attemptRunStart = this.#attempt.bind(this, 'onRunStart()', this.#onRunStart); logger_1.log.trace.begin(__TID(), 'jest-allure2-reporter'); await logger_1.log.trace.complete(__TID(), 'init', this.#init.bind(this)); await logger_1.log.trace.complete(__TID(), 'onRunStart', attemptRunStart); } async #onRunStart() { const reporterConfig = this._config; const allureWriter = this._writer; const globalContext = { $: {}, globalConfig: this._globalConfig, reporterConfig, value: undefined, }; globalContext.$ = await (0, resolveTestItem_1.resolvePromisedItem)(globalContext, reporterConfig.helpers, '$'); if (reporterConfig.sourceCode.enabled) { const { factories, options, plugins } = reporterConfig.sourceCode; const maybePlugins = await Promise.all(Object.entries(factories).map(async ([key, factory]) => factory({ ...globalContext, value: options[key], }))); plugins.push(...(0, utils_1.compactArray)(maybePlugins)); } this._globalContext = globalContext; const environment = await reporterConfig.environment(globalContext); if (environment) { await allureWriter.writeEnvironmentInfo((0, utils_1.stringifyValues)(environment)); } const executor = await reporterConfig.executor(globalContext); if (executor) { await allureWriter.writeExecutorInfo(executor); } const categories = await reporterConfig.categories(globalContext); if (categories) { await allureWriter.writeCategories(categories); } } async onTestFileStart(test) { super.onTestFileStart(test); const execute = this.#onTestFileStart.bind(this, test); const attempt = this.#attemptSync.bind(this, 'onTestFileStart()', execute); const testPath = node_path_1.default.relative(this._globalConfig.rootDir, test.path); logger_1.log.trace.begin(__TID(test), testPath); await logger_1.log.trace.complete(__TID(test), 'onTestFileStart', attempt); } async #onTestFileStart(test) { await utils_1.FileNavigatorCache.instance.scanSourcemap(test.path); const rawMetadata = _a.query.test(test); const testFileMetadata = new metadata_1.AllureMetadataProxy(rawMetadata); fallbacks.onTestFileStart(test, testFileMetadata); } onTestCaseStart(test, testCaseResult) { super.onTestCaseStart(test, testCaseResult); this._taskQueue.startPending(test.path); } onTestCaseResult(test, testCaseResult) { super.onTestCaseResult(test, testCaseResult); const testEntryMetadata = _a.query.testCaseResult(testCaseResult); const testInvocationMetadata = testEntryMetadata.lastInvocation; fallbacks.onTestCaseResult(test, testCaseResult, new metadata_1.AllureMetadataProxy(testInvocationMetadata)); this._taskQueue.enqueue({ test, testCaseResult, testInvocationMetadata, }); } async #writeTestResult({ test, testCaseResult, testInvocationMetadata }) { await this.#scanSourceMaps(test.path); await (0, postProcessMetadata_1.postProcessMetadata)(this._globalContext, testInvocationMetadata); const squasher = new metadata_1.MetadataSquasher(); const testCaseContext = { ...this._globalContext, filePath: node_path_1.default.relative(this._globalConfig.rootDir, test.path).split(node_path_1.default.sep), result: {}, testCase: testCaseResult, testCaseMetadata: squasher.testInvocation(testInvocationMetadata), testFileMetadata: squasher.testFile(testInvocationMetadata.file), testRunMetadata: this._globalMetadataProxy.get(), value: undefined, }; const allureTest = await (0, resolveTestItem_1.resolvePromisedTestCase)(testCaseContext, this._config.testCase); if (!allureTest) { return; } const invocationIndex = testInvocationMetadata.definition.invocations.indexOf(testInvocationMetadata); await (0, allureCommons_1.writeTest)({ resultsDir: this._config.resultsDir, containerName: `${testCaseResult.fullName} (${invocationIndex})`, writer: this._writer, test: allureTest, }); } async onTestFileResult(test, testResult, aggregatedResult) { super.onTestFileResult(test, testResult, aggregatedResult); const execute = this.#onTestFileResult.bind(this, test, testResult); const attempt = this.#attempt.bind(this, 'onTestFileResult()', execute); await logger_1.log.trace.complete(__TID(test), 'onTestFileResult', attempt); logger_1.log.trace.end(__TID(test)); } async #onTestFileResult(test, testResult) { const rawMetadata = _a.query.test(test); const testFileMetadata = new metadata_1.AllureMetadataProxy(rawMetadata); fallbacks.onTestFileResult(test, testFileMetadata); for (const testCaseResult of testResult.testResults) { const invocations = _a.query.testCaseResult(testCaseResult).invocations || []; for (const testInvocationMetadata of invocations) { this._taskQueue.enqueue({ test, testCaseResult, testInvocationMetadata, }); } } await this._taskQueue.awaitCompletion(); const config = this._config; const squasher = new metadata_1.MetadataSquasher(); const globalMetadataProxy = this._globalMetadataProxy; const testFileContext = { ...this._globalContext, filePath: node_path_1.default.relative(this._globalConfig.rootDir, testResult.testFilePath).split(node_path_1.default.sep), result: {}, testFile: testResult, testFileMetadata: squasher.testFile(_a.query.testResult(testResult)), testRunMetadata: globalMetadataProxy.get(), value: undefined, }; const allureFileTest = await (0, resolveTestItem_1.resolvePromisedTestCase)(testFileContext, config.testFile); if (allureFileTest) { await (0, allureCommons_1.writeTest)({ resultsDir: config.resultsDir, containerName: `${testResult.testFilePath}`, writer: this._writer, test: allureFileTest, }); } } async onRunComplete(testContexts, aggregatedResult) { await super.onRunComplete(testContexts, aggregatedResult); const execute = this.#onRunComplete.bind(this, aggregatedResult); const attempt = this.#attempt.bind(this, 'onRunComplete()', execute); await logger_1.log.trace.complete(__TID(), 'onRunComplete', attempt); await logger_1.log.trace.end(__TID()); } async #onRunComplete(aggregatedResult) { const globalMetadataProxy = this._globalMetadataProxy; globalMetadataProxy.set('stop', Date.now()); const allureWriter = this._writer; const config = this._config; const globalContext = this._globalContext; const testRunContext = { ...globalContext, aggregatedResult, result: {}, testRunMetadata: globalMetadataProxy.get(), value: undefined, }; const allureRunTest = await (0, resolveTestItem_1.resolvePromisedTestCase)(testRunContext, config.testRun); if (allureRunTest) { await (0, allureCommons_1.writeTest)({ resultsDir: config.resultsDir, containerName: `Test Run (${process.pid})`, writer: allureWriter, test: allureRunTest, }); } await allureWriter.cleanup?.(); } // Executing this once per file should be enough to scan source maps of auxiliary files #scanSourceMaps = (0, utils_1.memoize)(async (_testPath) => { const globalMetadataProxy = this._globalMetadataProxy; const loadedFiles = globalMetadataProxy .get('loadedFiles', []) .filter(utils_1.FileNavigatorCache.instance.hasScannedSourcemap); if (loadedFiles.length === 0) { return; } return Promise.all(loadedFiles.map(utils_1.FileNavigatorCache.instance.scanSourcemap)); }); } exports.JestAllure2Reporter = JestAllure2Reporter; _a = JestAllure2Reporter; //# sourceMappingURL=JestAllure2Reporter.js.map