Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Playwright has no single screenshot-folder switch because different APIs write different kinds of images. Set path on page.screenshot() or a locator for an individual file, configure snapshotPathTemplate (or expect.toHaveScreenshot.pathTemplate) for visual-regression baselines, and use testInfo.outputPath() for per-test run artifacts.
The important detail is that relative paths use different bases: direct screenshot paths are relative to the process working directory, while snapshot templates are relative to the Playwright configuration directory. The sections below show the exact settings and when to use each one.
Choose the path control that matches the screenshot
| Need | Setting or API | Relative-path base | Lifecycle |
|---|---|---|---|
| One explicitly named image | page.screenshot({ path }) or locator.screenshot({ path }) |
Current working directory | Custom image, debugging or report artifact |
| Every Playwright Test snapshot | snapshotPathTemplate |
Configuration directory | Version-controlled visual baseline |
| Only screenshot assertions | expect.toHaveScreenshot.pathTemplate |
Configuration directory | Screenshot-assertion baseline |
| Diagnostic output for one test | testInfo.outputPath(name) |
Test runner output directory | Run-specific artifact |
| Resolve a configured baseline path | testInfo.snapshotPath(name, { kind: 'screenshot' }) |
Configured snapshot template | Logging or custom tooling around a baseline |
There is therefore no universal “default screenshot path” to change. First identify whether the image is a direct capture, a snapshot assertion, or a test artifact; then apply the matching control.
Set a path for a direct screenshot
Use the call-site path option when your code explicitly captures an image. The same option works for a page and for a locator.
#1 Best Overall
- Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
- Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
- To get set up, connect the portable hard drive to a computer for automatic recognition no software required
- This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
- The available storage capacity may vary.
import { test } from '@playwright/test';
test('save the landing page', async ({ page }) => {
await page.goto('https://example.com');
await page.screenshot({ path: 'artifacts/home.png' });
await page.locator('.header').screenshot({ path: 'artifacts/header.png' });
});
For a relative path, Playwright resolves the value from the current working directory of the process. That is the directory from which the test command is launched, not necessarily the directory containing the test file or configuration file. An absolute path removes that ambiguity when your environment supplies one.
What happens when path is omitted?
Without path, Playwright returns the image data instead of saving a file. This is useful when you want to attach the bytes to a report, transform them in memory, or send them elsewhere.
const image = await page.screenshot();
// image is the screenshot data returned by Playwright.
Playwright infers the file type from the filename extension when you do provide a path. Use an extension that matches the format you want, such as .png, .jpeg or .webp.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Keep direct captures in one folder
Use a consistent prefix at each call site:
await page.screenshot({ path: 'artifacts/screens/pages/pricing.png' });
await page.screenshot({ path: 'artifacts/screens/pages/contact.png' });
await page.locator('[data-testid="chart"]').screenshot({
path: 'artifacts/screens/components/chart.png'
});
This is a naming convention, not a Playwright-wide default. Every direct capture still needs its own path unless you wrap the API in your own helper.
Set the default location for visual-regression snapshots
expect(page).toHaveScreenshot() uses Playwright Test’s snapshot system. Configure its project-level template in playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
snapshotPathTemplate:
'{testDir}/__screenshots__/{testFilePath}/{arg}{ext}',
});
This template controls screenshot snapshots and also the locations used by other snapshot assertions, including expect(locator).toMatchAriaSnapshot() and expect(value).toMatchSnapshot(). Relative templates resolve from the configuration directory, which is different from the current-working-directory rule for page.screenshot().
Rank #2
- Easily store and access 5TB of content on the go with the Seagate portable drive, a USB external hard Drive
- Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
- To get set up, connect the portable hard drive to a computer for automatic recognition software required
- This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
- The available storage capacity may vary.
Use the template in a test
import { test, expect } from '@playwright/test';
test('homepage visual baseline', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('landing.png');
});
With the template above, Playwright places the baseline beneath __screenshots__, using the test-file path and assertion argument to keep names separated. Run npx playwright test --update-snapshots when you intentionally want to create or update baselines.
Separate projects without collisions
If you test multiple named projects, include {projectName} in the template:
import { defineConfig } from '@playwright/test';
export default defineConfig({
snapshotPathTemplate:
'__screenshots__{/projectName}/{testFilePath}/{arg}{ext}',
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
],
});
The optional slash before {projectName} is included only when a project name exists. A named Chromium project can therefore produce a path such as <configDir>/__screenshots__/chromium/example.spec.ts/landing.png; with no project name, that segment is omitted.
Available snapshot-template tokens
Choose tokens according to the directory structure you need:
{snapshotDir}— the snapshot directory.{testDir}— the configured test directory.{testFileDir}— the directory containing the test file.{testFileBaseName}— the test file name without its extension.{testFileName}— the test file name.{testFilePath}— the test file path relative to the test directory.{testName}— the test title.{projectName}— the Playwright project name.{arg}— the argument passed to the snapshot assertion.{ext}— the generated snapshot extension.{platform}— the platform token.
For example, this compact layout keeps project directories optional while retaining the test-file path:
Recommended Free Tools
snapshotPathTemplate:
'__screenshots__{/projectName}/{testFilePath}/{arg}{ext}'
Scope a path to screenshot assertions only
If text and ARIA snapshots should remain in their normal locations while screenshot baselines go elsewhere, configure the assertion-specific template instead of the global template:
Rank #3
- Easily store and access 1TB to content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
- Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop. Reformatting may be required for Mac
- To get set up, connect the portable hard drive to a computer for automatic recognition no software required
- This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
- The available storage capacity may vary.
import { defineConfig } from '@playwright/test';
export default defineConfig({
expect: {
toHaveScreenshot: {
pathTemplate:
'{testDir}/__screenshots__/{projectName}/{testFilePath}/{arg}{ext}',
},
},
});
This setting applies to expect(page).toHaveScreenshot() and locator screenshot assertions. It is the narrower choice when you only want to reorganize image baselines.
Put run artifacts in the test output directory
A diagnostic capture belongs to a test run, not to the committed baseline tree. Use the testInfo fixture:
import { test } from '@playwright/test';
test('capture diagnostic image', async ({ page }, testInfo) => {
await page.goto('https://example.com');
await page.screenshot({
path: testInfo.outputPath('diagnostic.png'),
});
});
testInfo.outputPath() resolves a file inside that test’s output directory. This keeps evidence from separate runs associated with the test that produced it instead of mixing it with stable visual baselines.
Resolve the configured baseline programmatically
When custom tooling needs to know where a screenshot baseline belongs, use snapshotPath() and identify the kind explicitly:
import { test } from '@playwright/test';
test('log the baseline location', async ({}, testInfo) => {
const baseline = testInfo.snapshotPath('landing.png', {
kind: 'screenshot',
});
console.log(baseline);
});
This follows the configured screenshot template rather than the test output directory.
A practical path decision
- Capturing an image on demand? Put an explicit relative or absolute
pathonpage.screenshot()orlocator.screenshot(). - Comparing a page or locator against a visual baseline? Set
snapshotPathTemplate, or useexpect.toHaveScreenshot.pathTemplatewhen only screenshot assertions need a custom location. - Saving failure evidence or a temporary diagnostic? Use
testInfo.outputPath(). - Writing tooling around an existing baseline? Resolve it with
testInfo.snapshotPath(name, { kind: 'screenshot' }).
Do not mix these bases accidentally. A path that looks identical in source can land in different directories depending on which API resolves it.
Rank #4
- Easily store and access 4TB of content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
- Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
- To get set up, connect the portable hard drive to a computer for automatic recognition no software required
- This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
- The available storage capacity may vary.
Troubleshooting path problems
The file appears in an unexpected directory
Check whether the call uses a direct screenshot or a snapshot assertion. Direct relative paths follow the current working directory; template paths follow the configuration directory. Log the process working directory in your runner and inspect the location of playwright.config.ts.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →The assertion still uses the old baseline folder
Confirm that the configuration key is at the top level for snapshotPathTemplate, or nested under expect.toHaveScreenshot.pathTemplate for the scoped form. Then run the test with --update-snapshots only if changing the baseline is intentional.
Different projects overwrite one another
Add {projectName} to the template and give each project a name. Without a project segment, identical test-file and argument names can resolve to the same target.
A diagnostic image is mixed with committed snapshots
Replace a hard-coded baseline-style path with testInfo.outputPath('name.png'). Use snapshotPath() only when you specifically need the configured baseline location.
The generated filename has the wrong format
For direct screenshots, check the extension in path; Playwright infers the image type from it. For snapshot assertions, keep {ext} in the template so Playwright supplies the appropriate extension.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
No file is created
Inspect the call for an omitted path. In that case, page.screenshot() returns image data instead of writing to disk. Also verify that you are looking in the correct base directory for the API you used.
Best Value
- [Upgraded Version] - This external hard drive features a mirrored logo stripe combined with a striped anti-slip design, and the rounded corners of the casing make it easier to grip. The stripes also have a heat dissipation function, ensuring stable and fast data transfer.
- 【Ultra-thin and quiet】 - The motherboard adopts JMicron 578 noise-free solution, giving you a quiet working environment. Lightweight and portable size designed to fit in your pocket for easy portability.
- 【Ultra-Fast Data Transfers】 - Pairing this external hard drive with JMicron 578 solution USB 3.0 and USB 2.0 interfaces enables blazing-fast data transfer. It boasts theoretical read speeds of up to 125MB/s and write speeds of up to 103MB/s.
- 【Plug and Play】 - With no software to install, just plug it in and the drive is ready to use.The hard disk chip is wrapped with an aluminum anti-interference layer to increase heat dissipation and protect data.
- 【What You Get】 - 1 x Portable Hard Drive, 1 x USB 3.0 Cable, 1 x User Manual, Gift-type shell packaging ,Three-year manufacturer's warranty and free technical support services.
Reliability and repository practices
- Keep visual baselines in a deterministic template that includes the test-file path; this prevents similarly named assertions from colliding.
- Include the project name when the same tests run in multiple browser projects.
- Keep run-specific diagnostics under
testInfo.outputPath()so they do not become accidental baselines. - Use explicit extensions for direct captures and retain
{ext}in snapshot templates. - When changing a template, review the files generated by an update run before committing them; a path change can make an otherwise identical image appear as a new baseline.
Or skip the browser setup
If you only need a clean screenshot from a URL, ScreenshotNeo provides a single HTTP request instead of a local Playwright browser. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
cURL:
curl -G "https://api.screenshotneo.com/v1/shot"
-d access_key=YOUR_API_KEY
--data-urlencode url=https://stripe.com
-o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation for options such as full-page capture, CSS-selector element shots, device and retina settings, PDF output, custom CSS or JavaScript, waits, request blocking, headers, cookies, geolocation, caching, signed links, asynchronous jobs and bulk capture. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
FAQ
Can one configuration control both direct screenshots and snapshots?
No. Direct calls read their path at the call site, while snapshot assertions read the configured template. Use a shared helper if you want your own convention across both APIs.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWhich path should contain a failure screenshot?
Use testInfo.outputPath() so the image remains tied to that test run. Reserve the snapshot template for files that represent an intentional visual baseline.
How can I keep browser projects in separate baseline trees?
Add {projectName} to snapshotPathTemplate or the assertion-specific pathTemplate; the token is replaced with each named project.
Frequently Asked Questions
Can one configuration control both direct screenshots and snapshots?
No. Direct calls read their path at the call site, while snapshot assertions read the configured template. Use a shared helper if you want your own convention across both APIs.
Which path should contain a failure screenshot?
Use testInfo.outputPath() so the image remains tied to that test run. Reserve the snapshot template for files that represent an intentional visual baseline.
How can I keep browser projects in separate baseline trees?
Add {projectName} to snapshotPathTemplate or the assertion-specific pathTemplate; the token is replaced with each named project.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

