How to Record a Website Screencast with Playwright
Record browser actions with Playwright using context video recording, Playwright Test, or explicit screencast controls. Learn how to set dimensions, save files, and fix common issues.
To record a website screencast with a standalone Playwright script, enable recordVideo when you create the browser context, perform the browser actions, then await context.close(). Playwright writes the video when the context closes. For Playwright Test, configure the video option. For precise start and stop boundaries, use page.screencast in Playwright v1.59 or later.
These APIs record browser page content. They do not capture the full desktop, operating-system UI, or other applications.
1. Record a browser session from a Node.js script
Install Playwright and its Chromium browser if they are not already installed in your project:
npm install playwright
npx playwright install chromium
Create record.mjs. This complete example records a navigation and a short interaction:
import { 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('link').first().click();
// Closing the context finalizes the video file.
await context.close();
await browser.close();
Run it with node record.mjs. The recording is created under videos/, with a generated filename. Create the output directory first if your environment or workflow requires it. Enable recording on the context before creating and using pages; pages in that context receive video objects.
Choose the viewport and output dimensions
Set the page viewport to control the browser content being recorded. If a fixed video size matters, set recordVideo.size too. Playwright scales the page to fit the requested video dimensions. A manually configured recording defaults to scaling the viewport to fit within 800×800; if you do not set a viewport, the documented default video size is 800×450.
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
recordVideo: {
dir: 'videos/',
size: { width: 1280, height: 720 },
},
});
Choose dimensions that fit the page composition you want viewers to see. The recorded frame contains the page view, not browser chrome or the entire desktop. See the official Playwright Videos guide and BrowserType API documentation.
2. Record videos during Playwright Test runs
For a test suite, use the Playwright Test video setting rather than manually creating a context in each test. Videos are off by default. Set the mode in your Playwright configuration:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
video: 'on-first-retry',
},
});
The documented modes are:
| Mode | When to choose it |
|---|---|
off |
Do not record videos. This is the default. |
on |
Record every test run. |
retain-on-failure |
Record runs and keep videos for tests that fail. |
on-first-retry |
Record when a test is retried for the first time. |
Test recordings are written to the test output directory, typically test-results, and become available when the context closes after the test. You can also configure video dimensions and use the documented action or test annotations. See the Playwright Videos guide for the current configuration details.
3. Save the video to a specific path
When recording is enabled for a page, page.video().path() returns its video path. The file is guaranteed to be written only after the browser context closes, and path() throws when connected remotely. Use saveAs() when you want to copy the completed recording to a known destination; it waits for the page to close and the video to finish saving.
import { 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.video().saveAs('website-demo.webm');
await context.close();
await browser.close();
Do not try to read, upload, or move the video as though it were complete before the page or context closes. See the official Video API documentation.
4. Start and stop a screencast at exact points
For precise boundaries, Playwright v1.59 introduced page.screencast.start() and page.screencast.stop(). Check the Playwright version installed in the project before using this API. The requested dimensions are maximum bounds; frames preserve the page aspect ratio and may be smaller.
import { chromium } from 'playwright';
const browser = await chromium.launch();
const context = await browser.newContext({
viewport: { width: 1280, height: 800 },
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.screencast.start({
path: 'website-demo.webm',
size: { width: 1280, height: 800 },
});
// Only actions after start and before stop belong to this screencast.
await page.getByRole('link').first().click();
await page.screencast.stop();
await context.close();
await browser.close();
The API can also deliver JPEG frames through onFrame and supports action annotations and overlay or chapter helpers. If a screencast is already active, its existing configuration may take precedence. Consult the Page API documentation and Playwright release notes for version-specific details.
5. Pick the recording workflow
| Need | Use |
|---|---|
| Record an ad hoc scripted browser walkthrough | recordVideo on a browser context |
| Collect videos from a test suite | Playwright Test’s video option |
| Keep videos selectively for failures or retries | retain-on-failure or on-first-retry |
| Control exactly where recording begins and ends | page.screencast.start() and stop(), on v1.59+ |
| Use a consistent frame composition | Set both viewport and video size intentionally |
6. Troubleshoot common problems
| Symptom | Likely cause | Fix |
|---|---|---|
| No video file appears | The context is still open, or recording was not enabled when it was created. | Set recordVideo in browser.newContext() before creating the page, then await context.close(). |
| The video exists but is empty or incomplete | The script ended before the intended actions, or the context closed too early. | Await navigation and interactions, then close the context after the final action. Use saveAs() when you need to wait for the artifact explicitly. |
page.video().path() throws |
The browser is connected remotely, where the local path is unavailable. | Use page.video().saveAs(destination) where supported, or retrieve the artifact through the remote runner’s documented mechanism. |
| Video size or framing is unexpected | The viewport and output size differ, so the page view is scaled to fit. | Set both viewport and recordVideo.size to the intended dimensions. Keep the page’s important content within that viewport. |
page.screencast is unavailable |
The installed Playwright version is older than v1.59. | Check and update the project dependency if appropriate, or use context-level recordVideo. |
| Test videos are missing | The test configuration has video: 'off' or only retains recordings under a condition that was not met. |
Choose on while diagnosing, or confirm the test failed or retried for the selected retention mode. Look in the test output directory. |
7. Reliability, runtime, and storage considerations
- Close contexts cleanly. Video finalization depends on context closure. In scripts that can fail partway through, put context and browser cleanup in a
finallyblock so the recording has a chance to flush. - Wait for page readiness. Await the navigation and actions that should appear in the recording. If the page uses delayed content, wait for the relevant locator or state instead of assuming a fixed short delay.
- Choose retention intentionally. Recording every test produces more artifacts to retain and inspect; failure and retry modes limit which videos remain available according to their documented behavior.
- Plan for artifact handling. Save videos to an output directory your CI system collects, and retrieve them only after the context or test has closed.
- Expect extra work when capturing video. Recording adds an artifact and its storage and transfer needs to the browser run. The cited documentation gives configuration behavior, not comparative performance measurements, so benchmark your own workload if runtime or storage is constrained.
8. Or skip the browser setup
If you need a still screenshot rather than a video of browser actions, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns an image or PDF; see the ScreenshotNeo website and API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', image));
ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. This captures a page image or PDF, not a video of browser actions. Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Does Playwright record audio?
The documented video recording workflow here records page video. Do not assume it captures audio; check the current Playwright API documentation for any audio requirements.
Can I record more than one page in a context?
Video recording is associated with pages in the context when recordVideo is enabled. Each page has a video object; manage and save the pages’ artifacts separately as needed.
Can I record a desktop application with this method?
No. These APIs record browser page content. Use a desktop capture tool if the output must include operating-system chrome or other applications.
Can I use ScreenshotNeo to create a screencast?
No. ScreenshotNeo returns a website screenshot or PDF from a GET request. Use Playwright’s browser video recording for a sequence of actions.


