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 →The Playwright method for taking a screenshot is page.screenshot(). It captures the current page viewport and returns an image buffer; add a path to save the file. For one element, use page.locator(selector).screenshot(). Use fullPage: true when you need the entire scrollable document.
The direct answer: page.screenshot()
Playwright’s Page API provides page.screenshot() for explicit page captures. This minimal example writes a PNG to disk:
import { chromium } from 'playwright';
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();
With no path, the method returns a buffer instead of creating a file:
const imageBuffer = await page.screenshot();
You can pass that buffer to an image-processing library, upload it, or write it yourself. The supported output formats are PNG, JPEG and WebP. When a path is supplied, Playwright can infer the format from the filename extension; you can also set type explicitly.
#1 Best Overall
The official API reference documents this method at Playwright’s Page API.
Choose the right screenshot method
| Need | Method or option | Result |
|---|---|---|
| Capture the visible page | page.screenshot() |
The current viewport; full-page capture is off by default. |
| Save an image | page.screenshot({ path: 'screenshot.png' }) |
Writes the image to the specified path. |
| Capture the entire document | page.screenshot({ fullPage: true }) |
Captures all scrollable page content. |
| Capture one component | page.locator('.header').screenshot({ path: 'header.png' }) |
Captures the area occupied by the matched locator. |
| Capture a rectangle | page.screenshot({ clip: { x, y, width, height } }) |
Restricts the output to page coordinates. |
| Process image data in memory | const buffer = await page.screenshot() |
Returns image bytes without saving a file. |
Capture a viewport screenshot
A normal call captures what is currently inside the browser viewport. Set the viewport when you need repeatable dimensions:
const page = await browser.newPage({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 1
});
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'viewport.webp', type: 'webp', quality: 85 });
deviceScaleFactor controls device-pixel output. A scale of 1 produces one image pixel per CSS pixel; higher values produce a denser, retina-style image. The exact dimensions and loading state matter when comparing screenshots, so set them deliberately rather than relying on defaults.
Take a full-page screenshot
Use the fullPage option for content below the fold:
await page.screenshot({
path: 'full-page.png',
fullPage: true
});
Playwright scrolls and assembles the page’s scrollable content. Pages that lazy-load images may need an explicit scroll or a wait for the images before capture. A full-page image can also become very large; choose JPEG or WebP, reduce the scale, or capture sections if the resulting file is too big.
Capture a specific element with a locator
For a component, card, chart or header, prefer the locator API:
Rank #2
await page.locator('.header').screenshot({ path: 'header.png' });
await page.getByRole('button', { name: 'Buy now' }).screenshot({ path: 'buy-button.png' });
locator.screenshot() performs actionability checks and scrolls the matched element into view. This is generally safer than querying an element handle directly. The ElementHandle API marks elementHandle.screenshot() as discouraged and recommends locator-based screenshots; see the Locator API and ElementHandle API.
If the target is covered by another element, the covered area will not become visible merely because it matched a selector. For a scrollable element, the screenshot contains the content currently visible inside that element, not every possible scroll position.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Control format, quality and transparency
PNG, JPEG and WebP
await page.screenshot({ path: 'image.jpeg', type: 'jpeg', quality: 80 });
await page.screenshot({ path: 'image.webp', type: 'webp', quality: 80 });
await page.screenshot({ path: 'image.png', type: 'png' });
Quality applies to JPEG and WebP, not PNG. PNG is lossless and useful for text-heavy visual tests; JPEG and WebP can reduce transfer and storage size.
CSS pixels versus device pixels
The scale screenshot option can produce output at device-pixel scale or CSS-pixel scale. Use CSS scale when stable, predictable dimensions matter; use device scale when you need a high-density image for a display.
Animations and backgrounds
Screenshot options include animation handling, masking and background behavior. Setting animations: 'disabled' helps visual comparisons by stopping CSS animations and transitions. mask can cover changing regions, while omitBackground: true can preserve transparency where the page supports it. Use these options consistently in both baseline and comparison runs.
Clip a rectangle
await page.screenshot({
path: 'chart-area.png',
clip: { x: 120, y: 180, width: 640, height: 360 }
});
The rectangle is expressed in page coordinates. A clip is useful when a selector is unavailable, but a locator is usually more resilient to layout changes.
Rank #3
Make captures deterministic
A screenshot records the rendered state at one moment. Stabilize that state before calling the method:
- Navigate and wait for the page’s required content, preferably with a targeted locator rather than an arbitrary long delay.
- Set a fixed viewport, device scale and color scheme when those values affect layout.
- Wait for fonts, images or application data that the screenshot must contain.
- Disable or mask animations, timestamps, rotating banners and other changing regions.
- Use a consistent locale, timezone and test account when text or formatting can vary.
await page.goto('https://example.com/dashboard');
await page.getByRole('heading', { name: 'Dashboard' }).waitFor();
await page.screenshot({
path: 'dashboard.png',
animations: 'disabled',
fullPage: true
});
A very broad waitUntil: 'networkidle' can be inappropriate for applications that keep analytics or WebSocket connections open. Waiting for the content that proves the page is ready is often more reliable.
Playwright Test screenshots and visual assertions
There are two related but different features. In ordinary browser code, call page.screenshot() yourself. In Playwright Test, the use.screenshot setting can capture test artifacts automatically with modes such as on, only-on-failure and on-first-failure. Configure it in the test runner:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
screenshot: 'only-on-failure'
}
});
Visual assertions are a separate test-runner facility:
import { test, expect } from '@playwright/test';
test('homepage stays visually stable', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('homepage.png');
});
toHaveScreenshot() waits for consecutive screenshots to stabilize before comparing them. It is intended for regression testing, whereas a direct screenshot call is the method to use when your application needs an image file or buffer. See the TestOptions API and PageAssertions API.
Complete runnable example with common options
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({
viewport: { width: 1280, height: 800 },
deviceScaleFactor: 1
});
try {
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.locator('h1').waitFor();
await page.screenshot({
path: 'example-full.webp',
fullPage: true,
type: 'webp',
quality: 85,
animations: 'disabled'
});
const headingBuffer = await page.locator('h1').screenshot();
console.log(`Heading bytes: ${headingBuffer.length}`);
} finally {
await browser.close();
}
Install Playwright with your project’s package manager, install the browser binaries, and run the file as an ES module. Keep the browser in a finally block so failures do not leave processes running.
Troubleshooting screenshot failures
The file is blank or missing content
Cause: the capture ran before the application rendered, or the page is blocked behind a login or consent dialog. Fix: wait for a meaningful locator, authenticate before navigation, and handle required dialogs. For lazy content, scroll or wait for the relevant image or section before using fullPage.
The screenshot is only the viewport
Cause: fullPage defaults to false. Fix: pass fullPage: true, or capture individual sections when one very tall image is impractical.
Free tools Windows power users keep installed
One-click scans. No signup required.
A locator screenshot times out
Cause: the selector matches nothing, the element is hidden, or actionability checks never complete. Fix: use a stable role, label or test identifier; wait for the locator; confirm the element is visible; and inspect whether an overlay covers it.
The image changes between runs
Cause: animations, fonts, network data, time, locale or rotating content differ. Fix: control those inputs, disable animations, wait for the exact ready state and mask genuinely dynamic regions.
The output format or quality is wrong
Cause: the extension and type disagree, or quality was applied to PNG. Fix: choose one of PNG, JPEG or WebP, keep the filename consistent, and remember that quality affects only JPEG and WebP.
The capture is unexpectedly huge
Cause: full-page output combined with a large viewport or device scale. Fix: use CSS-pixel scale, lower the device scale, choose WebP or JPEG, clip the required region, or divide the page into sections.
Or skip the browser setup
If you need an HTTP endpoint rather than a Playwright runtime, ScreenshotNeo takes a URL and returns a PNG, JPEG, WebP or PDF. It removes cookie and consent banners, newsletter popups and chat widgets before capture; bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.
One-call cURL example (see the ScreenshotNeo documentation):
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}`);
Every plan includes the same feature set, including full-page and element capture, device presets, custom CSS and JavaScript, waits, blocking controls, headers and cookies, geolocation, resizing, caching, signed links, asynchronous webhooks, bulk capture and a usage API. The Free plan includes 1,000 screenshots each month without a card; paid plans start at $5 for 3,000. Sign up for the free ScreenshotNeo plan.
Frequently Asked Questions
Does Playwright use a separate screenshot class?
No. The primary page method is page.screenshot(); element captures use locator.screenshot().
Recommended Free Tools
What does Playwright return when no path is supplied?
It returns a buffer containing the captured image, which you can process or upload in memory.
Is page.screenshot() the same as toHaveScreenshot()?
No. page.screenshot() creates an image directly. toHaveScreenshot() is a Playwright Test visual assertion that compares stabilized screenshots.
The Bottom Line
Use await page.screenshot() for a page, add path to save it, set fullPage: true for the complete document, and use locator.screenshot() for a specific element.
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.
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 glitches

