diff --git a/packages/vitest/src/runtime/runners/test.ts b/packages/vitest/src/runtime/runners/test.ts index 72e1d17e0d08..6f1edeccd55c 100644 --- a/packages/vitest/src/runtime/runners/test.ts +++ b/packages/vitest/src/runtime/runners/test.ts @@ -27,15 +27,15 @@ export class VitestTestRunner implements VitestRunner { this.snapshotClient.clear() } - async onAfterRunFiles() { - const result = await this.snapshotClient.finishCurrentRun() - if (result) - await rpc().snapshotSaved(result) - } - - onAfterRunSuite(suite: Suite) { + async onAfterRunSuite(suite: Suite) { if (this.config.logHeapUsage && typeof process !== 'undefined') suite.result!.heap = process.memoryUsage().heapUsed + + if (suite.mode !== 'skip' && typeof suite.filepath !== 'undefined') { + const result = await this.snapshotClient.finishCurrentRun() + if (result) + await rpc().snapshotSaved(result) + } } onAfterRunTask(test: Test) { @@ -63,14 +63,20 @@ export class VitestTestRunner implements VitestRunner { } clearModuleMocks(this.config) - await this.snapshotClient.startCurrentRun(test.file!.filepath, name, this.workerState.config.snapshotOptions) this.workerState.current = test } - onBeforeRunSuite(suite: Suite) { + async onBeforeRunSuite(suite: Suite) { if (this.cancelRun) suite.mode = 'skip' + + // initialize snapshot state before running file suite + if (suite.mode !== 'skip' && typeof suite.filepath !== 'undefined') { + // default "name" is irrelevant for Vitest since each snapshot assertion + // (e.g. `toMatchSnapshot`) specifies "filepath" / "name" pair explicitly + await this.snapshotClient.startCurrentRun(suite.filepath, '__default_name_', this.workerState.config.snapshotOptions) + } } onBeforeTryTask(test: Test) { diff --git a/test/snapshots/test-update/inline-test-template-concurrent.test.js b/test/snapshots/test-update/inline-test-template-concurrent.test.js new file mode 100644 index 000000000000..ede082eeb681 --- /dev/null +++ b/test/snapshots/test-update/inline-test-template-concurrent.test.js @@ -0,0 +1,13 @@ +import { it } from 'vitest' + +it.concurrent('1st', ({ expect }) => { + expect('hi1').toMatchInlineSnapshot(`"hi1"`) +}) + +it.concurrent('2nd', ({ expect }) => { + expect('hi2').toMatchInlineSnapshot(`"hi2"`) +}) + +it.concurrent('3rd', ({ expect }) => { + expect('hi3').toMatchInlineSnapshot(`"hi3"`) +}) diff --git a/test/snapshots/test/__snapshots__/shapshots-concurrent-sync.test.ts.snap b/test/snapshots/test/__snapshots__/shapshots-concurrent-sync.test.ts.snap new file mode 100644 index 000000000000..aedefeaaf723 --- /dev/null +++ b/test/snapshots/test/__snapshots__/shapshots-concurrent-sync.test.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`concurrent suite > snapshot 1`] = ` +Object { + "foo": "bar", +} +`; diff --git a/test/snapshots/test/__snapshots__/shapshots.test.ts.snap b/test/snapshots/test/__snapshots__/shapshots.test.ts.snap index ed2941fa1a42..a3d90fc6be12 100644 --- a/test/snapshots/test/__snapshots__/shapshots.test.ts.snap +++ b/test/snapshots/test/__snapshots__/shapshots.test.ts.snap @@ -1,5 +1,22 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`concurrent snapshot update 1`] = ` +"import { it } from 'vitest' + +it.concurrent('1st', ({ expect }) => { + expect('hi1').toMatchInlineSnapshot(\`"hi1"\`) +}) + +it.concurrent('2nd', ({ expect }) => { + expect('hi2').toMatchInlineSnapshot(\`"hi2"\`) +}) + +it.concurrent('3rd', ({ expect }) => { + expect('hi3').toMatchInlineSnapshot(\`"hi3"\`) +}) +" +`; + exports[`js snapshots generated correctly 1`] = ` "import { describe, expect, test } from 'vitest' diff --git a/test/snapshots/test/shapshots-concurrent-sync.test.ts b/test/snapshots/test/shapshots-concurrent-sync.test.ts new file mode 100644 index 000000000000..1a46bdd87696 --- /dev/null +++ b/test/snapshots/test/shapshots-concurrent-sync.test.ts @@ -0,0 +1,10 @@ +import { describe, it } from 'vitest' + +// from https://github.com/vitest-dev/vitest/issues/3361 +describe.concurrent('concurrent suite', () => { + it('snapshot', ({ expect }) => { + expect({ foo: 'bar' }).toMatchSnapshot() + }) + + it('empty test') +}) diff --git a/test/snapshots/test/shapshots.test.ts b/test/snapshots/test/shapshots.test.ts index 60886cee40a7..4c7adbedea64 100644 --- a/test/snapshots/test/shapshots.test.ts +++ b/test/snapshots/test/shapshots.test.ts @@ -44,3 +44,9 @@ test('js snapshots generated correctly', async () => { const content = await fs.readFile(path, 'utf8') expect(content).toMatchSnapshot() }) + +test('concurrent snapshot update', async () => { + const path = pathe.resolve(__dirname, '../test-update/inline-test-template-concurrent.test.js') + const content = await fs.readFile(path, 'utf8') + expect(content).toMatchSnapshot() +}) diff --git a/test/snapshots/tools/generate-inline-test.mjs b/test/snapshots/tools/generate-inline-test.mjs index d89d59685a65..3e775e092a71 100644 --- a/test/snapshots/tools/generate-inline-test.mjs +++ b/test/snapshots/tools/generate-inline-test.mjs @@ -15,4 +15,8 @@ const template = resolve(dir, './inline-test-template.js'); (async () => { await generateInlineTest(template, filepath) + await generateInlineTest( + resolve(dir, './inline-test-template-concurrent.js'), + resolve(dir, '../test-update/inline-test-template-concurrent.test.js'), + ) })() diff --git a/test/snapshots/tools/inline-test-template-concurrent.js b/test/snapshots/tools/inline-test-template-concurrent.js new file mode 100644 index 000000000000..6c3ddb1dbca2 --- /dev/null +++ b/test/snapshots/tools/inline-test-template-concurrent.js @@ -0,0 +1,13 @@ +import { it } from 'vitest' + +it.concurrent('1st', ({ expect }) => { + expect('hi1').toMatchInlineSnapshot() +}) + +it.concurrent('2nd', ({ expect }) => { + expect('hi2').toMatchInlineSnapshot() +}) + +it.concurrent('3rd', ({ expect }) => { + expect('hi3').toMatchInlineSnapshot() +})