Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reports for vitest and playwright modules #1009

Merged
merged 2 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 73 additions & 61 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
14 changes: 8 additions & 6 deletions packages/allure-js-commons/src/facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { getGlobalTestRuntimeWithAutoconfig } from "./sdk/runtime/runtime.js";
import type { TestRuntime } from "./sdk/runtime/types.js";
import { isPromise } from "./sdk/utils.js";

// eslint-disable-next-line @typescript-eslint/ban-types
type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;
const callRuntimeMethod = <T extends keyof TestRuntime, S extends ArgumentTypes<TestRuntime[T]>>(
const callRuntimeMethod = <
T extends keyof TestRuntime,
S extends Parameters<TestRuntime[T]>,
R extends ReturnType<TestRuntime[T]>,
>(
method: T,
...args: S
) => {
): R => {
const runtime = getGlobalTestRuntimeWithAutoconfig();

if (!isPromise(runtime)) {
Expand All @@ -21,7 +23,7 @@ const callRuntimeMethod = <T extends keyof TestRuntime, S extends ArgumentTypes<
return (runtime as Promise<TestRuntime>).then((testRuntime) => {
// @ts-ignore
return testRuntime[method](...args);
});
}) as R;
};

export const label = (name: LabelName | string, value: string) => {
Expand Down Expand Up @@ -96,7 +98,7 @@ const stepContext: () => StepContext = () => ({
},
});

export const step = <T = void>(name: string, body: (context: StepContext) => T | PromiseLike<T>) => {
export const step = <T = void>(name: string, body: (context: StepContext) => T | PromiseLike<T>): PromiseLike<T> => {
return callRuntimeMethod("step", name, () => body(stepContext()));
};

Expand Down
33 changes: 17 additions & 16 deletions packages/allure-js-commons/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
export {
allureId,
attachment,
attachmentPath,
description,
descriptionHtml,
displayName,
epic,
feature,
historyId,
issue,
label,
labels,
layer,
link,
links,
owner,
parameter,
description,
descriptionHtml,
displayName,
historyId,
testCaseId,
attachment,
parentSuite,
severity,
step,
issue,
tms,
allureId,
epic,
feature,
story,
suite,
parentSuite,
subSuite,
owner,
severity,
layer,
suite,
tag,
tags,
testCaseId,
tms,
} from "./facade.js";
export type { StepContext } from "./facade.js";
export type {
Expand Down
2 changes: 1 addition & 1 deletion packages/allure-js-commons/src/sdk/reporter/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,4 @@ export const escapeRegExp = (value: string): string => {
};

export const parseProperties = properties.parse;
export const stringifyProperties = properties.stringify;
export const stringifyProperties = (data: any): string => properties.stringify(data, { unicode: true }).toString();
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export class FileSystemWriter implements Writer {
}

writeEnvironmentInfo(info: EnvironmentInfo): void {
const text = stringifyProperties(info, { unicode: true }).toString();
const text = stringifyProperties(info);
const path = this.buildPath("environment.properties");

writeFileSync(path, text);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { attachment, step } from "../../../facade.js";
import type { TestResult, TestResultContainer } from "../../../model.js";
import type { AllureResults, EnvironmentInfo } from "../../types.js";
import { parseProperties } from "../utils.js";
import { parseProperties, stringifyProperties } from "../utils.js";

const parseJsonResult = <T>(data: string) => {
return JSON.parse(Buffer.from(data, "base64").toString("utf-8")) as T;
Expand Down Expand Up @@ -42,4 +43,40 @@ export class MessageReader {
return;
}
};

attachResults = async () => {
await step("allure-results", async () => {
if (this.results.categories) {
await attachment("categories.json", JSON.stringify(this.results.categories), "application/json");
}
if (this.results.envInfo) {
await attachment("environment.properties", stringifyProperties(this.results.envInfo), "text/plain");
}
if (this.results.attachments) {
for (const key of Object.keys(this.results.attachments)) {
const content = this.results.attachments[key];
await attachment(key, content, {
contentType: "text/plain",
encoding: "base64",
});
}
}
if (this.results.tests) {
for (const tr of this.results.tests) {
await attachment(`${tr.uuid}-result.json`, JSON.stringify(tr, null, 2), {
contentType: "application/json",
encoding: "utf-8",
});
}
}
if (this.results.groups) {
for (const trc of this.results.groups) {
await attachment(`${trc.uuid}-container.json`, JSON.stringify(trc, null, 2), {
contentType: "application/json",
encoding: "utf-8",
});
}
}
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class MessageWriter implements Writer {
}

writeEnvironmentInfo(info: EnvironmentInfo): void {
const text = stringifyProperties(info, { unicode: true }).toString();
const text = stringifyProperties(info);

this.sendData("environment.properties", "misc", Buffer.from(text, "utf-8"));
}
Expand Down
2 changes: 1 addition & 1 deletion packages/allure-playwright/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
overrides: [
{
extends: ["plugin:@typescript-eslint/disable-type-checked"],
files: [".eslintrc.cjs"],
files: [".eslintrc.cjs", "vitest.config.ts", "vitest-setup.ts"],
}
],
};
6 changes: 4 additions & 2 deletions packages/allure-playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"generate-report": "allure generate ./out/allure-results -o ./out/allure-report --clean",
"lint": "eslint ./src ./test --ext .ts",
"lint:fix": "eslint ./src ./test --ext .ts --fix",
"pretest": "run compile",
"pretest": "run-p clean compile",
"test": "vitest run"
},
"dependencies": {
Expand All @@ -69,6 +69,8 @@
"@types/node": "^20.6.3",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"allure-commandline": "^2.29.0",
"allure-vitest": "workspace:*",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.28.1",
Expand All @@ -79,6 +81,6 @@
"npm-run-all2": "^6.1.2",
"rimraf": "^5.0.1",
"typescript": "^5.2.2",
"vitest": "^1.5.0"
"vitest": "^1.6.0"
}
}
35 changes: 22 additions & 13 deletions packages/allure-playwright/test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { fork } from "child_process";
import { randomUUID } from "node:crypto";
import { mkdir, rm, writeFile } from "node:fs/promises";
import { dirname, join } from "node:path";
import { dirname, extname, join } from "node:path";
import { attachment, step } from "allure-js-commons";
import type { AllureResults } from "allure-js-commons/sdk";
import { MessageReader } from "allure-js-commons/sdk/reporter";

Expand Down Expand Up @@ -34,24 +35,31 @@ export const runPlaywrightInlineTest = async (
};
const testDir = join(__dirname, "fixtures", randomUUID());

await mkdir(testDir, { recursive: true });
await step(`create test dir ${testDir}`, async () => {
await mkdir(testDir, { recursive: true });
});

for (const file of Object.keys(testFiles)) {
const filePath = join(testDir, file);

await mkdir(dirname(filePath), { recursive: true });
await writeFile(filePath, testFiles[file as keyof typeof testFiles], "utf8");
await step(file, async () => {
const filePath = join(testDir, file);
await mkdir(dirname(filePath), { recursive: true });
const content = testFiles[file as keyof typeof testFiles];
await writeFile(filePath, content, "utf8");
await attachment(file, content, { contentType: "text/plain", fileExtension: extname(file), encoding: "utf-8" });
});
}

const modulePath = require.resolve("@playwright/test/cli");
const args = ["test", "-c", "./playwright.config.js", testDir, ...cliArgs];
const testProcess = fork(modulePath, args, {
env: {
...process.env,
...env,
},
cwd: testDir,
stdio: "pipe",
const testProcess = await step(`${modulePath} ${args.join(" ")}`, () => {
return fork(modulePath, args, {
env: {
...process.env,
...env,
},
cwd: testDir,
stdio: "pipe",
});
});

const messageReader = new MessageReader();
Expand All @@ -69,6 +77,7 @@ export const runPlaywrightInlineTest = async (
testProcess.on("exit", async () => {
await rm(testDir, { recursive: true });

await messageReader.attachResults();
return resolve(messageReader.results);
});
});
Expand Down
1 change: 1 addition & 0 deletions packages/allure-playwright/vitest-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "allure-vitest/setup";
3 changes: 2 additions & 1 deletion packages/allure-playwright/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export default defineConfig({
dir: "./test/spec",
fileParallelism: false,
testTimeout: 25000,
reporters: ["default"],
setupFiles: ["./vitest-setup.ts"],
reporters: ["default", ["allure-vitest/reporter", { resultsDir: "./out/allure-results" }]],
typecheck: {
enabled: true,
tsconfig: "./tsconfig.test.json",
Expand Down
2 changes: 1 addition & 1 deletion packages/allure-vitest/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module.exports = {
overrides: [
{
extends: ["plugin:@typescript-eslint/disable-type-checked"],
files: [".eslintrc.cjs"],
files: [".eslintrc.cjs", "vitest.config.ts"],
}
],
};
6 changes: 5 additions & 1 deletion packages/allure-vitest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@
"dist"
],
"scripts": {
"clean": "rimraf ./dist",
"allure-report": "allure serve ./out/allure-results",
"clean": "rimraf ./dist ./out",
"compile": "tsc --project ./tsconfig.json",
"generate-report": "allure generate ./out/allure-results -o ./out/allure-report --clean --single-file",
"lint": "eslint ./src ./test --ext .ts",
"lint:fix": "eslint ./src ./test --ext .ts --fix",
"pretest": "run-p clean compile",
"test": "vitest run"
},
"dependencies": {
Expand All @@ -52,6 +55,7 @@
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"@vitest/runner": "^1.6.0",
"allure-commandline": "^2.29.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.28.1",
Expand Down
6 changes: 6 additions & 0 deletions packages/allure-vitest/src/VitestTestRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ export class VitestTestRuntime extends MessageTestRuntime {
const currentSuite = getCurrentSuite();
if (currentSuite) {
currentSuite.tasks.forEach((task) => processTask(task, message));
return Promise.resolve();
}
// eslint-disable-next-line no-console
console.error(
"no vitest context is detected. Please ensure you're using allure API within vitest test (it, test) " +
"or setup (beforeAll, beforeEach, afterAll, afterEach) function. Make sure [email protected] or above is used",
);
return Promise.resolve();
}
}
Expand Down
7 changes: 2 additions & 5 deletions packages/allure-vitest/src/reporter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { basename, normalize, relative } from "node:path";
import { normalize, relative } from "node:path";
import { cwd } from "node:process";
import type { File, Reporter, Task } from "vitest";
import { LabelName, Stage, Status } from "allure-js-commons";
Expand Down Expand Up @@ -82,10 +82,7 @@ export default class AllureVitestReporter implements Reporter {
}

const suitePath = getSuitePath(task);
const normalizedTestPath = normalize(relative(cwd(), task.file!.filepath))
.replace(/^\//, "")
.split("/")
.filter((item: string) => item !== basename(task.file!.filepath));
const normalizedTestPath = normalize(relative(cwd(), task.file!.filepath)).replace(/^\//, "").split("/");
const titleMetadata = extractMetadataFromString(task.name);
const testDisplayName = titleMetadata.cleanTitle || task.name;
const testFullname = getTestFullName(task, cwd());
Expand Down
16 changes: 9 additions & 7 deletions packages/allure-vitest/test/spec/categories.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { join } from "node:path";
import { expect, it } from "vitest";
import { describe, expect, it } from "vitest";
import { runVitestInlineTest } from "../utils.js";

it("should support categories", async () => {
const { categories } = await runVitestInlineTest(
`
describe("categories", () => {
it("should support categories", async () => {
const { categories } = await runVitestInlineTest(
`
import { test } from "vitest";

test("sample test", async () => {
});
`,
(testDir) => `
(testDir) => `
import { defineConfig } from "vitest/config";

export default defineConfig({
Expand All @@ -34,7 +35,8 @@ it("should support categories", async () => {
},
});
`,
);
);

expect(categories).toEqual(expect.arrayContaining([({ name: "first" }, { name: "second" })]));
expect(categories).toEqual(expect.arrayContaining([{ name: "first" }, { name: "second" }]));
});
});
16 changes: 9 additions & 7 deletions packages/allure-vitest/test/spec/dataTable.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { expect, it } from "vitest";
import { describe, expect, it } from "vitest";
import { runVitestInlineTest } from "../utils.js";

it("handles data table", async () => {
const { tests } = await runVitestInlineTest(`
describe("data tables", () => {
it("should support tests with data table", async () => {
const { tests } = await runVitestInlineTest(`
import { test, expect } from "vitest";
import { label } from "allure-js-commons";

Expand All @@ -15,8 +16,9 @@ it("handles data table", async () => {
})
`);

expect(tests).toHaveLength(3);
expect(tests[0].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
expect(tests[1].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
expect(tests[2].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
expect(tests).toHaveLength(3);
expect(tests[0].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
expect(tests[1].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
expect(tests[2].labels).toContainEqual(expect.objectContaining({ name: "foo", value: "bar" }));
});
});
Loading
Loading