Examples

These code blocks are imported from runnable files in this repository.

Plain Playwright

examples/playwright.tsuses 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.

TypeScript
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}`)
Terminal
npm run build
node --experimental-strip-types examples/playwright.ts

suitecut render \
  --manifest .suitecut/playwright-example.json \
  --output .suitecut/videos/playwright-example.mp4

Playwright 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.

TypeScript
import { expect, test } from 'suitecut'

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)
})
Terminal
npm run test:browsers

More repository examples

Select a test or retry

Terminal
suitecut render \
  --manifest .suitecut/latest-run.json \
  --test-id <playwright-test-id> \
  --retry 0 \
  --output .suitecut/videos/tour.webm \
  --container webm

Choose a container and encoders

Terminal
suitecut render \
  --manifest .suitecut/latest-run.json \
  --output .suitecut/videos/tour.mov \
  --container mov \
  --video-codec prores_ks \
  --audio-codec pcm_s24le \
  --pixel-format yuv422p10le

SuiteCut 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.