diff --git a/test/browser/fixtures/update-snapshot/__snapshots__/basic.test.ts.snap b/test/browser/fixtures/update-snapshot/__snapshots__/basic.test.ts.snap new file mode 100644 index 000000000000..e9b0ef842a27 --- /dev/null +++ b/test/browser/fixtures/update-snapshot/__snapshots__/basic.test.ts.snap @@ -0,0 +1,3 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`basic 1`] = `1`; diff --git a/test/browser/fixtures/update-snapshot/basic.test.ts b/test/browser/fixtures/update-snapshot/basic.test.ts new file mode 100644 index 000000000000..df50f69fe77e --- /dev/null +++ b/test/browser/fixtures/update-snapshot/basic.test.ts @@ -0,0 +1,5 @@ +import { expect, test } from 'vitest' + +test('basic', () => { + expect(1).toMatchSnapshot() +}) diff --git a/test/browser/fixtures/update-snapshot/vitest.config.ts b/test/browser/fixtures/update-snapshot/vitest.config.ts new file mode 100644 index 000000000000..0389002e930a --- /dev/null +++ b/test/browser/fixtures/update-snapshot/vitest.config.ts @@ -0,0 +1,26 @@ +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { defineConfig } from 'vitest/config' + +/* +manually test snapshot by + pnpm -C test/browser test-fixtures --root fixtures/update-snapshot +*/ + +const provider = process.env.PROVIDER || 'webdriverio' +const browser = + process.env.BROWSER || (provider === 'playwright' ? 'chromium' : 'chrome') + +export default defineConfig({ + test: { + browser: { + enabled: true, + provider, + name: browser, + }, + }, + cacheDir: path.join( + path.dirname(fileURLToPath(import.meta.url)), + 'node_modules/.vite' + ), +}) diff --git a/test/browser/package.json b/test/browser/package.json index 5131b1c5c03c..329c30e07863 100644 --- a/test/browser/package.json +++ b/test/browser/package.json @@ -7,6 +7,7 @@ "test:webdriverio": "PROVIDER=webdriverio node --test --test-concurrency=1 specs/", "test:playwright": "PROVIDER=playwright node --test --test-concurrency=1 specs/", "test:safaridriver": "PROVIDER=webdriverio BROWSER=safari node --test --test-concurrency=1 specs/", + "test-fixtures": "vitest", "coverage": "vitest --coverage.enabled --coverage.provider=istanbul --browser.headless=yes" }, "devDependencies": { diff --git a/test/browser/specs/update-snapshot.test.mjs b/test/browser/specs/update-snapshot.test.mjs new file mode 100644 index 000000000000..7e24ac1f34d7 --- /dev/null +++ b/test/browser/specs/update-snapshot.test.mjs @@ -0,0 +1,70 @@ +import assert from 'node:assert' +import fs from 'node:fs' +import test from 'node:test' +import { startVitest } from 'vitest/node' + +let vitest + +test.after(async () => { + await vitest?.close() +}) + +test('update snapshot', async () => { + // setup wrong snapshot value + const snapshotPath = './fixtures/update-snapshot/__snapshots__/basic.test.ts.snap' + await editFile(snapshotPath, data => data.replace('`1`', '`2`')) + + // run vitest watch mode + const result = await wrapExit(() => startVitest('test', [], { + watch: true, + root: './fixtures/update-snapshot', + reporters: ['tap-flat'], // use simple reporter to not pollute stdout + browser: { headless: true }, + })) + vitest = result.value + assert.ok(vitest) + + // test fails + assert.equal(result.exitCode, 1) + assert.equal(vitest.state.getFiles()[0].result.state, 'fail') + + // updateSnapshot API to simulate "u" commmand + await vitest.updateSnapshot() + + // verify snapshot value is updated + const snapshotData = await fs.promises.readFile(snapshotPath, 'utf-8') + assert.match(snapshotData, /`1`/) + + // test passes + assert.equal(vitest.state.getFiles()[0].result.state, 'pass') +}) + +/** + * @param {string} filepath + * @param {(data: string) => string} edit + */ +async function editFile(filepath, edit) { + const data = await fs.promises.readFile(filepath, 'utf-8') + await fs.promises.writeFile(filepath, edit(data)) +} + +/** + * run function and return mutated exitCode while preserving current exitCode + * @param {() => any} f + */ +async function wrapExit(f) { + const prevExitCode = process.exitCode + const prevExit = process.exit + process.exit = () => {} + /** @type {{ value?: any, exitCode?: number }} */ + const result = {} + try { + result.value = await f() + } + finally { + result.exitCode = process.exitCode + process.exitCode = prevExitCode + process.exit = prevExit + } + return result +}