Playwright screenshot configuration depends on what you are producing. Use page.screenshot() for an explicit image, use.screenshot for automatic test artifacts, locator.screenshot() for one element, and toHaveScreenshot() for visual regression checks. The defaults and the right options differ for each job.
Choose the right Playwright screenshot API
| Goal | API or setting | What it does |
|---|---|---|
| Save or return an image from test code | page.screenshot() |
Captures the current viewport unless configured otherwise. |
| Capture an element | locator.screenshot() |
Captures the bounding area of a locator-matched element. |
| Save screenshots automatically from tests | use.screenshot |
Controls test-runner artifacts; its default is off. |
| Compare against a baseline | expect(page).toHaveScreenshot() or a locator assertion |
Performs visual regression comparison rather than merely saving a file. |
Do not treat the test-runner setting as an implicit call to page.screenshot(). It controls artifacts generated by Playwright Test, while the Page API captures only when your code calls it.
Configure a direct page screenshot
Viewport versus full page
By default, page.screenshot() captures the currently visible viewport. To capture the entire scrollable document, set fullPage: true. The Page API documentation describes this as taking “a screenshot of the full scrollable page, instead of the currently visible viewport.” A clip rectangle is useful when neither the viewport nor the whole document is appropriate.
import { test } from '@playwright/test';
test('capture the page', async ({ page }) => {
await page.goto('https://example.com');
await page.screenshot({
path: 'artifacts/home.webp',
fullPage: true,
scale: 'css',
animations: 'disabled',
caret: 'hide'
});
});
With path omitted, the method returns an image buffer instead of writing a file. A relative path is resolved from the process working directory, so make the output directory first when your CI environment does not create it.
#1 Best Overall
Format, quality, and scale
Playwright supports PNG, JPEG, and WebP. When a path is supplied, its extension can determine the type; specifying type makes the choice explicit. PNG quality is not configurable. JPEG has a documented default quality of 80, while WebP defaults to 100 and is lossless. quality matters only for JPEG and WebP.
The Page screenshot API defaults to scale: 'device'. That produces one output pixel per device pixel and can make images substantially larger on high-DPI displays. Set scale: 'css' for one output pixel per CSS pixel, which is usually easier to diff, store, and embed consistently.
await page.screenshot({
path: 'artifacts/viewport.png',
type: 'png',
fullPage: false,
scale: 'css'
});
await page.screenshot({
path: 'artifacts/photo.jpg',
type: 'jpeg',
quality: 80
});
Transparency and backgrounds
omitBackground: true hides the default page background and allows transparency where the renderer supports it. It is not applicable to JPEG, which has no alpha channel. Use PNG or WebP when transparent output is required.
Stabilize the rendered result
animations: 'disabled': finite animations are fast-forwarded and infinite animations are canceled to their initial state.caret: 'hide': prevents a blinking text cursor from changing pixels.mask: overlays each target locator’s bounding box. The documented default mask color is pink (#FF00FF).style: injects screenshot-only CSS, useful for hiding timestamps, rotating banners, or other known sources of nondeterminism.timeout: limits how long Playwright waits for the screenshot operation.
await page.screenshot({
path: 'artifacts/stable.png',
mask: [page.locator('[data-testid="live-price"]')],
style: `
.rotating-ad, .clock { visibility: hidden !important; }
`,
animations: 'disabled',
caret: 'hide'
});
Masking covers the locator’s box; it does not remove the element from layout. If the element changes size, the surrounding pixels can still move, so prefer a stable test fixture where possible.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesAutomatic screenshots in Playwright Test
Configure automatic artifacts in playwright.config.ts under use.screenshot. The documented modes are off, on, only-on-failure, and on-first-failure; the default is off.
Rank #2
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure'
}
});
only-on-failure is a practical low-noise choice when screenshots are primarily for diagnosing failures. on-first-failure limits repeated artifacts when retries are enabled. Use on when every test needs an image, but expect more storage and slower artifact handling.
The object form lets you pass screenshot options such as fullPage and omitBackground:
export default defineConfig({
use: {
screenshot: {
mode: 'only-on-failure',
fullPage: true,
omitBackground: false
}
}
});
Keep this setting separate from explicit captures. A test can still call page.screenshot() regardless of the automatic mode, and an explicit capture can use different scope, format, masking, or timing.
Capture one element with a locator
Use locator.screenshot() when the artifact is a component, card, dialog, or other element rather than the page. Locator-based screenshots are preferred over the older ElementHandle screenshot method, which is marked discouraged.
import { test } from '@playwright/test';
test('capture the pricing card', async ({ page }) => {
await page.goto('https://example.com/pricing');
const card = page.getByRole('article', { name: 'Pro' });
await card.screenshot({
path: 'artifacts/pro-card.png',
animations: 'disabled'
});
});
The locator must resolve to the intended element. If it matches multiple elements, refine it with a role, accessible name, test ID, or CSS selector. A locator screenshot can use the same relevant rendering controls as a page screenshot, including animation handling and masking-related options.
Rank #3
Use screenshot assertions for visual regression
If the purpose is to detect visual changes, use an assertion rather than manually comparing files. Playwright can compare a page or locator with a stored baseline:
import { test, expect } from '@playwright/test';
test('homepage remains stable', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
animations: 'disabled',
caret: 'hide'
});
});
test('button remains stable', async ({ page }) => {
await page.goto('https://example.com');
await expect(page.getByRole('button', { name: 'Buy' }))
.toHaveScreenshot('buy-button.png');
});
Assertion options include a pixel-difference threshold and acceptable differing-pixel counts or ratios. Project and test configuration can provide defaults, so keep comparison policy in configuration when many tests share it. Run the test once in a controlled environment to create the baseline, then review intentional changes instead of blindly updating snapshots.
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 minuteConfiguration decisions that prevent flaky screenshots
Control the capture scope
- Viewport: fastest and least affected by document length.
- Full page: useful for documentation or page-level review, but can be tall and sensitive to lazy content.
- Clip: precise region with explicit coordinates; ensure the region exists at the capture point.
- Locator: isolates a component and avoids unrelated page changes.
Wait for the state you intend to record
Navigate, wait for the key locator, and then capture. For data-driven interfaces, wait for the loaded state represented by a stable selector rather than relying only on a fixed delay. Disable or mask content that is expected to vary, such as clocks, ads, random avatars, and live counters.
Keep rendering environments consistent
Device scale, browser engine, fonts, viewport size, color scheme, timezone, and installed font files all affect pixels. A baseline generated on one CI image can differ from a developer laptop even when application code is unchanged. Pin the browser and use the same project configuration for baseline generation and comparison.
Troubleshooting Playwright screenshot configuration
The image shows only the top of the page
Cause: the default is viewport capture. Fix: pass fullPage: true, or use a locator/clip when only a region is needed.
The file is unexpectedly huge
Cause: scale: 'device' on a high-DPI context, full-page dimensions, or a lossless format. Fix: use scale: 'css', choose WebP or JPEG where appropriate, and capture a locator or clip instead of the entire document.
Recommended Free Tools
Visual tests fail intermittently
Cause: animations, blinking carets, asynchronous data, or changing ads. Fix: disable animations, hide the caret, wait for a stable locator, mask dynamic regions, or inject screenshot-only CSS. Do not raise the diff threshold until you understand the source of the change.
No automatic screenshot appears after a failure
Cause: use.screenshot remains at its default, off, or the artifact is being collected in a different report directory. Fix: set screenshot: 'only-on-failure' (or another intended mode), rerun the test, and inspect the reporter’s artifact path.
Transparent output is black or opaque
Cause: JPEG cannot represent transparency, or the page itself paints an opaque background. Fix: use PNG/WebP with omitBackground: true and verify the page’s CSS background.
The target locator cannot be captured
Cause: it does not resolve, is detached, or is outside the expected state. Fix: make the locator specific, wait for it to be visible, and capture after the UI transition completes.
Or skip the browser setup
For a hosted screenshot instead of maintaining Playwright browsers, ScreenshotNeo provides a GET-based screenshot API and an MCP server for AI agents. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and billing status.
One request returns PNG, JPEG, WebP, or a PDF:
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 full parameter reference at ScreenshotNeo documentation. Its options include full-page and element capture, device presets, CSS/device scale, PDF settings, custom JavaScript and CSS, waits, request blocking, headers, cookies, geolocation, caching, signed links, asynchronous jobs, bulk capture, and a usage API. The MCP tools take_screenshot, get_page_info, and capture_pdf work with Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots monthly with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Frequently Asked Questions
Should I use PNG or WebP for Playwright visual tests?
Use the format your baseline policy supports consistently. PNG has no quality setting; WebP is lossless at its documented default, while JPEG introduces lossy compression.
Can full-page screenshots include lazy-loaded images?
They capture the scrollable page state available at capture time. Make sure your application has loaded the content you expect before calling the screenshot method.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →What is the difference between masking and hiding an element?
Masking covers a locator’s bounding box in the output; hiding changes page styling or layout. Use masking when preserving layout matters.
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.




