vitest/test/browser/specs/to-match-screenshot.test.ts

172 lines
5.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 { extractToMatchScreenshotPaths } from '../fixtures/expect-dom/utils'
import utilsContent from '../fixtures/expect-dom/utils?raw'
const testFilename = 'basic.test.ts'
const testName = 'screenshot-snapshot'
const bgColor = '#fff'
const testContent = /* ts */`
import { page, server } from 'vitest/browser'
import { describe, test } from 'vitest'
import { render } from './utils'
const dataTestId = 'inline-test'
test('${testName}', async ({ expect }) => {
render('<div data-testid="' + dataTestId + '" style="background-color: ${bgColor};">Inline Test</div>')
await expect(page.getByTestId(dataTestId)).toMatchScreenshot()
})
`
const browser = 'chromium'
export async function runInlineTests(
structure: TestFsStructure,
config: ViteUserConfig['test'] = {},
) {
const root = resolve(process.cwd(), `vitest-test-${crypto.randomUUID()}`)
const fs = useFS(root, {
...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)} }],
},
reporters: ['verbose'],
...${JSON.stringify(config)},
},
}`,
})
const vitest = await runVitestCli({
nodeOptions: {
env: {
CI: 'false',
GITHUB_ACTIONS: undefined,
NO_COLOR: 'true',
},
},
}, '--root', root, '--watch')
return {
fs,
root,
...vitest,
}
}
describe('--watch', () => {
test(
'fails when creating a snapshot for the first time and does NOT update it afterwards',
async () => {
const { fs, stderr, vitest } = await runInlineTests(
{
[testFilename]: testContent,
'utils.ts': utilsContent,
},
)
const [referencePath] = extractToMatchScreenshotPaths(stderr, testName)
expect(stderr).toContain(`No existing reference screenshot found; a new one was created. Review it before running tests again.\n\nReference screenshot:\n ${referencePath}`)
const { atime: _1, atimeMs: _2, ...referenceStat } = fs.statFile(referencePath)
fs.editFile(testFilename, content => `${content}\n`)
vitest.resetOutput()
await vitest.waitForStdout('Test Files 1 passed')
expect(vitest.stdout).toContain('✓ |chromium| basic.test.ts > screenshot-snapshot')
const { atime: _3, atimeMs: _4, ...newReferenceStat } = fs.statFile(referencePath)
expect(referenceStat).toEqual(newReferenceStat)
},
)
test(
'with --update creates snapshots and updates them on change',
async () => {
const { fs, stderr, vitest } = await runInlineTests(
{
[testFilename]: testContent,
'utils.ts': utilsContent,
},
{
update: true,
},
)
expect(stderr).toMatchInlineSnapshot(`""`)
const referencePath = `__screenshots__/${testFilename}/${testName}-1-${browser}-${platform()}.png`
const referenceStat = fs.statFile(referencePath)
fs.editFile(testFilename, content => `${content}\n`)
vitest.resetOutput()
await vitest.waitForStdout('Test Files 1 passed')
expect(vitest.stdout).toContain('✓ |chromium| basic.test.ts > screenshot-snapshot')
const {
atime,
atimeMs,
ctime,
ctimeMs,
mtime,
mtimeMs,
...diffs
} = fs.statFile(referencePath)
expect(referenceStat).toEqual(expect.objectContaining(diffs))
expect(atime.getTime()).toBeGreaterThan(referenceStat.atime.getTime())
expect(ctime.getTime()).toBeGreaterThan(referenceStat.ctime.getTime())
expect(mtime.getTime()).toBeGreaterThan(referenceStat.mtime.getTime())
expect(atimeMs).toBeGreaterThan(referenceStat.atimeMs)
expect(ctimeMs).toBeGreaterThan(referenceStat.ctimeMs)
expect(mtimeMs).toBeGreaterThan(referenceStat.mtimeMs)
},
)
test(
'creates a reference and fails when changing the DOM content',
async () => {
const { fs, stderr, vitest } = await runInlineTests(
{
[testFilename]: testContent,
'utils.ts': utilsContent,
},
)
expect(stderr).toContain(`No existing reference screenshot found; a new one was created. Review it before running tests again.\n\nReference screenshot:`)
fs.editFile(testFilename, content => content.replace(bgColor, '#0ff'))
vitest.resetOutput()
await vitest.waitForStdout('Test Files 1 failed')
expect(vitest.stdout).toContain('× |chromium| basic.test.ts > screenshot-snapshot')
expect(vitest.stdout).toContain('Screenshot does not match the stored reference.')
expect(vitest.stdout).toMatch(/\d+ pixels \(ratio 0.\d{2}\) differ\./)
},
)
})