Use Playwright Test’s built-in page fixture and call await page.screenshot() at the exact state you want to inspect. Pass a path to save an image, or keep the returned bytes and attach them with testInfo.attach(). Use a trace when you need actions, DOM snapshots, and network context; enable video only when a replay of the run is useful. Playwright Test creates an isolated browser context for each test, while manually created contexts must be closed so video and other artifacts are finalized.
How do I take a screenshot in a Playwright test?
Install Playwright Test and create a test file such as tests/capture.spec.ts:
import { test, expect } from '@playwright/test';
test('capture the landing page', async ({ page }) => {
await page.goto('https://playwright.dev');
await expect(page).toHaveTitle(/Playwright/);
await page.screenshot({ path: 'artifacts/landing.png', fullPage: true });
});
The runner supplies page through its built-in fixture. The screenshot is taken after navigation and the title assertion, so the captured state is meaningful rather than an intermediate loading screen. page.screenshot() returns a buffer when no path is supplied; providing path writes the image to that location. See the Page API documentation for the complete option set.
Save a viewport or full-page image
await page.screenshot({ path: 'shot.png' })captures the current viewport.fullPage: trueextends the image through the page’s full scrollable height.- Choose an extension such as
.pngor.jpegthat matches the format you need; use the documented screenshot options for quality and masking controls.
Capture after a stable locator is visible when the page contains asynchronous content:
#1 Best Overall
await page.goto('https://example.com');
await page.getByRole('main').waitFor();
await page.screenshot({ path: 'artifacts/ready.png' });
In a Playwright Test project, artifact paths should normally be placed under a directory you control or one configured for your CI artifact collection. The runner’s result directory is preferable when you want reporters to associate files with a test rather than leave files in the repository.
How do I attach a screenshot to the Playwright Test result?
Call page.screenshot() without a path, then pass the returned bytes to testInfo.attach():
import { test, expect } from '@playwright/test';
test('attach a visual checkpoint', async ({ page }, testInfo) => {
await page.goto('https://playwright.dev');
await expect(page.getByRole('heading', { name: 'Playwright enables reliable end-to-end testing for modern web apps.' })).toBeVisible();
const screenshot = await page.screenshot();
await testInfo.attach('homepage', {
body: screenshot,
contentType: 'image/png',
});
});
TestInfo.attach() copies the attachment to a location available to reporters. Supplying body with the screenshot buffer avoids a temporary file, while contentType tells the reporter how to display it. The API is documented in the TestInfo reference.
Attach only when a test fails
A screenshot is most useful as failure evidence when routine passing artifacts would create noise. This pattern captures the current page in a failure handler:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
import { test } from '@playwright/test';
test('checkout flow', async ({ page }, testInfo) => {
await page.goto('https://example.com/checkout');
try {
await page.getByRole('button', { name: 'Pay' }).click();
await page.getByText('Payment complete').waitFor();
} catch (error) {
await testInfo.attach('failure-state', {
body: await page.screenshot(),
contentType: 'image/png',
});
throw error;
}
});
For broad failure handling, configure Playwright Test’s reporter and artifact policy rather than duplicating this wrapper in every test. Keep the attachment name stable and descriptive so HTML or CI reporters are easy to scan.
Rank #2
When should I use a screenshot, trace, or video?
| Artifact | Best for | Important behavior |
|---|---|---|
| Screenshot | One visual state, such as a layout checkpoint or failure screen | Small, direct output from page.screenshot(); save it or attach its bytes |
| Trace | Explaining a failed sequence of actions | Can include action details, locator data, durations, DOM snapshots, and a screenshot film strip; recording every test can be performance heavy |
| Video | A replay-like visual record, especially for intermittent failures | Opt-in and finalized only after the page or browser context closes |
Use tracing when the image cannot explain the failure
A screenshot shows one moment. A trace preserves the path to that moment and can reveal which locator, request, snapshot, or timing caused the problem. For Playwright Test, configure tracing in the test-runner configuration so assertion context is retained:
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
trace: 'retain-on-failure',
},
});
Open the resulting trace with the Trace Viewer. It exposes action details, locator information, action duration, source location, DOM snapshots, and a film strip when screenshots are enabled. The Trace Viewer guide describes the available retention modes.
Do not confuse runner tracing with library tracing
Standalone Playwright scripts can use browserContext.tracing directly:
Recommended Free Tools
import { chromium } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext();
await context.tracing.start({ screenshots: true, snapshots: true });
const page = await context.newPage();
await page.goto('https://playwright.dev');
await context.tracing.stop({ path: 'artifacts/trace.zip' });
await context.close();
await browser.close();
Direct context tracing records browser operations and network activity, but it does not record test assertions. If assertion-level failure context matters, use Playwright Test configuration instead. The limitation is documented in the Tracing API.
Record video deliberately
Video recording is off by default. Select a mode in playwright.config.ts:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
video: 'retain-on-failure',
// Alternatives include: 'on', 'on-first-retry', and 'retain-on-first-failure'.
},
});
Use retain-on-failure when ordinary passing runs do not need videos. Choose on-first-retry when intermittent failures are the main concern. The exact supported modes and their retention behavior are listed in the Videos guide.
How does video behave with a manually created context?
When you use the library rather than the Test runner, enable recording while creating the context and close that context before reading the file:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext({
recordVideo: { dir: 'artifacts/videos' },
});
const page = await context.newPage();
await page.goto('https://playwright.dev');
await page.waitForTimeout(500);
await context.close(); // finalizes the video
await browser.close();
Attempting to inspect the recording before context.close() is premature because the video is finalized at context closure. The browser API documents explicit context lifecycle and video setup at Browser API.
Why browser-context isolation matters for captures
Playwright Test gives each test its own browser context, including separate cookies and storage. The isolation described in the browser-context guide prevents one test’s login or local-storage state from leaking into another and makes screenshots reproducible. The built-in page fixture belongs to that isolated context; you normally do not need to launch a browser or create a context in each test. Fixture setup and teardown are covered in the fixtures guide.
Standalone scripts have no such automatic lifecycle. Create a context explicitly, perform captures, close the context, and only then close the browser. If a screenshot unexpectedly shows a logged-out or first-visit state, check whether the test is using the intended fixture, storage state, viewport, and project configuration.
Rank #4
Reliable capture workflow
- Choose the artifact. Use a screenshot for a single state, a trace for action-level diagnosis, and video for replaying visual timing.
- Wait for the right state. Prefer locator assertions or waits for application readiness over arbitrary delays.
- Capture through the runner fixture. In a test, use the supplied
page; do not create an extra context unless the test specifically requires it. - Retain intentionally. Attach buffers for reporter visibility, save files for external processing, and retain traces or videos mainly on failures and retries.
- Close manually created contexts. This is required to finalize video and other context-owned artifacts.
- Collect artifacts in CI. Configure your CI system to preserve the Playwright result directory or the paths you selected.
Troubleshooting common capture problems
The screenshot is blank or taken too early
Cause: navigation or application rendering has not reached the state you intended. Fix: wait for a meaningful locator or assertion, and verify that the URL and page state are correct before calling screenshot(). Avoid relying solely on a fixed timeout.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteThe attachment does not appear in the report
Cause: the buffer was not passed to testInfo.attach(), or the content type is missing or incorrect. Fix: pass body: await page.screenshot() and contentType: 'image/png'; use a reporter that displays attachments.
The trace lacks assertion details
Cause: tracing was started through browserContext.tracing in a standalone script. Fix: configure the Playwright Test trace option when you need the runner’s assertion-aware failure workflow.
The video file is missing or incomplete
Cause: video recording is opt-in, or the manually created context was not closed. Fix: set a supported video mode in runner configuration, or use recordVideo and await context.close() before reading artifacts.
Tests influence one another
Cause: shared state in a manually reused context, rather than Playwright Test’s isolated fixture. Fix: use the built-in page fixture for independent tests, or create and close a fresh context for each standalone scenario.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server when you need a rendered URL without maintaining Playwright browser-launch code. Its capture endpoint accepts a URL and returns PNG, JPEG, WebP, or PDF. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
One cURL request:
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 documentation for options including full-page capture, CSS selectors, device and viewport settings, dark mode, custom JavaScript and CSS, waits, request blocking, cookies, headers, geolocation, PDFs, caching, signed links, asynchronous jobs, bulk capture, and the MCP tools take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000. Sign up free.
FAQ
Does page.screenshot() return an image buffer?
Yes. Without path, it returns screenshot bytes that you can attach or process in memory.
Are Playwright Test videos enabled automatically?
No. Video recording is off by default and must be selected through the video configuration option.
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 →Can a trace replace a screenshot?
They serve different purposes: a trace explains a sequence and its context, while a screenshot records one visual state.
Frequently Asked Questions
Does page.screenshot() return an image buffer?
Yes. Without path, it returns screenshot bytes that you can attach or process in memory.
Are Playwright Test videos enabled automatically?
No. Video recording is off by default and must be selected through the video configuration option.
Can a trace replace a screenshot?
They serve different purposes: a trace explains a sequence and its context, while a screenshot records one visual state.
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 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchQuick 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.

