UNPKG

allure-jest

Version:
364 lines (360 loc) 16.3 kB
var _excluded = ["resultsDir"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; } function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; } function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); } function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } import { relative, sep } from "node:path"; import { env } from "node:process"; import * as allure from "allure-js-commons"; import { Stage, Status } from "allure-js-commons"; import { serialize } from "allure-js-commons/sdk"; import { extractMetadataFromString, getMessageAndTraceFromError, getStatusFromError } from "allure-js-commons/sdk"; import { ReporterRuntime, createDefaultWriter, getEnvironmentLabels, getFrameworkLabel, getHostLabel, getLanguageLabel, getPackageLabel, getPosixPath, getSuiteLabels, getThreadLabel, parseTestPlan } from "allure-js-commons/sdk/reporter"; import { setGlobalTestRuntime } from "allure-js-commons/sdk/runtime"; import { AllureJestTestRuntime } from "./AllureJestTestRuntime.js"; import { getTestId, getTestPath, isTestPresentInTestPlan, last, shouldHookBeSkipped } from "./utils.js"; var createJestEnvironment = Base => { var _Class_brand; // @ts-expect-error (ts(2545)) Incorrect assumption about a mixin class: https://github.com/microsoft/TypeScript/issues/37142 return _Class_brand = /*#__PURE__*/new WeakSet(), class extends Base { // config is AllureJestConfig in Jest v28 or greater. In older versions // it's AllureJestProjectConfig. See https://github.com/jestjs/jest/pull/12461 constructor(config, context) { super(config, context); _classPrivateMethodInitSpec(this, _Class_brand); _defineProperty(this, "testPath", void 0); _defineProperty(this, "testPlan", void 0); _defineProperty(this, "runtime", void 0); _defineProperty(this, "runContext", { executables: [], steps: [], scopes: [], skippedTestsFullNamesByTestPlan: [] }); _defineProperty(this, "handleTestEvent", event => { switch (event.name) { case "hook_start": _assertClassBrand(_Class_brand, this, _handleHookStart).call(this, event.hook); break; case "hook_success": _assertClassBrand(_Class_brand, this, _handleHookPass).call(this, event.hook); break; case "hook_failure": _assertClassBrand(_Class_brand, this, _handleHookFail).call(this, event.hook, event.error); break; case "run_describe_start": _assertClassBrand(_Class_brand, this, _handleSuiteStart).call(this); break; case "run_describe_finish": _assertClassBrand(_Class_brand, this, _handleSuiteEnd).call(this); break; case "test_start": _assertClassBrand(_Class_brand, this, _handleTestScopeStart).call(this); break; case "test_fn_start": _assertClassBrand(_Class_brand, this, _handleTestStart).call(this, event.test); break; case "test_fn_success": _assertClassBrand(_Class_brand, this, _handleTestPass).call(this, event.test); break; case "test_fn_failure": _assertClassBrand(_Class_brand, this, _handleTestFail).call(this, event.test); break; case "test_done": _assertClassBrand(_Class_brand, this, _handleTestScopeStop).call(this, event.test); break; case "test_skip": _assertClassBrand(_Class_brand, this, _handleTestSkip).call(this, event.test); break; case "test_todo": _assertClassBrand(_Class_brand, this, _handleTestTodo).call(this, event.test); break; case "run_finish": _assertClassBrand(_Class_brand, this, _handleRunFinish).call(this); break; default: break; } }); var projectConfig = "projectConfig" in config ? config.projectConfig : config; var _ref = (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.testEnvironmentOptions) || {}, { resultsDir } = _ref, restConfig = _objectWithoutProperties(_ref, _excluded); this.runtime = new ReporterRuntime(_objectSpread(_objectSpread({}, restConfig), {}, { writer: createDefaultWriter({ resultsDir }) })); this.testPath = relative(projectConfig.rootDir, context.testPath); this.testPlan = parseTestPlan(); // @ts-ignore var testRuntime = new AllureJestTestRuntime(this, this.global); // @ts-ignore this.global.allure = allure; setGlobalTestRuntime(testRuntime); } setup() { return super.setup(); } teardown() { return super.teardown(); } handleAllureRuntimeMessage(message) { var executableUuid = last(this.runContext.executables); this.runtime.applyRuntimeMessages(executableUuid, [message]); } }; function _getTestFullName(test) { var testTitle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : test.name; var newTestSuitePath = getTestPath(test.parent); var newTestPath = newTestSuitePath.concat(testTitle); var newTestId = getTestId(newTestPath); return "".concat(getPosixPath(this.testPath), "#").concat(newTestId); } function _handleSuiteStart() { _assertClassBrand(_Class_brand, this, _startScope).call(this); } function _handleSuiteEnd() { _assertClassBrand(_Class_brand, this, _stopScope).call(this); } function _handleHookStart(hook) { if (shouldHookBeSkipped(hook)) { return; } var scopeUuid = last(this.runContext.scopes); var fixtureUuid = this.runtime.startFixture(scopeUuid, /after/i.test(hook.type) ? "after" : "before", { name: hook.type }); this.runContext.executables.push(fixtureUuid); } function _handleHookPass(hook) { if (shouldHookBeSkipped(hook)) { return; } var fixtureUuid = this.runContext.executables.pop(); this.runtime.updateFixture(fixtureUuid, r => { r.status = Status.PASSED; r.stage = Stage.FINISHED; }); this.runtime.stopFixture(fixtureUuid); } function _handleHookFail(hook, error) { if (shouldHookBeSkipped(hook)) { return; } var fixtureUuid = this.runContext.executables.pop(); var status = typeof error === "string" ? Status.BROKEN : getStatusFromError(error); this.runtime.updateFixture(fixtureUuid, r => { r.status = status; r.statusDetails = { message: typeof error === "string" ? error : error.message, trace: typeof error === "string" ? undefined : error.stack }; r.stage = Stage.FINISHED; }); this.runtime.stopFixture(fixtureUuid); } function _handleTestStart(test) { var _test$startedAt; var fsPath = this.testPath.split(sep); var newTestSuitePath = getTestPath(test.parent); var titlePath = fsPath.concat(newTestSuitePath); var { cleanTitle, labels, links } = extractMetadataFromString(test.name); var newTestFullName = _assertClassBrand(_Class_brand, this, _getTestFullName).call(this, test, cleanTitle); if (this.testPlan && !isTestPresentInTestPlan(newTestFullName, this.testPlan)) { test.mode = "skip"; this.runContext.skippedTestsFullNamesByTestPlan.push(newTestFullName); return; } var testUuid = this.runtime.startTest({ name: cleanTitle, fullName: newTestFullName, start: (_test$startedAt = test.startedAt) !== null && _test$startedAt !== void 0 ? _test$startedAt : undefined, stage: Stage.RUNNING, labels: [getLanguageLabel(), getFrameworkLabel("jest"), getPackageLabel(this.testPath), getHostLabel(), getThreadLabel(env.JEST_WORKER_ID), ...getEnvironmentLabels(), ...getSuiteLabels(newTestSuitePath), ...labels], titlePath, links }, this.runContext.scopes); this.runContext.executables.push(testUuid); return testUuid; } function _handleTestScopeStart() { _assertClassBrand(_Class_brand, this, _startScope).call(this); } function _handleTestScopeStop(test) { var testUuid = this.runContext.executables.pop(); if (testUuid) { var _tr, _tr2; var { details } = _assertClassBrand(_Class_brand, this, _statusAndDetails).call(this, test.errors); var tr; this.runtime.updateTest(testUuid, result => { tr = result; }); // hook failure, finish as skipped if (((_tr = tr) === null || _tr === void 0 ? void 0 : _tr.status) === undefined && ((_tr2 = tr) === null || _tr2 === void 0 ? void 0 : _tr2.stage) === Stage.RUNNING) { this.runtime.updateTest(testUuid, result => { result.stage = Stage.FINISHED; result.status = Status.SKIPPED; result.statusDetails = _objectSpread(_objectSpread({}, result.statusDetails), details); }); } this.runtime.writeTest(testUuid); } _assertClassBrand(_Class_brand, this, _stopScope).call(this); } function _startScope() { var scopeUuid = this.runtime.startScope(); this.runContext.scopes.push(scopeUuid); } function _stopScope() { var scopeUuid = this.runContext.scopes.pop(); if (!scopeUuid) { return; } this.runtime.writeScope(scopeUuid); } function _handleTestPass(test) { var _test$duration; var testUuid = _assertClassBrand(_Class_brand, this, _currentExecutable).call(this); if (!testUuid) { return; } // @ts-ignore var { suppressedErrors = [] } = this.global.expect.getState(); var statusAndDetails = _assertClassBrand(_Class_brand, this, _statusAndDetails).call(this, suppressedErrors); this.runtime.updateTest(testUuid, result => { result.stage = Stage.FINISHED; result.status = statusAndDetails.status; result.statusDetails = _objectSpread(_objectSpread({}, result.statusDetails), statusAndDetails.details); }); this.runtime.stopTest(testUuid, { duration: (_test$duration = test.duration) !== null && _test$duration !== void 0 ? _test$duration : 0 }); } function _handleTestFail(test) { var _test$duration2; var testUuid = _assertClassBrand(_Class_brand, this, _currentExecutable).call(this); if (!testUuid) { return; } var { status, details } = _assertClassBrand(_Class_brand, this, _statusAndDetails).call(this, test.errors); this.runtime.updateTest(testUuid, result => { result.stage = Stage.FINISHED; result.status = status; result.statusDetails = _objectSpread(_objectSpread({}, result.statusDetails), details); }); this.runtime.stopTest(testUuid, { duration: (_test$duration2 = test.duration) !== null && _test$duration2 !== void 0 ? _test$duration2 : 0 }); } function _handleTestSkip(test) { var newTestFullName = _assertClassBrand(_Class_brand, this, _getTestFullName).call(this, test); if (this.runContext.skippedTestsFullNamesByTestPlan.includes(newTestFullName)) { return; } // noinspection JSPotentiallyInvalidUsageOfThis var testUuid = _assertClassBrand(_Class_brand, this, _handleTestStart).call(this, test); if (!testUuid) { return; } this.runtime.updateTest(testUuid, result => { result.stage = Stage.FINISHED; result.status = Status.SKIPPED; }); // noinspection JSPotentiallyInvalidUsageOfThis _assertClassBrand(_Class_brand, this, _handleTestScopeStop).call(this, test); } function _handleTestTodo(test) { // noinspection JSPotentiallyInvalidUsageOfThis var testUuid = _assertClassBrand(_Class_brand, this, _handleTestStart).call(this, test); if (!testUuid) { return; } this.runtime.updateTest(testUuid, result => { result.stage = Stage.FINISHED; result.status = Status.SKIPPED; result.statusDetails = { message: "TODO" }; }); // noinspection JSPotentiallyInvalidUsageOfThis _assertClassBrand(_Class_brand, this, _handleTestScopeStop).call(this, test); } function _handleRunFinish() { this.runtime.writeEnvironmentInfo(); this.runtime.writeCategoriesDefinitions(); } function _currentExecutable() { if (this.runContext.executables.length === 0) { return undefined; } return this.runContext.executables[this.runContext.executables.length - 1]; } function _statusAndDetails(errors) { if (errors.length === 0) { return { status: Status.PASSED, details: {} }; } // jest collects all errors, but we need to report the first one because it's a reason why the test has been failed var [error] = errors; var hasMultipleErrors = Array.isArray(error); var exception = hasMultipleErrors ? error[0] : error; var firstError = _assertClassBrand(_Class_brand, this, _convertToError).call(this, exception); // in case user throws non-Error type, the first exception is the user-thrown object, // while the second one is provided by jest and has correct stack trace if (hasMultipleErrors && error.length > 1) { var secondError = _assertClassBrand(_Class_brand, this, _convertToError).call(this, error[1]); if (!firstError.message) { firstError.message = secondError.message; } if (!firstError.stack) { firstError.stack = secondError.stack; } } var details = getMessageAndTraceFromError(firstError); var status = getStatusFromError(firstError); return { status, details }; } function _convertToError(exception) { if (!exception) { return {}; } // user may throw an object as well if (typeof exception !== "object" || !("stack" in exception)) { return { message: serialize(exception) }; } var prototypeDescriptors = Object.getOwnPropertyDescriptors(Object.getPrototypeOf(exception)); var protoClone = Object.create(null, prototypeDescriptors); // eslint-disable-next-line @typescript-eslint/no-unsafe-argument var clone = Object.create(protoClone, Object.getOwnPropertyDescriptors(exception)); return clone; } }; export { createJestEnvironment }; //# sourceMappingURL=environmentFactory.js.map