diff --git a/package.json b/package.json index aa195cf11..09242906c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "allure-js", - "version": "3.0.1", + "version": "3.0.2", "private": true, "workspaces": [ "packages/*" diff --git a/packages/allure-codeceptjs/package.json b/packages/allure-codeceptjs/package.json index b0bfcb7dc..2516598b9 100644 --- a/packages/allure-codeceptjs/package.json +++ b/packages/allure-codeceptjs/package.json @@ -1,6 +1,6 @@ { "name": "allure-codeceptjs", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure codeceptjs integration", "keywords": [ "codeceptjs", diff --git a/packages/allure-cucumberjs/package.json b/packages/allure-cucumberjs/package.json index fb5e50ed0..4898fe08d 100644 --- a/packages/allure-cucumberjs/package.json +++ b/packages/allure-cucumberjs/package.json @@ -1,6 +1,6 @@ { "name": "allure-cucumberjs", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Cucumber.JS integration", "homepage": "https://allurereport.org/", "repository": { diff --git a/packages/allure-cucumberjs/src/reporter.ts b/packages/allure-cucumberjs/src/reporter.ts index 9aaee63d2..d3f272bd7 100644 --- a/packages/allure-cucumberjs/src/reporter.ts +++ b/packages/allure-cucumberjs/src/reporter.ts @@ -236,18 +236,19 @@ export default class AllureCucumberReporter extends Formatter { const testCase = this.testCaseMap.get(data.testCaseId)!; const pickle = this.pickleMap.get(testCase.pickleId)!; const doc = this.documentMap.get(pickle.uri)!; - const [scenarioId] = pickle.astNodeIds; + const [scenarioId, ...astIds] = pickle.astNodeIds; const scenario = this.scenarioMap.get(scenarioId); const posixPath = getPosixPathRelativeToProjectRoot(pickle); const fullName = `${posixPath}#${pickle.name}`; + const testCaseId = md5(`${posixPath}#${scenario?.name ?? pickle.name}`); const result: Partial = { name: pickle.name, description: (scenario?.description || doc?.feature?.description || "").trim(), labels: [], links: [], - testCaseId: md5(fullName), start: TimeConversion.timestampToMillisecondsSinceEpoch(data.timestamp), + testCaseId, fullName, }; @@ -288,22 +289,39 @@ export default class AllureCucumberReporter extends Formatter { return; } - scenario.examples.forEach((example) => { - const csvDataTableHeader = example?.tableHeader?.cells.map((cell) => cell.value).join(",") || ""; + for (const example of scenario.examples) { + const exampleName = example?.name ? `Examples: ${example.name}` : "Examples"; + const parameterNames = example?.tableHeader?.cells.map((cell) => cell.value); + const csvDataTableHeader = parameterNames?.join(",") || ""; + + const currentRow = example?.tableBody?.find((tb) => astIds.includes(tb.id)); + if (currentRow) { + const parameters = currentRow.cells.map((cell, index) => { + const paramName = parameterNames && parameterNames.length > index ? parameterNames[index] : `arg${index}`; + const paramValue = cell.value; + return { + name: paramName, + value: paramValue, + }; + }); + + this.allureRuntime.updateTest(testUuid, (tr) => (tr.parameters = [...tr.parameters, ...parameters])); + } + const csvDataTableBody = example?.tableBody.map((row) => row.cells.map((cell) => cell.value).join(",")).join("\n") || ""; if (!csvDataTableHeader && !csvDataTableBody) { - return; + continue; } const csvDataTable = `${csvDataTableHeader}\n${csvDataTableBody}\n`; - this.allureRuntime.writeAttachment(testUuid, null, "Examples", Buffer.from(csvDataTable, "utf-8"), { + this.allureRuntime.writeAttachment(testUuid, null, exampleName, Buffer.from(csvDataTable, "utf-8"), { contentType: ContentType.CSV, fileExtension: ".csv", }); - }); + } } private onTestCaseFinished(data: messages.TestCaseFinished) { diff --git a/packages/allure-cucumberjs/test/samples/features/examples-multi.feature b/packages/allure-cucumberjs/test/samples/features/examples-multi.feature new file mode 100644 index 000000000..24a745868 --- /dev/null +++ b/packages/allure-cucumberjs/test/samples/features/examples-multi.feature @@ -0,0 +1,13 @@ +Feature: allure-test + Scenario Outline: Allure Tests + Given The sum of the numbers and must be equal to + + @tag + Examples: default set + | a | b | c | + | 1 | 2 | 3 | + | 2 | 2 | 4 | + + Examples: + | a | b | c | + | 3 | 10 | 13 | diff --git a/packages/allure-cucumberjs/test/samples/features/examples-name-change.feature b/packages/allure-cucumberjs/test/samples/features/examples-name-change.feature new file mode 100644 index 000000000..ada828160 --- /dev/null +++ b/packages/allure-cucumberjs/test/samples/features/examples-name-change.feature @@ -0,0 +1,8 @@ +Feature: allure-test + Scenario Outline: test + = + Given The sum of the numbers and must be equal to + + Examples: + | a | b | c | + | 1 | 2 | 3 | + | 2 | 2 | 4 | diff --git a/packages/allure-cucumberjs/test/samples/support/examples-multi.cjs b/packages/allure-cucumberjs/test/samples/support/examples-multi.cjs new file mode 100644 index 000000000..29e6e2192 --- /dev/null +++ b/packages/allure-cucumberjs/test/samples/support/examples-multi.cjs @@ -0,0 +1,3 @@ +const { Given } = require("@cucumber/cucumber"); + +Given("The sum of the numbers {int} and {int} must be equal to {int}", (a, b, c) => {}); diff --git a/packages/allure-cucumberjs/test/spec/examples.test.ts b/packages/allure-cucumberjs/test/spec/examples.test.ts index 474c1abe5..e877802ae 100644 --- a/packages/allure-cucumberjs/test/spec/examples.test.ts +++ b/packages/allure-cucumberjs/test/spec/examples.test.ts @@ -15,6 +15,20 @@ it("handles examples table", async () => { type: ContentType.CSV, }), ]), + parameters: expect.arrayContaining([ + { + name: "a", + value: "1", + }, + { + name: "b", + value: "3", + }, + { + name: "result", + value: "4", + }, + ]), steps: expect.arrayContaining([ expect.objectContaining({ name: "Given a is 1", @@ -40,6 +54,20 @@ it("handles examples table", async () => { type: ContentType.CSV, }), ]), + parameters: expect.arrayContaining([ + { + name: "a", + value: "2", + }, + { + name: "b", + value: "4", + }, + { + name: "result", + value: "6", + }, + ]), steps: expect.arrayContaining([ expect.objectContaining({ name: "Given a is 2", @@ -58,3 +86,120 @@ it("handles examples table", async () => { ); expect(Object.keys(attachments as object)).toHaveLength(2); }); + +it("should handle multiple examples tables", async () => { + const { tests, attachments } = await runCucumberInlineTest(["examples-multi"], ["examples-multi"]); + + expect(tests).toHaveLength(3); + expect(tests).toContainEqual( + expect.objectContaining({ + name: "Allure Tests", + parameters: expect.arrayContaining([ + { + name: "a", + value: "1", + }, + { + name: "b", + value: "2", + }, + { + name: "c", + value: "3", + }, + ]), + attachments: expect.arrayContaining([ + expect.objectContaining({ + name: "Examples", + type: ContentType.CSV, + }), + expect.objectContaining({ + name: "Examples: default set", + type: ContentType.CSV, + }), + ]), + steps: expect.arrayContaining([ + expect.objectContaining({ + name: "Given The sum of the numbers 1 and 2 must be equal to 3", + }), + ]), + }), + ); + expect(tests).toContainEqual( + expect.objectContaining({ + name: "Allure Tests", + attachments: expect.arrayContaining([ + expect.objectContaining({ + name: "Examples", + type: ContentType.CSV, + }), + expect.objectContaining({ + name: "Examples: default set", + type: ContentType.CSV, + }), + ]), + parameters: expect.arrayContaining([ + { + name: "a", + value: "2", + }, + { + name: "b", + value: "2", + }, + { + name: "c", + value: "4", + }, + ]), + steps: expect.arrayContaining([ + expect.objectContaining({ + name: "Given The sum of the numbers 2 and 2 must be equal to 4", + }), + ]), + }), + ); + expect(tests).toContainEqual( + expect.objectContaining({ + name: "Allure Tests", + attachments: expect.arrayContaining([ + expect.objectContaining({ + name: "Examples", + type: ContentType.CSV, + }), + expect.objectContaining({ + name: "Examples: default set", + type: ContentType.CSV, + }), + ]), + parameters: expect.arrayContaining([ + { + name: "a", + value: "3", + }, + { + name: "b", + value: "10", + }, + { + name: "c", + value: "13", + }, + ]), + steps: expect.arrayContaining([ + expect.objectContaining({ + name: "Given The sum of the numbers 3 and 10 must be equal to 13", + }), + ]), + }), + ); + expect(Object.keys(attachments as object)).toHaveLength(6); +}); + +it("should create same test case id for scenario outline tests with template name", async () => { + const { tests } = await runCucumberInlineTest(["examples-name-change"], ["examples-multi"]); + + expect(tests).toHaveLength(2); + const [tr1, tr2] = tests; + expect(tr1.testCaseId).toEqual(tr2.testCaseId); +}); diff --git a/packages/allure-cucumberjs/test/utils.ts b/packages/allure-cucumberjs/test/utils.ts index e9bf6119b..ea2516301 100644 --- a/packages/allure-cucumberjs/test/utils.ts +++ b/packages/allure-cucumberjs/test/utils.ts @@ -22,7 +22,7 @@ export const runCucumberInlineTest = async ( const samplesPath = join(__dirname, "samples"); const testDir = join(__dirname, "fixtures", randomUUID()); const configFilePath = join(testDir, "config.js"); - const reporterFilePath = join(testDir, "reporter.js"); + const reporterFilePath = require.resolve("allure-cucumberjs/reporter"); const featuresTempPath = join(testDir, "features"); const supportTempPath = join(testDir, "features/support"); const worldFilePath = join(supportTempPath, "world.js"); @@ -31,7 +31,7 @@ export const runCucumberInlineTest = async ( default: { paths: ["./**/*.feature"], ${parallel ? "parallel: 4," : ""} - format: ["summary", '"${pathToFileURL(reporterFilePath).toString()}"'], + format: ["summary", '"${pathToFileURL(reporterFilePath).toString()}":"ignore.txt"'], formatOptions: { labels: [ { @@ -66,11 +66,6 @@ export const runCucumberInlineTest = async ( } } `; - const reporterContent = ` - const AllureCucumberReporter = require("allure-cucumberjs/reporter"); - - module.exports = AllureCucumberReporter; - `; const worldContent = ` require("allure-cucumberjs"); `; @@ -90,14 +85,6 @@ export const runCucumberInlineTest = async ( }); }); await writeFile(join(testDir, "package.json"), String.raw`{"name": "dummy"}`, "utf8"); - await step("reporter.js", async () => { - await writeFile(reporterFilePath, reporterContent, "utf8"); - await attachment("reporter.js", reporterContent, { - contentType: "text/plain", - encoding: "utf-8", - fileExtension: ".js", - }); - }); await step("world.js", async () => { await writeFile(worldFilePath, worldContent, "utf8"); await attachment("world.js", worldContent, { diff --git a/packages/allure-cypress/package.json b/packages/allure-cypress/package.json index fa6d8f312..4acde9564 100644 --- a/packages/allure-cypress/package.json +++ b/packages/allure-cypress/package.json @@ -1,6 +1,6 @@ { "name": "allure-cypress", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Cypress integration", "keywords": [ "cypress", diff --git a/packages/allure-jasmine/package.json b/packages/allure-jasmine/package.json index 8dc2adb9f..9b6e44453 100644 --- a/packages/allure-jasmine/package.json +++ b/packages/allure-jasmine/package.json @@ -1,6 +1,6 @@ { "name": "allure-jasmine", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Jasmine integration", "homepage": "https://allurereport.org/", "repository": { diff --git a/packages/allure-jest/package.json b/packages/allure-jest/package.json index 4edb2e74e..349abe4b8 100644 --- a/packages/allure-jest/package.json +++ b/packages/allure-jest/package.json @@ -1,6 +1,6 @@ { "name": "allure-jest", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Jest integration", "keywords": [ "jest", diff --git a/packages/allure-jest/src/environmentFactory.ts b/packages/allure-jest/src/environmentFactory.ts index 788b13fe8..53c76e89e 100644 --- a/packages/allure-jest/src/environmentFactory.ts +++ b/packages/allure-jest/src/environmentFactory.ts @@ -3,7 +3,7 @@ import type { Circus } from "@jest/types"; import { relative } from "node:path"; import { env } from "node:process"; import * as allure from "allure-js-commons"; -import { Stage, Status } from "allure-js-commons"; +import { Stage, Status, type StatusDetails, type TestResult } from "allure-js-commons"; import type { RuntimeMessage } from "allure-js-commons/sdk"; import { getMessageAndTraceFromError, getStatusFromError } from "allure-js-commons/sdk"; import type { TestPlanV1 } from "allure-js-commons/sdk"; @@ -94,13 +94,10 @@ const createJestEnvironment = (Base: T): T => this.#handleSuiteEnd(); break; case "test_start": - this.#handleTestStart(event.test); - break; - case "test_done": - this.#handleTestDone(); + this.#handleTestScopeStart(); break; - case "test_todo": - this.#handleTestTodo(event.test); + case "test_fn_start": + this.#handleTestStart(event.test); break; case "test_fn_success": this.#handleTestPass(event.test); @@ -108,9 +105,15 @@ const createJestEnvironment = (Base: T): T => case "test_fn_failure": this.#handleTestFail(event.test); break; + case "test_done": + this.#handleTestScopeStop(event.test); + break; case "test_skip": this.#handleTestSkip(event.test); break; + case "test_todo": + this.#handleTestTodo(event.test); + break; case "run_finish": this.#handleRunFinish(); break; @@ -181,7 +184,7 @@ const createJestEnvironment = (Base: T): T => this.runtime.stopFixture(fixtureUuid); } - #startTest(test: Circus.TestEntry) { + #handleTestStart(test: Circus.TestEntry) { const newTestSuitePath = getTestPath(test.parent); const newTestFullName = this.#getTestFullName(test); @@ -191,12 +194,12 @@ const createJestEnvironment = (Base: T): T => return; } - this.#startScope(); const testUuid = this.runtime.startTest( { name: test.name, fullName: newTestFullName, start: test.startedAt ?? undefined, + stage: Stage.RUNNING, labels: [ getLanguageLabel(), getFrameworkLabel("jest"), @@ -215,28 +218,34 @@ const createJestEnvironment = (Base: T): T => return testUuid; } - #stopTest(testUuid: string, duration: number) { - if (!testUuid) { - return; - } - - this.runtime.stopTest(testUuid, { duration }); - this.runtime.writeTest(testUuid); + #handleTestScopeStart() { + this.#startScope(); } - #handleTestStart(test: Circus.TestEntry) { - const testUuid = this.#startTest(test); + #handleTestScopeStop(test: Circus.TestEntry) { + const testUuid = this.runContext.executables.pop(); - if (!testUuid) { - return; + if (testUuid) { + const { details } = this.#statusAndDetails(test.errors); + let tr: TestResult | undefined; + this.runtime.updateTest(testUuid, (result) => { + tr = result; + }); + // hook failure, finish as skipped + if (tr?.status === undefined && tr?.stage === Stage.RUNNING) { + this.runtime.updateTest(testUuid, (result) => { + result.stage = Stage.FINISHED; + result.status = Status.SKIPPED; + result.statusDetails = { + ...result.statusDetails, + ...details, + }; + }); + } + + this.runtime.writeTest(testUuid); } - this.runtime.updateTest(testUuid, (result) => { - result.stage = Stage.RUNNING; - }); - } - - #handleTestDone() { this.#stopScope(); } @@ -247,47 +256,54 @@ const createJestEnvironment = (Base: T): T => } #stopScope() { - const scopeUuid = this.runContext.scopes.pop()!; + const scopeUuid = this.runContext.scopes.pop(); + if (!scopeUuid) { + return; + } this.runtime.writeScope(scopeUuid); } #handleTestPass(test: Circus.TestEntry) { - const testUuid = this.runContext.executables.pop(); + const testUuid = this.#currentExecutable(); if (!testUuid) { return; } + // @ts-ignore + const { suppressedErrors = [] } = this.global.expect.getState(); + const statusAndDetails = this.#statusAndDetails(suppressedErrors as Circus.TestError[]); this.runtime.updateTest(testUuid, (result) => { result.stage = Stage.FINISHED; - result.status = Status.PASSED; + result.status = statusAndDetails.status; + result.statusDetails = { + ...result.statusDetails, + ...statusAndDetails.details, + }; }); - this.#stopTest(testUuid, test.duration ?? 0); + + this.runtime.stopTest(testUuid, { duration: test.duration ?? 0 }); } #handleTestFail(test: Circus.TestEntry) { - const testUuid = this.runContext.executables.pop(); + const testUuid = this.#currentExecutable(); if (!testUuid) { return; } - // jest collects all errors, but we need to report the first one because it's a reason why the test has been failed - const [error] = test.errors; - const hasMultipleErrors = Array.isArray(error); - const firstError: Error = hasMultipleErrors ? error[0] : error; - const details = getMessageAndTraceFromError(firstError); - const status = getStatusFromError(firstError); + const { status, details } = this.#statusAndDetails(test.errors); this.runtime.updateTest(testUuid, (result) => { result.stage = Stage.FINISHED; result.status = status; result.statusDetails = { + ...result.statusDetails, ...details, }; }); - this.#stopTest(testUuid, test.duration ?? 0); + this.runtime.stopTest(testUuid, { duration: test.duration ?? 0 }); } #handleTestSkip(test: Circus.TestEntry) { @@ -297,37 +313,66 @@ const createJestEnvironment = (Base: T): T => return; } - const testUuid = this.runContext.executables.pop(); + // noinspection JSPotentiallyInvalidUsageOfThis + const testUuid = this.#handleTestStart(test); if (!testUuid) { return; } this.runtime.updateTest(testUuid, (result) => { - result.stage = Stage.PENDING; + result.stage = Stage.FINISHED; result.status = Status.SKIPPED; }); - this.#stopTest(testUuid, test.duration ?? 0); + // noinspection JSPotentiallyInvalidUsageOfThis + this.#handleTestScopeStop(test); } #handleTestTodo(test: Circus.TestEntry) { - const testUuid = this.runContext.executables.pop(); - + // noinspection JSPotentiallyInvalidUsageOfThis + const testUuid = this.#handleTestStart(test); if (!testUuid) { return; } this.runtime.updateTest(testUuid, (result) => { - result.stage = Stage.PENDING; + result.stage = Stage.FINISHED; result.status = Status.SKIPPED; + result.statusDetails = { + message: "TODO", + }; }); - this.#stopTest(testUuid, test.duration ?? 0); + // noinspection JSPotentiallyInvalidUsageOfThis + this.#handleTestScopeStop(test); } #handleRunFinish() { this.runtime.writeEnvironmentInfo(); this.runtime.writeCategoriesDefinitions(); } + + #currentExecutable() { + if (this.runContext.executables.length === 0) { + return undefined; + } + return this.runContext.executables[this.runContext.executables.length - 1]; + } + + #statusAndDetails(errors: Circus.TestError[]): { status: Status; details: Partial } { + 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 + const [error] = errors; + const hasMultipleErrors = Array.isArray(error); + const firstError: Error = hasMultipleErrors ? error[0] : error; + const details = getMessageAndTraceFromError(firstError); + const status = getStatusFromError(firstError); + return { status, details }; + } }; }; diff --git a/packages/allure-jest/test/spec/hooks.test.ts b/packages/allure-jest/test/spec/hooks.test.ts index 1988913d5..57159004b 100644 --- a/packages/allure-jest/test/spec/hooks.test.ts +++ b/packages/allure-jest/test/spec/hooks.test.ts @@ -176,18 +176,43 @@ it("should report beforeAll/afterAll for tests in sub-suites", async () => { ); }); -it("reports failed hooks", async () => { +it("should report failed beforeAll hooks", async () => { const { tests, groups } = await runJestInlineTest({ "sample.test.js": ` beforeAll(() => { throw new Error("foo"); }); - it("passed", () => {}); + it("test 1", () => {}); + it("test 2", () => {}); `, }); - expect(tests).toHaveLength(0); + expect(tests).toHaveLength(2); + expect(tests).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "test 1", + status: Status.SKIPPED, + stage: Stage.FINISHED, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + }), + + expect.objectContaining({ + name: "test 2", + status: Status.SKIPPED, + stage: Stage.FINISHED, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + }), + ]), + ); + expect(groups).toHaveLength(1); expect(groups).toEqual( expect.arrayContaining([ @@ -204,6 +229,140 @@ it("reports failed hooks", async () => { }), ]), afters: [], + children: expect.arrayContaining(tests.map((t) => t.uuid)), + }), + ]), + ); +}); + +it("should report failed beforeEach hooks", async () => { + const { tests, groups } = await runJestInlineTest({ + "sample.test.js": ` + beforeEach(() => { + throw new Error("foo"); + }); + + it("sample test", () => {}); + `, + }); + + expect(tests).toHaveLength(1); + const [testResult] = tests; + expect(testResult).toEqual( + expect.objectContaining({ + name: "sample test", + status: Status.SKIPPED, + stage: Stage.FINISHED, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + }), + ); + + expect(groups).toHaveLength(1); + expect(groups).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "beforeEach", + befores: expect.arrayContaining([ + expect.objectContaining({ + status: Status.BROKEN, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + name: "beforeEach", + }), + ]), + afters: [], + children: [testResult.uuid], + }), + ]), + ); +}); + +it("should report failed afterEach hooks", async () => { + const { tests, groups } = await runJestInlineTest({ + "sample.test.js": ` + afterEach(() => { + throw new Error("foo"); + }); + + it("sample test", () => {}); + `, + }); + + expect(tests).toHaveLength(1); + const [testResult] = tests; + expect(testResult).toEqual( + expect.objectContaining({ + name: "sample test", + status: Status.PASSED, + stage: Stage.FINISHED, + }), + ); + + expect(groups).toHaveLength(1); + expect(groups).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "afterEach", + afters: expect.arrayContaining([ + expect.objectContaining({ + status: Status.BROKEN, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + name: "afterEach", + }), + ]), + befores: [], + children: [testResult.uuid], + }), + ]), + ); +}); + +it("should report failed afterAll hooks", async () => { + const { tests, groups } = await runJestInlineTest({ + "sample.test.js": ` + afterAll(() => { + throw new Error("foo"); + }); + + it("sample test", () => {}); + `, + }); + + expect(tests).toHaveLength(1); + const [testResult] = tests; + expect(testResult).toEqual( + expect.objectContaining({ + name: "sample test", + status: Status.PASSED, + stage: Stage.FINISHED, + }), + ); + + expect(groups).toHaveLength(1); + expect(groups).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "afterAll", + afters: expect.arrayContaining([ + expect.objectContaining({ + status: Status.BROKEN, + statusDetails: expect.objectContaining({ + message: "foo", + trace: expect.any(String), + }), + name: "afterAll", + }), + ]), + befores: [], + children: [testResult.uuid], }), ]), ); diff --git a/packages/allure-jest/test/spec/skipped.test.ts b/packages/allure-jest/test/spec/skipped.test.ts index 2283b9f03..ea4f9197a 100644 --- a/packages/allure-jest/test/spec/skipped.test.ts +++ b/packages/allure-jest/test/spec/skipped.test.ts @@ -10,8 +10,14 @@ it("skipped test", async () => { }); expect(tests).toHaveLength(1); - expect(tests[0].stage).toBe(Stage.PENDING); - expect(tests[0].status).toBe(Status.SKIPPED); + const [tr] = tests; + + expect(tr).toEqual( + expect.objectContaining({ + stage: Stage.FINISHED, + status: Status.SKIPPED, + }), + ); }); it("test inside skipped suite", async () => { @@ -24,6 +30,12 @@ it("test inside skipped suite", async () => { }); expect(tests).toHaveLength(1); - expect(tests[0].stage).toBe(Stage.PENDING); - expect(tests[0].status).toBe(Status.SKIPPED); + const [tr] = tests; + + expect(tr).toEqual( + expect.objectContaining({ + stage: Stage.FINISHED, + status: Status.SKIPPED, + }), + ); }); diff --git a/packages/allure-jest/test/spec/snapshot.test.ts b/packages/allure-jest/test/spec/snapshot.test.ts new file mode 100644 index 000000000..c37b22e13 --- /dev/null +++ b/packages/allure-jest/test/spec/snapshot.test.ts @@ -0,0 +1,38 @@ +import { expect, it } from "vitest"; +import { Status } from "allure-js-commons"; +import { runJestInlineTest } from "../utils.js"; + +it("should support snapshot testing", async () => { + const { tests } = await runJestInlineTest({ + "sample.spec.js": ` + it("test with snapshot", () => { + expect("some other data").toMatchSnapshot(); + }); + afterEach(() => { + }); + `, + "__snapshots__/sample.spec.js.snap": + "// Jest Snapshot v1, https://goo.gl/fbAQLP\n" + + "\n" + + // prettier-ignore + "exports[`test with snapshot 1`] = `\"some data\"`;\n", + }); + + expect(tests).toHaveLength(1); + const [testResult] = tests; + + expect(testResult).toEqual( + expect.objectContaining({ + name: "test with snapshot", + status: Status.FAILED, + statusDetails: expect.objectContaining({ + message: expect.stringContaining(`expect(received).toMatchSnapshot() + +Snapshot name: \`test with snapshot 1\` + +Snapshot: "some data" +Received: "some other data"`), + }), + }), + ); +}); diff --git a/packages/allure-jest/test/spec/todo.test.ts b/packages/allure-jest/test/spec/todo.test.ts index 1086a8182..9654a61e8 100644 --- a/packages/allure-jest/test/spec/todo.test.ts +++ b/packages/allure-jest/test/spec/todo.test.ts @@ -10,6 +10,15 @@ it("todo", async () => { }); expect(tests).toHaveLength(1); - expect(tests[0].stage).toBe(Stage.PENDING); - expect(tests[0].status).toBe(Status.SKIPPED); + const [tr] = tests; + + expect(tr).toEqual( + expect.objectContaining({ + stage: Stage.FINISHED, + status: Status.SKIPPED, + statusDetails: expect.objectContaining({ + message: "TODO", + }), + }), + ); }); diff --git a/packages/allure-js-commons/package.json b/packages/allure-js-commons/package.json index 7134f5094..bb173ef34 100644 --- a/packages/allure-js-commons/package.json +++ b/packages/allure-js-commons/package.json @@ -1,6 +1,6 @@ { "name": "allure-js-commons", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure JS Commons", "homepage": "https://allurereport.org/", "repository": { diff --git a/packages/allure-mocha/package.json b/packages/allure-mocha/package.json index ba4cc9c19..bf9a1833c 100644 --- a/packages/allure-mocha/package.json +++ b/packages/allure-mocha/package.json @@ -1,6 +1,6 @@ { "name": "allure-mocha", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Mocha integration", "keywords": [ "mocha", diff --git a/packages/allure-playwright/package.json b/packages/allure-playwright/package.json index 07293e901..b87d5e61d 100644 --- a/packages/allure-playwright/package.json +++ b/packages/allure-playwright/package.json @@ -1,6 +1,6 @@ { "name": "allure-playwright", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Playwright integration", "keywords": [ "playwright", diff --git a/packages/allure-vitest/package.json b/packages/allure-vitest/package.json index 2321fd142..00edbba38 100644 --- a/packages/allure-vitest/package.json +++ b/packages/allure-vitest/package.json @@ -1,6 +1,6 @@ { "name": "allure-vitest", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Vitest integration", "keywords": [ "vitest", diff --git a/packages/newman-reporter-allure/package.json b/packages/newman-reporter-allure/package.json index 32d04cb10..46c2afea0 100644 --- a/packages/newman-reporter-allure/package.json +++ b/packages/newman-reporter-allure/package.json @@ -1,6 +1,6 @@ { "name": "newman-reporter-allure", - "version": "3.0.1", + "version": "3.0.2", "description": "Allure Newman integration", "keywords": [ "allure", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy

Alternative Proxy