Skip to content

Commit a60ded0

Browse files
authored
feat!: add screenshotDirectory config to browser.expect.toMatchScreenshot (#10592)
1 parent a6c0a97 commit a60ded0

5 files changed

Lines changed: 92 additions & 15 deletions

File tree

docs/config/browser/expect.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,19 @@ export default defineConfig({
4646
can be configured here. Additionally, two path resolution functions are
4747
available: `resolveScreenshotPath` and `resolveDiffPath`.
4848

49+
## browser.expect.toMatchScreenshot.screenshotDirectory
50+
51+
- **Type:** `string | undefined`
52+
- **Default:** `__screenshots__`
53+
54+
The directory name used for storing reference screenshots.
55+
56+
This value is passed as `screenshotDirectory` to [`browser.expect.toMatchScreenshot.resolveScreenshotPath`](#browserexpecttomatchscreenshotresolvescreenshotpath) and [`browser.expect.toMatchScreenshot.resolveDiffPath`](#browserexpecttomatchscreenshotresolvediffpath), and used in the default path resolution of `resolveScreenshotPath`.
57+
4958
## browser.expect.toMatchScreenshot.resolveScreenshotPath
5059

5160
- **Type:** `(data: PathResolveData) => string`
52-
- **Default output:** `` `${root}/${testFileDirectory}/${screenshotDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
61+
- **Default output:** ``path.resolve(root, testFileDirectory, screenshotDirectory, testFileName, `${arg}-${browserName}-${platform}${ext}`)``
5362

5463
A function to customize where reference screenshots are stored. The function
5564
receives an object with the following properties:
@@ -92,9 +101,7 @@ receives an object with the following properties:
92101

93102
- `screenshotDirectory: string`
94103

95-
The value provided to
96-
[`browser.screenshotDirectory`](/config/browser/screenshotdirectory),
97-
if none is provided, its default value.
104+
The value provided to [`browser.expect.toMatchScreenshot.screenshotDirectory`](#browserexpecttomatchscreenshotscreenshotdirectory), if none is provided, its default value (`__screenshots__`).
98105

99106
- `root: string`
100107

@@ -132,7 +139,7 @@ resolveScreenshotPath: ({ arg, browserName, ext, root, testFileName }) =>
132139
## browser.expect.toMatchScreenshot.resolveDiffPath
133140

134141
- **Type:** `(data: PathResolveData) => string`
135-
- **Default output:** `` `${root}/${attachmentsDir}/${testFileDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}` ``
142+
- **Default output:** ``path.resolve(root, attachmentsDir, testFileDirectory, testFileName, `${arg}-${browserName}-${platform}${ext}`)``
136143

137144
A function to customize where diff images are stored when screenshot comparisons
138145
fail. Receives the same data object as

docs/guide/migration.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,32 @@ Vitest now uses a single `.vitest` directory at the project root as the shared a
182182
- **Blob reporter** and `--merge-reports`: `.vitest-reports/blob-*.json``.vitest/blob/blob-*.json`
183183
- **HTML reporter** ([`html`](/guide/reporters#html-reporter)): `html/index.html``.vitest/index.html`, and its option changed from `outputFile` (a file) to `outputDir` (a directory)
184184

185+
### `toMatchScreenshot` Now Uses a Dedicated Screenshot Directory Config
186+
187+
Previously, reference screenshots for `toMatchScreenshot` did not correctly respect `browser.screenshotDirectory`. As a result, screenshots were saved in an unintended location when a custom directory was configured.
188+
189+
This has now been fixed by introducing a dedicated option: `browser.expect.toMatchScreenshot.screenshotDirectory`. Its default value is `__screenshots__`.
190+
191+
- If you did not set `browser.screenshotDirectory`, no changes are required.
192+
- If you did set `browser.screenshotDirectory`, you must now explicitly configure the new option:
193+
194+
```ts [vitest.config.ts]
195+
export default defineConfig({
196+
test: {
197+
browser: {
198+
screenshotDirectory: 'my-screenshots',
199+
expect: { // [!code ++]
200+
toMatchScreenshot: { // [!code ++]
201+
screenshotDirectory: 'my-screenshots', // [!code ++]
202+
}, // [!code ++]
203+
}, // [!code ++]
204+
},
205+
},
206+
})
207+
```
208+
209+
Then either move existing reference screenshots to the new location or regenerate them.
210+
185211
## Migrating to Vitest 4.0 {#vitest-4}
186212

187213
::: warning Prerequisites

packages/browser/src/node/commands/screenshotMatcher/utils.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type GlobalOptions = Required<Omit<
1717
NonNullable<BrowserConfigOptions['expect']>['toMatchScreenshot']
1818
& NonNullable<Pick<ScreenshotMatcherArguments[2], 'screenshotOptions'>>
1919
>,
20-
'comparators'
20+
'comparators' | 'screenshotDirectory'
2121
>>
2222

2323
const defaultOptions = {
@@ -135,10 +135,7 @@ export function resolveOptions(
135135
ext: `.${extension}`,
136136
platform: platform(),
137137
root,
138-
screenshotDirectory: relative(
139-
root,
140-
join(root, context.project.config.browser.screenshotDirectory ?? '__screenshots__'),
141-
),
138+
screenshotDirectory: context.project.config.browser.expect?.toMatchScreenshot?.screenshotDirectory ?? '__screenshots__',
142139
attachmentsDir: relative(root, context.project.config.attachmentsDir),
143140
testFileDirectory: relative(root, dirname(context.testPath)),
144141
testFileName: basename(context.testPath),

packages/vitest/src/node/types/browser.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,7 @@ type ToMatchScreenshotResolvePath = (data: {
518518
*/
519519
platform: NodeJS.Platform
520520
/**
521-
* The value provided to
522-
* {@linkcode https://vitest.dev/config/browser/screenshotdirectory|browser.screenshotDirectory},
523-
* if none is provided, its default value.
521+
* The value provided to {@linkcode ToMatchScreenshotOptions.screenshotDirectory|browser.expect.toMatchScreenshot.screenshotDirectory}, if none is provided, its default value (`__screenshots__`).
524522
*/
525523
screenshotDirectory: string
526524
/**
@@ -557,16 +555,24 @@ type ToMatchScreenshotResolvePath = (data: {
557555
}) => string
558556

559557
export interface ToMatchScreenshotOptions {
558+
/**
559+
* The directory name used for storing reference screenshots.
560+
*
561+
* This value is passed as `screenshotDirectory` to {@linkcode resolveScreenshotPath|browser.expect.toMatchScreenshot.resolveScreenshotPath} and {@linkcode resolveDiffPath|browser.expect.toMatchScreenshot.resolveDiffPath}, and used in the default path resolution of `resolveScreenshotPath`.
562+
*
563+
* @default `__screenshots__`.
564+
*/
565+
screenshotDirectory?: string
560566
/**
561567
* Overrides default reference screenshot path.
562568
*
563-
* @default `${root}/${testFileDirectory}/${screenshotDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}`
569+
* @default path.resolve(root, testFileDirectory, screenshotDirectory, testFileName, `${arg}-${browserName}-${platform}${ext}`)
564570
*/
565571
resolveScreenshotPath?: ToMatchScreenshotResolvePath
566572
/**
567573
* Overrides default screenshot path used for diffs.
568574
*
569-
* @default `${root}/${attachmentsDir}/${testFileDirectory}/${testFileName}/${arg}-${browserName}-${platform}${ext}`
575+
* @default path.resolve(root, attachmentsDir, testFileDirectory, testFileName, `${arg}-${browserName}-${platform}${ext}`)
570576
*/
571577
resolveDiffPath?: ToMatchScreenshotResolvePath
572578
}

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,47 @@ describe('--watch', () => {
131131
},
132132
)
133133

134+
test(
135+
'uses the `screenshotDirectory` option from config',
136+
async () => {
137+
const customDir = 'my-screenshots'
138+
139+
const { stderr } = await runBrowserTests(
140+
{
141+
[testFilename]: testContent,
142+
'utils.ts': utilsContent,
143+
},
144+
{
145+
browser: {
146+
enabled: true,
147+
screenshotFailures: false,
148+
provider,
149+
headless: true,
150+
instances,
151+
viewport: {
152+
width: 400,
153+
height: 200,
154+
},
155+
expect: {
156+
toMatchScreenshot: {
157+
screenshotDirectory: customDir,
158+
},
159+
},
160+
},
161+
update: 'new',
162+
},
163+
)
164+
165+
const references = extractToMatchScreenshotPaths(stderr, testName)
166+
167+
expect(references.length).toBeGreaterThan(0)
168+
169+
for (const referencePath of references) {
170+
expect(referencePath).toContain(`/${customDir}/`)
171+
}
172+
},
173+
)
174+
134175
describe('--update', () => {
135176
test(
136177
'creates snapshot and does NOT update it if reference matches',

0 commit comments

Comments
 (0)