diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 521649d37..efa95c608 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -622,7 +622,7 @@ export class Vitest { const specifications: TestSpecification[] = [] for (const file of files) { const project = this.getProjectByName(file.projectName || '') - const specification = project.createSpecification(file.filepath, undefined, file.pool, file.meta) + const specification = project.createSpecification(file.filepath, undefined, file.pool, file.id) specifications.push(specification) } diff --git a/packages/vitest/src/node/project.ts b/packages/vitest/src/node/project.ts index 3ff810a69..234bc56a4 100644 --- a/packages/vitest/src/node/project.ts +++ b/packages/vitest/src/node/project.ts @@ -1,4 +1,3 @@ -import type { TaskMeta } from '@vitest/runner/types' import type { GlobOptions } from 'tinyglobby' import type { DevEnvironment, ViteDevServer, InlineConfig as ViteInlineConfig } from 'vite' import type { ModuleRunner } from 'vite/module-runner' @@ -154,14 +153,14 @@ export class TestProject { /** @internal */ pool?: string, /** @internal */ - metaOverride?: TaskMeta, + taskIdOverride?: string, ): TestSpecification { return new TestSpecification( this, moduleId, pool || getFilePoolName(this), locationsOrOptions, - metaOverride, + taskIdOverride, ) } diff --git a/packages/vitest/src/node/test-specification.ts b/packages/vitest/src/node/test-specification.ts index 133251c34..ccd1e52ba 100644 --- a/packages/vitest/src/node/test-specification.ts +++ b/packages/vitest/src/node/test-specification.ts @@ -1,4 +1,3 @@ -import type { TaskMeta } from '@vitest/runner/types' import type { SerializedTestSpecification } from '../runtime/types/utils' import type { TestProject } from './project' import type { TestModule } from './reporters/reported-tasks' @@ -56,14 +55,14 @@ export class TestSpecification { moduleId: string, pool: Pool, testLinesOrOptions?: number[] | TestSpecificationOptions | undefined, - // merge-reports uses the original `file.meta` from the test run - metaOverride?: TaskMeta, + // merge-reports forces the original task id from the test run + taskIdOverride?: string, ) { const projectName = project.config.name - this.taskId = generateFileHash( + this.taskId = taskIdOverride ?? generateFileHash( relative(project.config.root, moduleId), projectName, - metaOverride ?? { typecheck: pool === 'typescript', __vitest_label__: project.config.mergeReportsLabel }, + { typecheck: pool === 'typescript', __vitest_label__: project.config.mergeReportsLabel }, ) this.project = project this.moduleId = moduleId diff --git a/test/e2e/test/reporters/merge-reports.test.ts b/test/e2e/test/reporters/merge-reports.test.ts index 36a29856b..961955bc4 100644 --- a/test/e2e/test/reporters/merge-reports.test.ts +++ b/test/e2e/test/reporters/merge-reports.test.ts @@ -2,8 +2,9 @@ import type { RunVitestConfig } from '#test-utils' import type { File, Test } from '@vitest/runner/types' import type { TestUserConfig, Vitest } from 'vitest/node' import type { MergeReport } from 'vitest/src/node/reporters/blob.js' -import { existsSync, readdirSync, rmSync } from 'node:fs' +import { cpSync, existsSync, readdirSync, rmSync } from 'node:fs' import { mkdir, writeFile } from 'node:fs/promises' +import path from 'node:path' import { buildTestTree, runVitest, useFS } from '#test-utils' import { playwright } from '@vitest/browser-playwright' import { createFileTask } from '@vitest/runner/utils' @@ -1026,6 +1027,69 @@ test("top-test", () => {}) `) }) +test('onTestRunEnd(testModules) are preserved from different test run roots', async () => { + const root1 = resolve(process.cwd(), `vitest-test-${crypto.randomUUID()}`) + const root2 = resolve(process.cwd(), `vitest-test-${crypto.randomUUID()}`) + useFS(root1, { + 'basic.test.ts': `test("ok", () => {})`, + }) + useFS(root2, { + 'basic.test.ts': `test("ok", () => {})`, + }) + + const result1 = await runVitest({ + root: root1, + globals: true, + reporters: [['blob', { label: 'linux' }]], + }) + expect(result1.stderr).toMatchInlineSnapshot(`""`) + expect(result1.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "ok": "passed", + }, + } + `) + + const result2 = await runVitest({ + root: root2, + globals: true, + reporters: [['blob', { label: 'macos' }]], + }) + expect(result2.stderr).toMatchInlineSnapshot(`""`) + expect(result2.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "ok": "passed", + }, + } + `) + + const blobDir1 = path.join(root1, '.vitest/blob') + const blobDir2 = path.join(root2, '.vitest/blob') + for (const filename of readdirSync(blobDir2)) { + cpSync(path.join(blobDir2, filename), path.join(blobDir1, filename)) + } + + const result = await runVitest({ + root: root1, + mergeReports: blobDir1, + }) + expect(result.stderr).toMatchInlineSnapshot(`""`) + // previously this was "1 passed" due to broken onTestRunEnd(testModules) + expect(result.stdout).toContain('Test Files 2 passed') + expect(result.errorTree({ fileLabel: true })).toMatchInlineSnapshot(` + { + "basic.test.ts (linux)": { + "ok": "passed", + }, + "basic.test.ts (macos)": { + "ok": "passed", + }, + } + `) +}) + async function writeBlob(content: MergeReport, filename: string): Promise { const report = stringify(content)