Skip to main content

Video Recording

Record browser sessions as WebM videos with chapter markers and action callouts.

Commands​

CommandDescription
video-start [filename]Start recording
video-stopStop and save
video-chapter <title>Show a full-screen chapter card and mark the position
video-show-actionsAnnotate subsequent actions with a callout and highlight
video-hide-actionsStop annotating actions

Basic recording​

playwright-cli open https://example.com
playwright-cli video-start demo.webm
playwright-cli click e5
playwright-cli fill e3 "test"
playwright-cli video-stop
# Video saved to: .playwright-cli/demo.webm

Without a filename the video is saved as video-{timestamp}.webm in the output directory.

Video size​

playwright-cli video-start --size=800x600

If --size is omitted, the recording is scaled to fit 800x800.

Chapter markers​

video-chapter blurs the page and shows a chapter card for the given duration, then removes it — useful for section transitions in a walkthrough.

playwright-cli video-start

playwright-cli video-chapter "Step 1: Login" --description="Signing in as a returning user" --duration=2000
playwright-cli goto https://app.example.com/login
playwright-cli fill e3 "user@example.com"
playwright-cli fill e5 "password"
playwright-cli click e7

playwright-cli video-chapter "Step 2: Navigate to settings"
playwright-cli goto /settings

playwright-cli video-chapter "Step 3: Update profile"
playwright-cli fill e10 "New Display Name"
playwright-cli click e15

playwright-cli video-stop

Action callouts​

video-show-actions makes every subsequent command narrate itself in the recording: a callout names the action and the target element is highlighted, with an animated pointer moving between action points.

playwright-cli video-start walkthrough.webm
playwright-cli video-show-actions --duration=600 --position=top-right

playwright-cli click e5
playwright-cli fill e3 "test"

playwright-cli video-hide-actions
playwright-cli video-stop
OptionDescription
--duration=<ms>How long each callout stays on screen (default 500)
--position=<pos>top-left, top, top-right, bottom-left, bottom, bottom-right (default top-right)
--cursor=<mode>pointer animates a mouse pointer (default), none disables it

Scripted videos​

For a polished recording — controlled pacing, realistic typing, custom overlays — drive the whole scenario from a single script with run-code instead of issuing commands one at a time. Explore the page with the CLI first to collect the locators, then write the script:

// hero.js
async page => {
await page.screencast.start({ path: 'video.webm', size: { width: 1280, height: 800 } });
await page.goto('https://demo.playwright.dev/todomvc');

// Chapter card: blurs the page, blocks for the duration, then auto-removes.
await page.screencast.showChapter('Adding Todo Items', {
description: 'We will add several items to the todo list.',
duration: 2000,
});

const input = page.getByRole('textbox', { name: 'What needs to be done?' });
await input.pressSequentially('Walk the dog', { delay: 60 });
await input.press('Enter');
await page.waitForTimeout(1000);

// Sticky overlay: pointer-events are disabled, so it never blocks interaction.
const annotation = await page.screencast.showOverlay(`
<div style="position: absolute; top: 8px; right: 8px; padding: 6px 12px;
background: rgba(0,0,0,0.7); border-radius: 8px; font-size: 13px; color: white;">
✓ Item added successfully
</div>
`);

await input.pressSequentially('Buy groceries', { delay: 60 });
await input.press('Enter');
await page.waitForTimeout(1500);
await annotation.dispose();

await page.screencast.stop();
}
playwright-cli run-code --filename=hero.js

Overlay API​

MethodUse case
page.screencast.start(options) / stop()Start and stop the recording
page.screencast.showChapter(title, { description?, duration?, styleSheet? })Full-screen chapter card with a blurred backdrop
page.screencast.showOverlay(html, { duration? })Custom HTML overlay — callouts, labels, highlights
page.screencast.showActions(options) / hideActions()The API behind video-show-actions
disposable.dispose()Remove a sticky overlay added without a duration
page.screencast.hideOverlays() / showOverlays()Temporarily hide or show all overlays

Overlays are pointer-events: none, so they can stay visible while you click, fill, or interact with the page. To position one over a specific element, read its box first:

const bounds = await page.getByText('Walk the dog').boundingBox();

Video vs tracing​

FeatureVideoTracing
OutputWebM fileTrace files viewable in the Trace Viewer
ShowsVisual recordingDOM snapshots, network, console, actions
Best forDemos, documentation, bug reportsDebugging and analysis
SizeLargerSmaller

Use cases​

ScenarioApproach
Bug reproductionRecord steps, attach to issue
Test documentationRecord with chapter markers
Agent monitoringRecord agent sessions for review
Demo creationScript the scenario with run-code and overlays