Examples
These code blocks are imported from runnable files in this repository.
Playwright script
examples/playwright.tsuses the explicit Playwright backend. The 2.0 native default is covered in the getting-started guide. It uses defineSuiteCut() without Playwright Test, a reporter, fixtures, or a Playwright configuration file. It records a local page, uses SuiteCut's cursor and highlight, captures a checkpoint, and prints the manifest path.
import { defineSuiteCut } from 'suitecut/playwright'
const record = defineSuiteCut({
browserName: 'chromium',
launch: { headless: true },
context: { colorScheme: 'light' },
capture: {
viewport: { width: 1280, height: 720 },
size: { width: 1280, height: 720 },
framesPerSecond: 30,
quality: 90,
},
output: {
directory: '.suitecut/playwright-example',
manifestPath: '.suitecut/playwright-example.json',
pathKind: 'manifest-relative',
},
})
const result = await record('plain Playwright recording', async ({ page, suitecut }) => {
await page.setContent(`
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>SuiteCut plain Playwright example</title>
<style>
body { font: 18px system-ui; margin: 0; padding: 64px; }
main { max-width: 720px; margin: 0 auto; }
button { font: inherit; padding: 12px 18px; }
#status { margin-top: 24px; }
</style>
</head>
<body>
<main>
<h1>Record a browser flow</h1>
<p>This script owns Playwright's browser lifecycle. There is no test runner.</p>
<button type="button">Create report</button>
<p id="status" aria-live="polite">No report yet.</p>
<script>
document.querySelector('button').addEventListener('click', () => {
document.querySelector('#status').textContent = 'Report created.'
})
</script>
</main>
</body>
</html>
`)
const create = page.getByRole('button', { name: 'Create report' })
await suitecut.highlight(create, { durationMs: 700 })
await suitecut.click(create)
await suitecut.hold(400)
await suitecut.checkpoint('Report created')
})
console.log(`Manifest: ${result.manifestPath}`)npm run build
node --experimental-strip-types examples/playwright.ts
suitecut render \
--manifest .suitecut/playwright-example.json \
--output .suitecut/videos/playwright-example.mp4OpenAI Status livestream
examples/playwright/openai-status-livestream.ts publishes the public OpenAI Status page at 1080p with tab audio. It highlights the system status, stays live untilCtrl+C, and reconnects after an ingest interruption.
import { record } from 'suitecut/playwright'
const streamUrl = process.env.SUITECUT_STREAM_URL
if (!streamUrl) {
throw new Error('Set SUITECUT_STREAM_URL to your full RTMP or RTMPS publish URL.')
}
const statusUrl = process.env.SUITECUT_STATUS_URL ?? 'https://status.openai.com/'
const headed = process.env.SUITECUT_HEADED === '1'
const controller = new AbortController()
const stop = (): void => controller.abort()
process.once('SIGINT', stop)
process.once('SIGTERM', stop)
try {
await record(
'OpenAI Status livestream',
async ({ page, suitecut, signal }) => {
await page.goto(statusUrl, { waitUntil: 'domcontentloaded' })
await suitecut.hold(2_000)
const systemStatus = page.getByRole('heading', { name: 'System status' })
if ((await systemStatus.count()) > 0) {
await suitecut.scrollTo(systemStatus, { behavior: 'smooth', settleMs: 800 })
await suitecut.highlight(systemStatus, { durationMs: 1_200 })
}
await new Promise<void>((resolve) => {
if (signal?.aborted === true) resolve()
else signal?.addEventListener('abort', () => resolve(), { once: true })
})
},
{
launch: { headless: !headed },
capture: {
viewport: { width: 1920, height: 1080 },
framesPerSecond: 30,
stream: {
url: streamUrl,
audio: true,
bitrateKbps: 4500,
onDiagnostic: (event) => console.log(event.event, event.bottleneck),
reconnect: { initialDelayMs: 1_000, maxDelayMs: 30_000, maxAttempts: 0 },
},
},
signal: controller.signal,
},
)
} catch (error) {
if (!controller.signal.aborted) throw error
} finally {
process.off('SIGINT', stop)
process.off('SIGTERM', stop)
}SUITECUT_STREAM_URL='rtmps://your-ingest/app/your-stream-key' \
pnpm example:livestream:statusPlaywright Test in three browsers
examples/browser-support.spec.ts is the focused browser matrix. The repository runs the same recording in Chromium, Firefox, and WebKit, then verifies every attempt, source-video artifact, event set, dimension, frame rate, and duration.
import { expect, test } from 'suitecut/test'
test.use({
suitecutCapture: {
viewport: { width: 960, height: 540 },
framesPerSecond: 30,
quality: 85,
},
})
test('records a SuiteCut flow in every supported browser', async ({ page, suitecut }) => {
await page.setContent(`
<main style="display:grid;place-content:center;min-height:100vh;font:20px system-ui">
<button type="button" style="padding:16px 24px">Create report</button>
<p role="status">Waiting</p>
</main>
<script>
document.querySelector('button').addEventListener('click', () => {
document.querySelector('[role=status]').textContent = 'Report created'
})
</script>
`)
const createReport = page.getByRole('button', { name: 'Create report' })
await suitecut.checkpoint('Browser ready')
await suitecut.highlight(createReport, { durationMs: 450, label: 'Create report' })
await suitecut.click(createReport, {
moveDurationMs: 120,
settleMs: 80,
waitForAnimations: false,
})
await expect(page.getByRole('status')).toHaveText('Report created')
await suitecut.hold(200)
})npm run test:browsersMore repository examples
examples/product-tour.spec.tsrecords narration, captions, pointer movement, a click effect, holds, highlights, zoom, and a checkpoint inside Playwright Test.examples/popup-tour.spec.tsrecords an opener and popup, then returns the active recording to the opener after the popup closes.examples/browser-presentation.spec.tschecks captions, highlights, pointer actions, application animation waits, native scrolling, navigation, and an off-screen zoom target.examples/playwright/product-tour.tsrecords the product tour through the standalone Playwright lifecycle.examples/playwright/popup-tour.tsrecords a popup and opener without Playwright Test.examples/playwright/custom-setup.tsstarts a local HTTP server insetup(), returns its URL as a typed callback value, and registers reverse-order cleanup.examples/playwright/checkpoints.tscaptures short WebM checkpoint clips from the page screencast.site/tests/site-demo.spec.tsgenerates the 4K, 60 fps demo embedded on the homepage.
Select a test or retry
suitecut render \
--manifest .suitecut/latest-run.json \
--test-id <playwright-test-id> \
--retry 0 \
--output .suitecut/videos/tour.webm \
--container webmChoose a container and encoders
suitecut render \
--manifest .suitecut/latest-run.json \
--output .suitecut/videos/tour.mov \
--container mov \
--video-codec prores_ks \
--audio-codec pcm_s24le \
--pixel-format yuv422p10leSuiteCut infers MP4, WebM, MOV, or MKV from the output extension. You can select any compatible encoder in the installed FFmpeg build. --color-range controls sample range, not the video or audio codec.