Skip to content

Commit

Permalink
Make allure-jest compatible with jest v28 or lower
Browse files Browse the repository at this point in the history
Fix #1010
  • Loading branch information
delatrie committed Jul 8, 2024
1 parent 1b3c982 commit 88fcd72
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 15 deletions.
16 changes: 10 additions & 6 deletions packages/allure-jest/src/environmentFactory.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { EnvironmentContext, JestEnvironment } from "@jest/environment";
import type { EnvironmentContext, JestEnvironment, JestEnvironmentConfig } from "@jest/environment";
import type { Circus } from "@jest/types";
import os from "node:os";
import { dirname, sep } from "node:path";
Expand All @@ -18,7 +18,7 @@ import {
} from "allure-js-commons/sdk/reporter";
import { setGlobalTestRuntime } from "allure-js-commons/sdk/runtime";
import { AllureJestTestRuntime } from "./AllureJestTestRuntime.js";
import type { AllureJestConfig, AllureJestEnvironment, RunContext } from "./model.js";
import type { AllureJestConfig, AllureJestEnvironment, AllureJestProjectConfig, RunContext } from "./model.js";
import { getTestId, getTestPath, isTestPresentInTestPlan, last, shouldHookBeSkipped } from "./utils.js";

const { ALLURE_TEST_MODE, ALLURE_HOST_NAME, ALLURE_THREAD_NAME, JEST_WORKER_ID } = process.env;
Expand All @@ -37,9 +37,13 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
skippedTestsFullNamesByTestPlan: [],
};

constructor(config: AllureJestConfig, context: EnvironmentContext) {
super(config, context);
const { resultsDir = "allure-results", ...restConfig } = config?.projectConfig?.testEnvironmentOptions || {};
// config is AllureJestConfig in Jest v28 or greater. In older versions
// it's AllureJestProjectConfig. See https://github.com/jestjs/jest/pull/12461
constructor(config: AllureJestConfig | AllureJestProjectConfig, context: EnvironmentContext) {
super(config as JestEnvironmentConfig, context);

const projectConfig = "projectConfig" in config ? config.projectConfig : config;
const { resultsDir = "allure-results", ...restConfig } = projectConfig?.testEnvironmentOptions || {};

this.runtime = new ReporterRuntime({
...restConfig,
Expand All @@ -49,7 +53,7 @@ const createJestEnvironment = <T extends typeof JestEnvironment>(Base: T): T =>
resultsDir,
}),
});
this.testPath = context.testPath.replace(config.globalConfig.rootDir, "").replace(sep, "");
this.testPath = context.testPath.replace(projectConfig.rootDir, "").replace(sep, "");
this.testPlan = parseTestPlan();

// @ts-ignore
Expand Down
2 changes: 1 addition & 1 deletion packages/allure-jest/src/jsdom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestEnvironment } from "jest-environment-jsdom";
import TestEnvironment from "jest-environment-jsdom";
import createJestEnvironment from "./environmentFactory.js";

export default createJestEnvironment(TestEnvironment);
13 changes: 8 additions & 5 deletions packages/allure-jest/src/model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { JestEnvironment, JestEnvironmentConfig } from "@jest/environment";
import type { Config as JestConfig } from "@jest/types";
import type { RuntimeMessage } from "allure-js-commons/sdk";
import type { Config } from "allure-js-commons/sdk/reporter";

Expand All @@ -14,8 +15,10 @@ export interface AllureJestEnvironment extends JestEnvironment {
handleAllureRuntimeMessage(message: RuntimeMessage): void;
}

export interface AllureJestConfig extends JestEnvironmentConfig {
projectConfig: JestEnvironmentConfig["projectConfig"] & {
testEnvironmentOptions?: JestEnvironmentConfig["projectConfig"]["testEnvironmentOptions"] & Config;
};
}
export type AllureJestProjectConfig = JestConfig.ProjectConfig & {
testEnvironmentOptions?: JestConfig.ProjectConfig["testEnvironmentOptions"] & Config;
};

export type AllureJestConfig = JestEnvironmentConfig & {
projectConfig: AllureJestProjectConfig;
};
2 changes: 1 addition & 1 deletion packages/allure-jest/src/node.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestEnvironment } from "jest-environment-node";
import TestEnvironment from "jest-environment-node";
import createJestEnvironment from "./environmentFactory.js";

export default createJestEnvironment(TestEnvironment);
11 changes: 9 additions & 2 deletions packages/allure-jest/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,17 @@ export const getTestId = (path: string[]): string => path.join(" ");
*/
export const getTestFullName = (path: string[]): string => path.join(" > ");

const jestHookPattern = /^at jestAdapter/i;
// A slightly different reference should be used to identify jestAdapter's global hook in some older versions of Jest.
const jestHookLegacyPattern = /jest-circus\/build\/legacy-code-todo-rewrite\/jestAdapter.js:\d+:\d+$/;

export const shouldHookBeSkipped = (hook: Circus.Hook): boolean => {
const errorFirstLine = hook?.asyncError?.stack?.split("\n")?.[1]?.trim() || "";
// In older versions of Jest the hook's stack is direcrly in asyncError. In newer ones - in asyncError.stack.
const stackOrError: string | Error | undefined = hook?.asyncError;
const stack = typeof stackOrError === "string" ? stackOrError : stackOrError?.stack;
const errorFirstLine = stack?.split("\n")?.[1]?.trim() || "";

return /^at jestAdapter/i.test(errorFirstLine);
return jestHookPattern.test(errorFirstLine) || jestHookLegacyPattern.test(errorFirstLine);
};

export const last = <T>(array: T[]): T => array[array.length - 1];
Expand Down

0 comments on commit 88fcd72

Please sign in to comment.