Recommended Free Tools
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 records browser video in two ways: configure the Playwright Test runner with use.video, or enable recordVideo on a browser context when using the library directly. In both cases, wait for the browser context to close before treating the file as complete. Use the test-runner modes for automatic retention (all tests, failures only, or first retries); use the library API or Screencast API when your script needs destination or start/stop control.
Choose the recording method
| Use case | API | When the file is finalized | Retention control |
|---|---|---|---|
| Playwright Test debugging | use.video in playwright.config.ts |
At the end of the test, when its browser context closes | off, on, retain-on-failure, or on-first-retry |
| Standalone Playwright script | recordVideo in browser.newContext() |
When you close the recording context | Your script decides which files to keep |
| Explicit start and stop | page.screencast.start() and stop() |
When stop() completes |
Controlled around a particular interaction |
The official references are the Playwright video guide, Browser API, Video API, and Screencast API.
Record videos in Playwright Test
Configure recording in playwright.config.ts
Video is off by default. Add a use.video setting to your Playwright Test configuration:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
video: 'on-first-retry',
},
});
This records a test when it is retried and keeps the video from the first retry. The output is written under the test output directory, typically test-results. The recording is saved as the test’s browser context closes.
#1 Best Overall
Pick the retention mode
off: no videos (the default).on: record every test, useful when you need a complete visual archive but produces the most artifacts.retain-on-failure: record tests and remove videos for successful tests, keeping failures for diagnosis.on-first-retry: record only the first retry, which limits storage while preserving a reproduction attempt.
Choose the mode according to retention rather than image quality: all four modes use the same browser recording mechanism. For CI, failure-only or first-retry recording usually keeps artifact volume manageable; for investigating a flaky flow, first-retry captures the run where the failure is being reproduced.
Find the resulting file
After a run, inspect the configured test output directory (normally test-results) and the test’s artifact folder. A video is not guaranteed to exist for a successful test when you selected retain-on-failure or on-first-retry; that is expected retention behavior, not a capture error.
Record a video with the Playwright library
Minimal runnable JavaScript example
Set recordVideo.dir when creating a browser context. Perform all interactions, then close that context:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsimport { chromium } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext({
recordVideo: { dir: 'videos/' },
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.getByRole('heading').waitFor();
// Perform the browser actions you want to capture.
await context.close(); // finalizes the recording
await browser.close();
The directory is created or used as the destination for the recording. Closing only the page is not the normal save boundary for context recording; close the context and await the promise before uploading, renaming, or inspecting the file.
Rank #2
Set the output dimensions
const context = await browser.newContext({
viewport: { width: 1280, height: 800 },
recordVideo: {
dir: 'videos/',
size: { width: 1280, height: 800 },
},
});
recordVideo.size sets the video frame dimensions. If you omit dimensions, Playwright scales the viewport to fit 800×800. If you also omit an explicit viewport, the documented default viewport is 800×450. Set both values when a downstream editor, review system, or regression comparison requires a predictable 16:10, 16:9, or other size. The recording dimensions and the browser viewport serve different purposes: the viewport controls layout, while size controls the encoded frame.
Capture a scenario reliably
- Create one context with
recordVideoenabled. - Create pages from that context; pages associated with recording expose a
videoobject. - Navigate and wait for the state you want visible in the artifact (for example, wait for a selector rather than relying on a fixed sleep).
- Perform the interaction sequence.
- Await
context.close()before checking that the file exists.
Get, save, or delete a recording
Use the page’s Video object
const video = page.video();
await context.close();
const path = await video.path();
console.log(`Saved to ${path}`);
video.path() returns the output path after the context closes. It throws when the browser is connected remotely, so do not build a remote execution workflow that depends on a local path being available.
Copy the artifact with saveAs
const video = page.video();
await video.saveAs('artifacts/login-flow.webm');
saveAs(path) can be called while recording is in progress or after the page closes. It waits for the page to close and for the video to be fully saved, making it suitable when you need a known artifact name. To remove an unwanted recording, call await video.delete() after the recording has been finalized.
Control exactly when recording starts and stops
Context recording runs for the context lifetime. If you need to capture only one portion of a longer script, use the Screencast API:
await page.screencast.start({
path: 'video.webm',
size: { width: 1280, height: 800 },
});
await page.goto('https://example.com');
// Interactions to include in the clip.
await page.screencast.stop();
start accepts a destination path and optional dimensions; stop saves the recording to that path. This is the direct start/stop choice when a context-wide recording would include setup or teardown that you do not want in the final clip.
Dimensions, timing, and artifact management
Make the frame match the intended layout
- Set an explicit
viewportfor deterministic responsive behavior. - Set matching
recordVideo.size(or Screencastsize) when consumers expect fixed dimensions. - Use the default only when the 800×800 scaling behavior, or the 800×450 default viewport, is acceptable.
Wait for meaningful visual states
Video captures what the browser displays, not what your test intended to display. Wait for a selector, navigation state, or application-ready condition before the interaction you want reviewers to see. Avoid making a fixed delay the only synchronization mechanism; network and rendering time vary between runs.
Close in a predictable order
For normal context recording, await context.close() first, then read or upload the file, and finally close the browser. If your script has multiple contexts, close each recording context and retain its corresponding Video object so artifacts are not mixed up.
Troubleshooting
No video appears
- Test runner: verify that
use.videois notoffand that your selected retention mode would keep this test. A passing test withretain-on-failureis intentionally deleted. - Library script: verify that the context, rather than the browser, was created with
recordVideo. - Premature inspection: await
context.close()before checking the directory or callingvideo.path().
The file is incomplete or cannot be opened
Ensure the close or stop promise is awaited. Do not terminate the process immediately after an interaction; finalization occurs at context close for recordVideo, and at screencast.stop() for Screencast.
Rank #4
video.path() fails in CI
The Video API documents that path() throws for remotely connected browsers. Use video.saveAs() where supported, or collect artifacts through the remote runner’s own storage mechanism instead of assuming a local filesystem path.
The video has the wrong size
Set both viewport and the recording size. Omitting size invokes Playwright’s scaling rule, while omitting viewport invokes the documented 800×450 default viewport.
The clip includes unwanted setup
Use Screencast start/stop around the exact interaction, or create a fresh recording context immediately before the scenario. Test-runner video modes are designed for test artifacts, not arbitrary clip boundaries.
Or skip the browser setup
If you need a still screenshot of a page rather than a time-based browser video, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. It is not a replacement for Playwright video recording, but it avoids maintaining a browser capture script for static artifacts.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for options. 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 as clean shots, and response headers report the page verdict and billing status. ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Sign up for the free plan.
FAQ
Is Playwright video recording enabled automatically?
No. Playwright Test defaults to video: 'off'; standalone scripts must explicitly set recordVideo on the context.
Can I choose MP4 instead of the default recording format?
The documented APIs in this workflow specify destination, dimensions, and lifecycle, but do not state an MP4 output option. Plan your post-processing around the format produced by your installed Playwright/browser setup.
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 →Should I use context recording or Screencast?
Use context recording for whole-test artifacts and Screencast when you need an explicit start and stop around a smaller segment.
Frequently Asked Questions
Does closing a page finalize a Playwright video?
Normal recordVideo recordings are finalized when the browser context closes; await browserContext.close() before relying on the file.
Can I access a video path with a remote browser?
video.path() throws when connected remotely. Use an available artifact-transfer mechanism or saveAs() where supported.
How do I keep videos only for failed tests?
Set use.video to 'retain-on-failure' in playwright.config.ts.
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.

