Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
In a Playwright script, enable a screenshot by navigating to a page and calling await page.screenshot({ path: 'screenshot.png' }). Add fullPage: true for the complete scrollable document. In Playwright Test, screenshots are a separate feature: configure use.screenshot for automatic artifacts, or use expect(page).toHaveScreenshot() when you need visual-regression comparisons.
Set up a project that can capture screenshots
The examples below use JavaScript and the Playwright Test runner where noted. Install Playwright in an existing Node.js project, then install the browser binaries required by your environment:
npm install -D playwright
npx playwright install
For a standalone script, require the browser package directly. For test fixtures, import test and expect from @playwright/test and run tests with the Playwright Test command.
Take a basic screenshot in a standalone script
This complete script launches Chromium, opens a URL, writes a PNG, and closes the browser even after the capture is complete:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png' });
await browser.close();
})();
The path extension determines the image format. A relative path is resolved from the process’s current working directory, so a file named screenshot.png appears wherever you ran the command. If you omit path, the method returns image bytes instead of writing a file:
const pngBytes = await page.screenshot();
// pngBytes is a Buffer that can be saved, uploaded, or attached to a test.
Wait for the page state your capture requires before calling the method. For example, navigate with an appropriate waitUntil value or wait for a specific locator when application content is rendered after the initial document load.
Choose the capture area and image output
Viewport versus full page
By default, Playwright captures only the current viewport. To capture the entire scrollable page, pass fullPage: true:
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 minuteawait page.screenshot({
path: 'full-page.png',
fullPage: true,
});
Full-page mode is useful for documentation and long pages, but it can produce very tall images. If the page contains lazy-loaded content, scroll or otherwise trigger the loading behavior before capture so the content is present.
Capture one element
Use a locator when the required artifact is a component rather than the whole page:
await page.locator('[data-testid="invoice"]').screenshot({
path: 'invoice.png',
});
Locator screenshots reduce unrelated pixels and are usually easier to compare in a visual test.
Clip a rectangle
For a precise region, supply a clip rectangle in page coordinates:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteawait page.screenshot({
path: 'header.png',
clip: { x: 0, y: 0, width: 1280, height: 180 },
});
Control format, quality, scale, and transparency
Use type (or the filename extension) for PNG, JPEG, or WebP. JPEG and WebP support a quality value. scale chooses CSS-pixel or device-pixel output, and omitBackground can preserve transparency where the selected format supports it:
await page.screenshot({
path: 'card.webp',
type: 'webp',
quality: 85,
scale: 'css',
omitBackground: true,
});
Screenshot options also support masking locators and controlling animation behavior. Mask dynamic regions when a stable visual comparison matters more than their current content.
Enable automatic screenshots in Playwright Test
Playwright Test’s automatic screenshot setting is off by default. Add a use block to playwright.config.ts (or the equivalent JavaScript configuration):
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure',
},
});
The available modes are:
| Mode | When Playwright captures | Use it for |
|---|---|---|
off |
No automatic screenshot | Keeping test artifacts minimal (the default) |
on |
Every test | Auditing every run or retaining a complete visual record |
only-on-failure |
Failed tests | Debugging failures with lower artifact volume |
on-first-failure |
The first failure in a retry sequence | Debugging retries without duplicating every artifact |
This setting creates test-run artifacts; it does not establish a visual baseline or compare pixels. For that, use a screenshot assertion.
Compare screenshots with visual regression assertions
toHaveScreenshot() is available through Playwright Test, not an ordinary standalone script. A basic test looks like this:
import { test, expect } from '@playwright/test';
test('homepage visual check', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot();
});
On the first approved run, Playwright creates an expected image. Later runs capture the page and compare it with that baseline. The assertion waits for two consecutive screenshots to match before comparing, which helps avoid capturing a frame while the page is still settling.
You can name a baseline, capture the full page, clip an area, mask locators, and control animation or caret handling through assertion options:
await expect(page).toHaveScreenshot('dashboard.png', {
fullPage: true,
animations: 'disabled',
caret: 'hide',
mask: [page.locator('.live-clock')],
});
Locator assertions use the same idea for a component:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →await expect(page.locator('[data-testid="checkout"]'))
.toHaveScreenshot('checkout.png');
Review a changed image rather than automatically accepting it. A changed baseline can indicate either an intentional design update or a regression.
Attach a screenshot to a test result
When you need a file attached to the report rather than a baseline comparison, capture bytes and call testInfo.attach:
import { test } from '@playwright/test';
test('attach diagnostic image', async ({ page }, testInfo) => {
await page.goto('https://example.com');
const screenshot = await page.screenshot();
await testInfo.attach('screenshot', {
body: screenshot,
contentType: 'image/png',
});
});
For a test-specific file location, use testInfo.outputPath('screenshot.png') and pass the resulting path to page.screenshot. Attachments are diagnostic artifacts; they do not replace the automatic screenshot setting or a visual assertion.
Rank #4
Make captures deterministic
Visual comparisons can differ when the execution environment changes. Keep the operating system, browser version, Playwright settings, hardware, power conditions, and headless or headed mode consistent when generating and comparing baselines.
Free tools Windows power users keep installed
One-click scans. No signup required.
- Wait for the relevant content or locator instead of relying on an arbitrary delay.
- Disable or mask animations, blinking carets, clocks, rotating banners, and other changing regions.
- Use a fixed viewport and device scale when pixel dimensions matter.
- Use the same fonts and browser binaries in baseline and comparison jobs.
- Capture after the application reaches the state the test is meant to verify, not merely after navigation returns.
Troubleshoot common screenshot problems
No screenshot is produced by a test
Automatic screenshots default to off. Set use.screenshot to on, only-on-failure, or on-first-failure, or call page.screenshot explicitly.
The image shows only the visible screen
That is the default behavior. Add fullPage: true for the complete scrollable document, or use a locator screenshot for a specific component.
toHaveScreenshot is undefined
Visual assertions require the Playwright Test runner. Import expect from @playwright/test and run the test with that runner. In a standalone script, use the Page or Locator screenshot API instead.
Baselines fail on another machine
Rendering varies with OS, browser version, settings, hardware, power source, and headless mode. Generate and compare baselines in a consistent environment, then remove dynamic content with masking or deterministic test data.
The capture is blank or incomplete
Check that navigation succeeded, wait for the selector that owns the content, and make sure lazy-loaded sections have been triggered. A screenshot records the rendered state at the moment of the call; it does not wait for application-specific readiness unless you tell it what readiness means.
Best Value
The output file is unexpectedly large
A full-page or device-pixel-scale image can be much larger than a viewport CSS-pixel image. Capture only the required element or clip, choose an appropriate format, and set a lower JPEG or WebP quality when loss is acceptable.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
For a hosted capture, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. It accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before the capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
Use the API documentation at https://screenshotneo.com/docs/ for all parameters. This one-call example captures Stripe:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Equivalent 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)
Equivalent 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}`);
ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF controls, custom CSS and JavaScript, click-before-capture actions, selector hiding, waits for selectors, delays or network idle, request and resource blocking, headers, cookies, user agents, authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is included on every plan. Create a free ScreenshotNeo account to begin.
FAQ
Does page.screenshot() return an image or save one?
It returns image bytes when no path is supplied; providing a path writes the image to disk.
Can I screenshot a locator instead of a page?
Yes. Call locator.screenshot() for a component, or use a locator with expect(locator).toHaveScreenshot() in Playwright Test.
Recommended Free Tools
Are automatic screenshots and visual assertions the same feature?
No. use.screenshot controls diagnostic artifacts, while toHaveScreenshot() compares a capture with an expected baseline.
Frequently Asked Questions
Can I capture a PDF with Playwright screenshots?
The Page screenshot API writes image formats. For PDF output, use the browser’s PDF capabilities or a service that provides PDF capture, such as ScreenshotNeo’s capture_pdf MCP tool.
Why do two screenshots differ when the page looks unchanged?
Rendering can vary between operating systems, browser versions, settings, hardware, power conditions, and headless modes. Keep the comparison environment consistent and mask dynamic regions.
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.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.

