Skip to content

Commit 46528e3

Browse files
committed
add timestamp test && fix vitest issue
1 parent 63ddcf5 commit 46528e3

File tree

8 files changed

+109
-38
lines changed

8 files changed

+109
-38
lines changed

packages/allure-js-commons/src/sdk/reporter/ReporterRuntime.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ export class ReporterRuntime {
758758
fileExtension: message.fileExtension,
759759
});
760760

761-
this.#writeGlobals(`${randomUuid()}-globals.json`, {
761+
this.#writeGlobals({
762762
attachments: [this.#createGlobalAttachment(message.name, message.contentType, attachmentSource)],
763763
errors: [],
764764
});
@@ -770,14 +770,14 @@ export class ReporterRuntime {
770770
fileExtension: message.fileExtension ?? extname(message.path),
771771
});
772772

773-
this.#writeGlobals(`${randomUuid()}-globals.json`, {
773+
this.#writeGlobals({
774774
attachments: [this.#createGlobalAttachment(message.name, message.contentType, attachmentSource)],
775775
errors: [],
776776
});
777777
};
778778

779779
#handleGlobalErrorMessage = (message: RuntimeGlobalErrorMessage["data"]) => {
780-
this.#writeGlobals(`${randomUuid()}-globals.json`, {
780+
this.#writeGlobals({
781781
attachments: [],
782782
errors: [{ ...message, timestamp: Date.now() }],
783783
});
@@ -832,8 +832,8 @@ export class ReporterRuntime {
832832
timestamp: Date.now(),
833833
});
834834

835-
#writeGlobals = (distFileName: string, globals: Globals): void => {
836-
this.writer.writeGlobals(distFileName, globals);
835+
#writeGlobals = (globals: Globals): void => {
836+
this.writer.writeGlobals(`${randomUuid()}-globals.json`, globals);
837837
};
838838

839839
#writeFixturesOfScope = ({ fixtures, tests }: TestScope) => {

packages/allure-js-commons/test/sdk/reporter/ReporterRuntime.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,48 @@ describe("ReporterRuntime", () => {
997997
);
998998
});
999999

1000+
it("should set global timestamps within message processing window", () => {
1001+
const writer = mockWriter();
1002+
const runtime = new ReporterRuntime({ writer });
1003+
const before = Date.now();
1004+
1005+
runtime.applyGlobalRuntimeMessages([
1006+
{
1007+
type: "global_attachment_content",
1008+
data: {
1009+
name: "setup-log",
1010+
content: Buffer.from("hello", "utf-8").toString("base64"),
1011+
encoding: "base64",
1012+
contentType: "text/plain",
1013+
fileExtension: ".txt",
1014+
},
1015+
},
1016+
{
1017+
type: "global_error",
1018+
data: {
1019+
message: "setup failed",
1020+
trace: "stack",
1021+
},
1022+
},
1023+
]);
1024+
1025+
const after = Date.now();
1026+
const globalsPayloads = writer.writeGlobals.mock.calls.map(([, globals]) => globals);
1027+
const attachmentTimestamps = globalsPayloads.flatMap((globals) => globals.attachments.map((a) => a.timestamp));
1028+
const errorTimestamps = globalsPayloads.flatMap((globals) => globals.errors.map((e) => e.timestamp));
1029+
1030+
expect(attachmentTimestamps).toHaveLength(1);
1031+
expect(errorTimestamps).toHaveLength(1);
1032+
attachmentTimestamps.forEach((timestamp) => {
1033+
expect(timestamp).toBeGreaterThanOrEqual(before);
1034+
expect(timestamp).toBeLessThanOrEqual(after);
1035+
});
1036+
errorTimestamps.forEach((timestamp) => {
1037+
expect(timestamp).toBeGreaterThanOrEqual(before);
1038+
expect(timestamp).toBeLessThanOrEqual(after);
1039+
});
1040+
});
1041+
10001042
it("should write global attachment from path", () => {
10011043
const writer = mockWriter();
10021044
const runtime = new ReporterRuntime({ writer });

packages/allure-mocha/test/samples/spec/globals/runtimeGlobals.spec.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
// cjs: const { it } = require("mocha");
2+
// cjs: const { writeFileSync } = require("node:fs");
3+
// cjs: const { join } = require("node:path");
4+
// cjs: const { globalAttachment, globalAttachmentPath, globalError } = require("allure-js-commons");
5+
// esm: import { it } from "mocha";
6+
// esm: import { writeFileSync } from "node:fs";
7+
// esm: import { join } from "node:path";
8+
// esm: import { globalAttachment, globalAttachmentPath, globalError } from "allure-js-commons";
9+
110
it("a test", async () => {
2-
const { writeFileSync } = await import("node:fs");
3-
const { join } = await import("node:path");
4-
const { globalAttachment, globalAttachmentPath, globalError } = await import("allure-js-commons");
511
const pathAttachmentFile = join(process.cwd(), "global-path.log");
612
writeFileSync(pathAttachmentFile, "hello-from-path", "utf8");
713

packages/allure-mocha/test/samples/spec/globals/runtimeGlobalsContexts.spec.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
// cjs: const { after, before, it } = require("mocha");
2+
// esm: import { after, before, it } from "mocha";
3+
14
void (async () => {
2-
const { globalError } = await import("allure-js-commons");
3-
await globalError({ message: "module scope error" });
5+
const { globalError: emitGlobalError } = await import("allure-js-commons");
6+
await emitGlobalError({ message: "module scope error" });
47
})();
58

69
before(async () => {

packages/allure-mocha/test/samples/spec/globals/runtimeGlobalsSetupOnly.spec.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
const { writeFileSync } = require("node:fs");
2-
const { join } = require("node:path");
3-
const { globalAttachment, globalAttachmentPath, globalError } = require("allure-js-commons");
1+
// cjs: const { writeFileSync } = require("node:fs");
2+
// cjs: const { join } = require("node:path");
3+
// cjs: const { globalAttachment, globalAttachmentPath, globalError } = require("allure-js-commons");
4+
// esm: import { writeFileSync } from "node:fs";
5+
// esm: import { join } from "node:path";
6+
// esm: import { globalAttachment, globalAttachmentPath, globalError } from "allure-js-commons";
47

58
const setupFilePath = join(process.cwd(), "setup-only.log");
69
writeFileSync(setupFilePath, "from-path", "utf8");

packages/allure-vitest/src/VitestTestRuntime.ts

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,26 @@ import { MessageTestRuntime } from "allure-js-commons/sdk/runtime";
55

66
const ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_KEY = "__allureVitestGlobalRuntimeMessages";
77
const ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY = "allureGlobalRuntimeMessages";
8+
const ALLURE_VITEST_RUNTIME_MESSAGES_META_KEY = "allureRuntimeMessages";
9+
10+
type RuntimeMessageMetaKey =
11+
| typeof ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY
12+
| typeof ALLURE_VITEST_RUNTIME_MESSAGES_META_KEY;
13+
type RuntimeMessageTaskMeta = TaskMeta & {
14+
[ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY]?: RuntimeMessage[];
15+
[ALLURE_VITEST_RUNTIME_MESSAGES_META_KEY]?: RuntimeMessage[];
16+
};
817

918
const addGlobalMessage = (message: RuntimeMessage) => {
1019
const holder = globalThis as unknown as Record<string, RuntimeMessage[] | undefined>;
1120
const messages = (holder[ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_KEY] ??= []);
1221
messages.push(message);
1322
};
1423

15-
const addGlobalMessageToMeta = (meta: TaskMeta, message: RuntimeMessage) => {
16-
// @ts-ignore
17-
if (!meta[ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY]) {
18-
// @ts-ignore
19-
meta[ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY] = [];
20-
}
21-
// @ts-ignore
22-
meta[ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY].push(message);
24+
const addMessageToMeta = (meta: TaskMeta, key: RuntimeMessageMetaKey, message: RuntimeMessage) => {
25+
const typedMeta = meta as RuntimeMessageTaskMeta;
26+
const messages = (typedMeta[key] ??= []);
27+
messages.push(message);
2328
};
2429

2530
export const takeGlobalRuntimeMessages = (): RuntimeMessage[] => {
@@ -35,17 +40,18 @@ export class VitestTestRuntime extends MessageTestRuntime {
3540

3641
if (isGlobalRuntimeMessage(message)) {
3742
if (currentTest) {
38-
addGlobalMessageToMeta(currentTest.meta, message);
43+
addMessageToMeta(currentTest.meta, ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY, message);
3944
return Promise.resolve();
4045
}
4146

4247
try {
4348
const currentSuite = getCurrentSuite();
4449

4550
if (currentSuite) {
46-
// @ts-ignore
47-
currentSuite.tasks.forEach((task) => processTask(task, message, true));
48-
return Promise.resolve();
51+
const hasTargetTest = attachGlobalMessageToFirstTest(currentSuite, message);
52+
if (hasTargetTest) {
53+
return Promise.resolve();
54+
}
4955
}
5056
} catch {}
5157

@@ -63,8 +69,7 @@ export class VitestTestRuntime extends MessageTestRuntime {
6369
const currentSuite = getCurrentSuite();
6470

6571
if (currentSuite) {
66-
// @ts-ignore
67-
currentSuite.tasks.forEach((task) => processTask(task, message));
72+
processTask(currentSuite, message);
6873
return Promise.resolve();
6974
}
7075
} catch {}
@@ -87,7 +92,7 @@ const processTask = (task: Task | SuiteCollector, message: RuntimeMessage, isGlo
8792
break;
8893
case "test":
8994
if (isGlobal) {
90-
addGlobalMessageToMeta(task.meta, message);
95+
addMessageToMeta(task.meta, ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY, message);
9196
} else {
9297
addMessage(task.meta, message);
9398
}
@@ -97,12 +102,23 @@ const processTask = (task: Task | SuiteCollector, message: RuntimeMessage, isGlo
97102
}
98103
};
99104

100-
const addMessage = (meta: TaskMeta, message: RuntimeMessage) => {
101-
// @ts-ignore
102-
if (!meta.allureRuntimeMessages) {
103-
// @ts-ignore
104-
meta.allureRuntimeMessages = [];
105+
// beforeAll is suite-scoped in Vitest (no current test context):
106+
// https://main.vitest.dev/api/hooks#beforeall
107+
// Bind a global message to the first test task to avoid duplicating it across every
108+
// test in the suite when suite-level globals are later collected.
109+
const attachGlobalMessageToFirstTest = (task: Task | SuiteCollector, message: RuntimeMessage): boolean => {
110+
switch (task.type) {
111+
case "collector":
112+
case "suite":
113+
return task.tasks.some((sub) => attachGlobalMessageToFirstTest(sub, message));
114+
case "test":
115+
addMessageToMeta(task.meta, ALLURE_VITEST_GLOBAL_RUNTIME_MESSAGES_META_KEY, message);
116+
return true;
117+
default:
118+
return false;
105119
}
106-
// @ts-ignore
107-
meta.allureRuntimeMessages.push(message);
120+
};
121+
122+
const addMessage = (meta: TaskMeta, message: RuntimeMessage) => {
123+
addMessageToMeta(meta, ALLURE_VITEST_RUNTIME_MESSAGES_META_KEY, message);
108124
};

packages/allure-vitest/test/spec/runtime/modern/globals.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ it("writes globals payload from runtime API calls", async () => {
1212
await globalError({ message: "global setup failed", trace: "stack" });
1313
});
1414
15-
test("passes", () => {});
15+
test("passes 1", () => {});
16+
test("passes 2", () => {});
1617
`,
1718
});
1819

packages/allure-vitest/test/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ export const runVitestInlineTest = async (
3232
const configFilename = "vitest.config.ts";
3333
const configPath = join(testDir, configFilename);
3434
// getPosixPath allows us to interpolate such paths without escaping
35-
const setupModulePath = getPosixPath(join(fileDirname, "..", "src", "setup.ts"));
36-
const reporterModulePath = getPosixPath(join(fileDirname, "..", "src", "reporter.ts"));
35+
const setupModulePath = getPosixPath(require.resolve("allure-vitest/setup"));
36+
const reporterModulePath = getPosixPath(require.resolve("allure-vitest/reporter"));
3737
const allureResultsPath = getPosixPath(join(testDir, "allure-results"));
3838
const fixtureAccessorOpts = {
3939
setupModulePath,

0 commit comments

Comments
 (0)