From dc12bdc5d0accf3a90d0f56c7c2c38549e7440a1 Mon Sep 17 00:00:00 2001 From: Maxim <17935127+delatrie@users.noreply.github.com> Date: Tue, 9 Jul 2024 16:32:34 +0700 Subject: [PATCH] feat(allure-jest): compatibility with Jest >=24.8.0 (via #1054) --- packages/allure-jest/package.json | 12 ++++++++---- packages/allure-jest/src/environmentFactory.ts | 16 ++++++++++------ packages/allure-jest/src/jsdom.ts | 2 +- packages/allure-jest/src/model.ts | 13 ++++++++----- packages/allure-jest/src/node.ts | 2 +- packages/allure-jest/src/utils.ts | 11 +++++++++-- yarn.lock | 11 +++++++---- 7 files changed, 44 insertions(+), 23 deletions(-) diff --git a/packages/allure-jest/package.json b/packages/allure-jest/package.json index 4e1f25892..5f996ff4d 100644 --- a/packages/allure-jest/package.json +++ b/packages/allure-jest/package.json @@ -82,15 +82,19 @@ "vitest": "^1.6.0" }, "peerDependencies": { - "jest": ">=28.0.0", - "jest-cli": ">=28.0.0", - "jest-environment-jsdom": ">=28.0.0", - "jest-environment-node": ">=28.0.0" + "jest": ">=24.8.0", + "jest-circus": ">=24.8.0", + "jest-cli": ">=24.8.0", + "jest-environment-jsdom": ">=24.8.0", + "jest-environment-node": ">=24.8.0" }, "peerDependenciesMeta": { "jest": { "optional": true }, + "jest-circus": { + "optional": true + }, "jest-cli": { "optional": true }, diff --git a/packages/allure-jest/src/environmentFactory.ts b/packages/allure-jest/src/environmentFactory.ts index dc826f3cc..b9d6d2c54 100644 --- a/packages/allure-jest/src/environmentFactory.ts +++ b/packages/allure-jest/src/environmentFactory.ts @@ -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"; @@ -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; @@ -37,9 +37,13 @@ const createJestEnvironment = (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, @@ -49,7 +53,7 @@ const createJestEnvironment = (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 diff --git a/packages/allure-jest/src/jsdom.ts b/packages/allure-jest/src/jsdom.ts index 07f79be11..2d7d10bc3 100644 --- a/packages/allure-jest/src/jsdom.ts +++ b/packages/allure-jest/src/jsdom.ts @@ -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); diff --git a/packages/allure-jest/src/model.ts b/packages/allure-jest/src/model.ts index a8f53f777..cebae09b1 100644 --- a/packages/allure-jest/src/model.ts +++ b/packages/allure-jest/src/model.ts @@ -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"; @@ -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; +}; diff --git a/packages/allure-jest/src/node.ts b/packages/allure-jest/src/node.ts index 10de6de80..b493ff394 100644 --- a/packages/allure-jest/src/node.ts +++ b/packages/allure-jest/src/node.ts @@ -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); diff --git a/packages/allure-jest/src/utils.ts b/packages/allure-jest/src/utils.ts index c3dec46df..dc5852549 100644 --- a/packages/allure-jest/src/utils.ts +++ b/packages/allure-jest/src/utils.ts @@ -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 = (array: T[]): T => array[array.length - 1]; diff --git a/yarn.lock b/yarn.lock index 0b390deca..7e27e60dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4110,13 +4110,16 @@ __metadata: typescript: "npm:^5.2.2" vitest: "npm:^1.6.0" peerDependencies: - jest: ">=28.0.0" - jest-cli: ">=28.0.0" - jest-environment-jsdom: ">=28.0.0" - jest-environment-node: ">=28.0.0" + jest: ">=24.8.0" + jest-circus: ">=24.8.0" + jest-cli: ">=24.8.0" + jest-environment-jsdom: ">=24.8.0" + jest-environment-node: ">=24.8.0" peerDependenciesMeta: jest: optional: true + jest-circus: + optional: true jest-cli: optional: true jest-environment-jsdom: