From 5610cd8c34afef6702151676afe248937b588e6e Mon Sep 17 00:00:00 2001 From: Hamed Bavar Date: Sun, 6 Sep 2026 08:48:10 +0330 Subject: [PATCH 1/3] fix(snapshot): report obsolete keys next to skipped tests --- packages/snapshot/src/port/state.ts | 5 +- test/e2e/snapshots/skip-test.test.ts | 91 +++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/packages/snapshot/src/port/state.ts b/packages/snapshot/src/port/state.ts index 2fec430b8460..599d32aa1ec6 100644 --- a/packages/snapshot/src/port/state.ts +++ b/packages/snapshot/src/port/state.ts @@ -147,10 +147,13 @@ export default class SnapshotState { markSnapshotsAsCheckedForTest(testName: string): void { this._uncheckedKeys.forEach((uncheckedKey) => { + if (!uncheckedKey.startsWith(testName)) { + return + } // skip snapshots with following keys // testName n // testName > xxx n (this is for toMatchSnapshot("xxx") API) - if (/ \d+$| > /.test(uncheckedKey.slice(testName.length))) { + if (/^ \d+$|^ > /.test(uncheckedKey.slice(testName.length))) { this._uncheckedKeys.delete(uncheckedKey) } }) diff --git a/test/e2e/snapshots/skip-test.test.ts b/test/e2e/snapshots/skip-test.test.ts index cd6ad08901a0..83da300f4d17 100644 --- a/test/e2e/snapshots/skip-test.test.ts +++ b/test/e2e/snapshots/skip-test.test.ts @@ -1,7 +1,7 @@ import fs from 'node:fs' import path from 'node:path' import { expect, test } from 'vitest' -import { runVitest } from '../../test-utils' +import { runInlineTests, runVitest } from '../../test-utils' test('snapshots in skipped test/suite is not obsolete', async () => { // create snapshot on first run @@ -114,3 +114,92 @@ test('handle obsoleteness of toMatchSnapshot("custom message")', async () => { " `) }) + +test('obsolete snapshots are still reported when another test is skipped', async () => { + const structure = { + 'basic.test.ts': ` + import { expect, it } from 'vitest' + + it.skip('a', () => { + expect(0).toMatchSnapshot() + }) + + it('b', () => { + expect(1).toMatchSnapshot() + }) + `, + '__snapshots__/basic.test.ts.snap': `// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[\`a 1\`] = \`0\`; + +exports[\`b 1\`] = \`1\`; + +exports[\`removed test 1\`] = \`2\`; +`, + } + + const failed = await runInlineTests(structure, { update: 'none' }) + expect(failed.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "__module_errors__": [ + "Obsolete snapshots found when no snapshot update is expected. + · removed test 1 + ", + ], + "a": "skipped", + "b": "passed", + }, + } + `) + + const updated = await runInlineTests(structure, { update: true }) + expect(fs.readFileSync(path.join(updated.root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` + "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + + exports[\`a 1\`] = \`0\`; + + exports[\`b 1\`] = \`1\`; + " + `) +}) + +test('skipped test does not hide obsolete snapshots of a test with a longer name', async () => { + const result = await runInlineTests({ + 'basic.test.ts': ` + import { expect, it } from 'vitest' + + it.skip('foo', () => { + expect(0).toMatchSnapshot() + expect(0).toMatchSnapshot('custom') + }) + + it('bar', () => { + expect(1).toMatchSnapshot() + }) + `, + '__snapshots__/basic.test.ts.snap': `// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[\`bar 1\`] = \`1\`; + +exports[\`foo 1\`] = \`0\`; + +exports[\`foo > custom 1\`] = \`0\`; + +exports[\`foobar 1\`] = \`0\`; +`, + }, { update: 'none' }) + expect(result.errorTree()).toMatchInlineSnapshot(` + { + "basic.test.ts": { + "__module_errors__": [ + "Obsolete snapshots found when no snapshot update is expected. + · foobar 1 + ", + ], + "bar": "passed", + "foo": "skipped", + }, + } + `) +}) From 4f3c397a69eff469788c81c3d534ac1423be1d20 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:44:17 +0900 Subject: [PATCH 2/3] refactor(snapshot): combine skipped key conditions Co-authored-by: OpenCode (gpt-6-astra) --- packages/snapshot/src/port/state.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/snapshot/src/port/state.ts b/packages/snapshot/src/port/state.ts index 599d32aa1ec6..4c46373a4890 100644 --- a/packages/snapshot/src/port/state.ts +++ b/packages/snapshot/src/port/state.ts @@ -147,13 +147,13 @@ export default class SnapshotState { markSnapshotsAsCheckedForTest(testName: string): void { this._uncheckedKeys.forEach((uncheckedKey) => { - if (!uncheckedKey.startsWith(testName)) { - return - } // skip snapshots with following keys // testName n // testName > xxx n (this is for toMatchSnapshot("xxx") API) - if (/^ \d+$|^ > /.test(uncheckedKey.slice(testName.length))) { + if ( + uncheckedKey.startsWith(testName) + && /^ \d+$|^ > /.test(uncheckedKey.slice(testName.length)) + ) { this._uncheckedKeys.delete(uncheckedKey) } }) From aa67028d116194820c821cbc1cf8ddaef4a602de Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa <4232207+hi-ogawa@users.noreply.github.com> Date: Mon, 7 Sep 2026 12:46:34 +0900 Subject: [PATCH 3/3] test(snapshot): use explicit update mode Co-authored-by: OpenCode (gpt-6-astra) --- test/e2e/snapshots/skip-test.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/snapshots/skip-test.test.ts b/test/e2e/snapshots/skip-test.test.ts index 83da300f4d17..5252f05b92a3 100644 --- a/test/e2e/snapshots/skip-test.test.ts +++ b/test/e2e/snapshots/skip-test.test.ts @@ -153,7 +153,7 @@ exports[\`removed test 1\`] = \`2\`; } `) - const updated = await runInlineTests(structure, { update: true }) + const updated = await runInlineTests(structure, { update: 'all' }) expect(fs.readFileSync(path.join(updated.root, '__snapshots__/basic.test.ts.snap'), 'utf-8')).toMatchInlineSnapshot(` "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html