From 6ffddc0edda44435a7638e779dbae518aefc16c1 Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Wed, 28 Jan 2026 15:37:24 +0100 Subject: [PATCH] feat: accept `new` or `all` in `--update` flag --- docs/config/update.md | 9 ++- docs/guide/cli-generated.md | 4 +- packages/vitest/src/node/cli/cli-config.ts | 3 +- .../vitest/src/node/config/resolveConfig.ts | 4 +- packages/vitest/src/node/types/config.ts | 2 +- .../browser/fixtures/user-event/wheel.test.ts | 2 +- .../browser/specs/to-match-screenshot.test.ts | 74 +++++++++---------- 7 files changed, 48 insertions(+), 50 deletions(-) diff --git a/docs/config/update.md b/docs/config/update.md index 8668b8e20478..a154000bd696 100644 --- a/docs/config/update.md +++ b/docs/config/update.md @@ -5,8 +5,11 @@ outline: deep # update {#update} -- **Type:** `boolean` +- **Type:** `boolean | 'new' | 'all'` - **Default:** `false` -- **CLI:** `-u`, `--update`, `--update=false` +- **CLI:** `-u`, `--update`, `--update=false`, `--update=new` -Update snapshot files. This will update all changed snapshots and delete obsolete ones. +Update snapshot files. The behaviour depends on the value: + +- `true` or `'all'`: updates all changed snapshots and delete obsolete ones +- `new`: generates new snapshots without changing or deleting obsolete ones diff --git a/docs/guide/cli-generated.md b/docs/guide/cli-generated.md index 0b1340c77418..9003015fe1a1 100644 --- a/docs/guide/cli-generated.md +++ b/docs/guide/cli-generated.md @@ -13,10 +13,10 @@ Path to config file ### update -- **CLI:** `-u, --update` +- **CLI:** `-u, --update [type]` - **Config:** [update](/config/update) -Update snapshot +Update snapshot (accepts boolean, "new" or "all") ### watch diff --git a/packages/vitest/src/node/cli/cli-config.ts b/packages/vitest/src/node/cli/cli-config.ts index c7e0711453b8..f7c2efb49c88 100644 --- a/packages/vitest/src/node/cli/cli-config.ts +++ b/packages/vitest/src/node/cli/cli-config.ts @@ -78,7 +78,8 @@ export const cliOptionsConfig: VitestCLIOptions = { }, update: { shorthand: 'u', - description: 'Update snapshot', + description: 'Update snapshot (accepts boolean, "new" or "all")', + argument: '[type]', }, watch: { shorthand: 'w', diff --git a/packages/vitest/src/node/config/resolveConfig.ts b/packages/vitest/src/node/config/resolveConfig.ts index ada18c1f6bea..c61021cadb3d 100644 --- a/packages/vitest/src/node/config/resolveConfig.ts +++ b/packages/vitest/src/node/config/resolveConfig.ts @@ -508,7 +508,9 @@ export function resolveConfig( expand: resolved.expandSnapshotDiff ?? false, snapshotFormat: resolved.snapshotFormat || {}, updateSnapshot: - isCI && !UPDATE_SNAPSHOT ? 'none' : UPDATE_SNAPSHOT ? 'all' : 'new', + UPDATE_SNAPSHOT === 'all' || UPDATE_SNAPSHOT === 'new' + ? UPDATE_SNAPSHOT + : isCI && !UPDATE_SNAPSHOT ? 'none' : UPDATE_SNAPSHOT ? 'all' : 'new', resolveSnapshotPath: options.resolveSnapshotPath, // resolved inside the worker snapshotEnvironment: null as any, diff --git a/packages/vitest/src/node/types/config.ts b/packages/vitest/src/node/types/config.ts index aeb025a06eb2..e65d5b8656dd 100644 --- a/packages/vitest/src/node/types/config.ts +++ b/packages/vitest/src/node/types/config.ts @@ -365,7 +365,7 @@ export interface InlineConfig { * * @default false */ - update?: boolean + update?: boolean | 'all' | 'new' /** * Watch mode diff --git a/test/browser/fixtures/user-event/wheel.test.ts b/test/browser/fixtures/user-event/wheel.test.ts index 950d9e4af5b8..9d6dc4f99dec 100644 --- a/test/browser/fixtures/user-event/wheel.test.ts +++ b/test/browser/fixtures/user-event/wheel.test.ts @@ -25,7 +25,7 @@ describe.for([ await (testType === 'userEvent' ? userEvent.wheel(selector, options) : selector.wheel(options)) - expect(wheel).toHaveBeenCalledOnce() + await expect.poll(() => wheel).toHaveBeenCalledOnce() expect(wheel.mock.calls[0][0].deltaX).toBe(deltaX) expect(wheel.mock.calls[0][0].deltaY).toBe(deltaY) }) diff --git a/test/browser/specs/to-match-screenshot.test.ts b/test/browser/specs/to-match-screenshot.test.ts index 1591bb5bbacb..f5e196222dd2 100644 --- a/test/browser/specs/to-match-screenshot.test.ts +++ b/test/browser/specs/to-match-screenshot.test.ts @@ -1,11 +1,11 @@ import type { ViteUserConfig } from 'vitest/config' import type { TestFsStructure } from '../../test-utils' import { platform } from 'node:os' -import { resolve } from 'node:path' import { describe, expect, test } from 'vitest' -import { runVitestCli, useFS } from '../../test-utils' +import { runInlineTests } from '../../test-utils' import { extractToMatchScreenshotPaths } from '../fixtures/expect-dom/utils' import utilsContent from '../fixtures/expect-dom/utils?raw' +import { provider } from '../settings' const testFilename = 'basic.test.ts' const testName = 'screenshot-snapshot' @@ -27,57 +27,46 @@ test('${testName}', async ({ expect }) => { const browser = 'chromium' -async function runInlineTests( +async function runBrowserTests( structure: TestFsStructure, config: ViteUserConfig['test'] = {}, ) { - const root = resolve(process.cwd(), `vitest-test-${crypto.randomUUID()}`) - - const fs = useFS(root, { + return runInlineTests({ ...structure, - 'vitest.config.ts': ` - import { playwright } from '@vitest/browser-playwright' - export default { - test: { - browser: { - enabled: true, - screenshotFailures: false, - provider: playwright(), - headless: true, - instances: [{ browser: ${JSON.stringify(browser)} }], + 'vitest.config.js': ` + import { playwright } from '@vitest/browser-playwright' + export default { + test: { + browser: { + enabled: true, + screenshotFailures: false, + provider: playwright(), + headless: true, + instances: [{ browser: ${JSON.stringify(browser)} }], + }, + reporters: ['verbose'], + ...${JSON.stringify(config)}, }, - reporters: ['verbose'], - ...${JSON.stringify(config)}, - }, - }`, - }) - - const vitest = await runVitestCli({ - nodeOptions: { - env: { - CI: 'false', - GITHUB_ACTIONS: undefined, - NO_COLOR: 'true', - }, + }`, + }, { + $cliOptions: { + watch: true, }, - }, '--root', root, '--watch') - - return { - fs, - root, - ...vitest, - } + }) } -describe('--watch', () => { +describe.runIf(provider.name === 'playwright')('--watch', () => { test( 'fails when creating a snapshot for the first time and does NOT update it afterwards', async () => { - const { fs, stderr, vitest } = await runInlineTests( + const { fs, stderr, vitest } = await runBrowserTests( { [testFilename]: testContent, 'utils.ts': utilsContent, }, + { + update: 'new', + }, ) const [referencePath] = extractToMatchScreenshotPaths(stderr, testName) @@ -102,11 +91,14 @@ describe('--watch', () => { test( 'creates a reference and fails when changing the DOM content', async () => { - const { fs, stderr, vitest } = await runInlineTests( + const { fs, stderr, vitest } = await runBrowserTests( { [testFilename]: testContent, 'utils.ts': utilsContent, }, + { + update: 'new', + }, ) expect(stderr).toContain(`No existing reference screenshot found; a new one was created. Review it before running tests again.\n\nReference screenshot:`) @@ -126,7 +118,7 @@ describe('--watch', () => { test( 'creates snapshot and does NOT update it if reference matches', async () => { - const { fs, stderr, vitest } = await runInlineTests( + const { fs, stderr, vitest } = await runBrowserTests( { [testFilename]: testContent, 'utils.ts': utilsContent, @@ -174,7 +166,7 @@ describe('--watch', () => { test( 'creates snapshot and updates it if reference mismatches', async () => { - const { fs, stderr, vitest } = await runInlineTests( + const { fs, stderr, vitest } = await runBrowserTests( { [testFilename]: testContent, 'utils.ts': utilsContent,