Documentation / API and CLI referenceView source ↗

API and CLI

SuiteCut's fixture, capture, output, reporter, and render option objects reject unknown keys and invalid values. Playwright launch and browser-context options pass through to Playwright.

Native API in 2.0

The root record and defineSuiteCut now use CEF. Configure dimensions, device scale, FPS, and executable path in native. Native capture accepts size, narrationTailMs, and booleanaudio. The callback receives source, page,suitecut, signal, and addSource. Locators are strict main-document CSS selectors. See native setup and migration.

TypeScript
import { record, launchBrowser, createBroadcast } from 'suitecut'

await record('Native tour', async ({ page, suitecut }) => {
  await page.goto('https://example.com')
  await suitecut.highlight(page.locator('h1'))
}, {
  native: { width: 1920, height: 1080, framesPerSecond: 60 },
  capture: { audio: true },
})

launchBrowser(options) returns a caller-owned native source.createBroadcast({ source, stream }) publishes it; stop the broadcast and close the source separately. createNativePage(source) exposes page controls outside a recording. Root recording types describe native callbacks and results. Import Playwright recording types fromsuitecut/playwright. The detailed Playwright capture and setup options below apply to that explicit backend and the test integration.

Public exports

These are the main package entry points and public exports. Files belowsuitecut/src are internal and are not public imports.

suitecut

The native CEF recorder, browser launcher, broadcaster, renderer, and their public types.

TypeScript
import {
  DEFAULT_BACKEND,
  launchBrowser,
  createBroadcast,
  createNativePage,
  type SuiteCutBrowserOptions,
  type SuiteCutNativeRecordOptions,
  type SuiteCutPlaywrightRecordOptions,
  type SuiteCutRecordingResult,
  type NativePage,
  type NativeLocator,
  type NativeRecordingContext,
  defineSuiteCut,
  record,
  decodeWordTimingArtifact,
  renderSuiteCut,
  type LiveStreamDiagnostic,
  type SuiteCutBrowserName,
  type SuiteCutDefinitionOptions,
  type SuiteCutWordTiming,
  type SuiteCutWordTimingArtifact,
  type Milliseconds,
  type SuiteCutAnimationOptions,
  type SuiteCutAudioPlugin,
  type SuiteCutAudioPluginReference,
  type SuiteCutAudioSynthesisRequest,
  type SuiteCutBorderStyle,
  type SuiteCutStreamOptions,
  type SuiteCutReconnectOptions,
  type SuiteCutCaptureOptions,
  type SuiteCutCaptureSize,
  type SuiteCutCaptureViewport,
  type SuiteCutCheckpointOptions,
  type SuiteCutCleanup,
  type SuiteCutColorRange,
  type SuiteCutEasing,
  type SuiteCutFixture,
  type SuiteCutHighlightMode,
  type SuiteCutHighlightOptions,
  type SuiteCutJsonValue,
  type SuiteCutNarrationOptions,
  type SuiteCutNarrationProvider,
  type SuiteCutNarrationVoice,
  type SuiteCutOutputOptions,
  type SuiteCutOutputContainer,
  type SuiteCutOutputFormat,
  type SuiteCutPointerActionOptions,
  type SuiteCutRecordOptions,
  type SuiteCutRecordResult,
  type SuiteCutRecorder,
  type SuiteCutRecordingCallback,
  type SuiteCutRecordingContext,
  type SuiteCutRenderConfig,
  type SuiteCutRenderFailureMode,
  type SuiteCutRenderOutputConfig,
  type SuiteCutRenderQuality,
  type SuiteCutRenderReport,
  type SuiteCutRenderRequest,
  type SuiteCutScrollAlignment,
  type SuiteCutScrollBehavior,
  type SuiteCutScrollOptions,
  type SuiteCutSetupContext,
  type SuiteCutTypeOptions,
  type SuiteCutVisualAnimation,
  type SuiteCutZoomOptions,
} from 'suitecut'

suitecut/test

The optional Playwright Test fixture and assertion API.

TypeScript
import { expect, test } from 'suitecut/test'

suitecut/playwright

The explicit Playwright recorder, preserving the 1.x launch, context, and setup APIs.

TypeScript
import {
  defineSuiteCut,
  record,
  type Milliseconds,
  type SuiteCutAudioPluginReference,
  type SuiteCutBrowserName,
  type SuiteCutCaptureOptions,
  type SuiteCutCheckpointOptions,
  type SuiteCutCleanup,
  type SuiteCutDefinitionOptions,
  type SuiteCutFixture,
  type SuiteCutHighlightOptions,
  type SuiteCutNarrationOptions,
  type SuiteCutOutputOptions,
  type SuiteCutPointerActionOptions,
  type SuiteCutRecordOptions,
  type SuiteCutRecordResult,
  type SuiteCutRecorder,
  type SuiteCutRecordingCallback,
  type SuiteCutRecordingContext,
  type SuiteCutScrollOptions,
  type SuiteCutTypeOptions,
  type SuiteCutSetupContext,
  type SuiteCutZoomOptions,
} from 'suitecut/playwright'

suitecut/audio-plugin

The contract and helpers for external narration packages.

TypeScript
import {
  audioPluginReference,
  defineSuiteCutAudioPlugin,
  encodePcm16Wav,
  type SuiteCutAudioPlugin,
  type SuiteCutAudioPluginReference,
  type SuiteCutAudioSynthesisRequest,
  type SuiteCutJsonValue,
} from 'suitecut/audio-plugin'

suitecut/render

The programmatic renderer and its complete request, output, edit, and report types.

TypeScript
import {
  renderSuiteCut,
  type SuiteCutColorRange,
  type SuiteCutEditSegment,
  type SuiteCutOutputContainer,
  type SuiteCutOutputFormat,
  type SuiteCutRenderConfig,
  type SuiteCutRenderFailureMode,
  type SuiteCutRenderOutputConfig,
  type SuiteCutRenderQuality,
  type SuiteCutRenderReport,
  type SuiteCutRenderRequest,
} from 'suitecut/render'

suitecut/reporter

The Playwright reporter class and reporter configuration type.

TypeScript
import SuiteCutReporter, {
  type SuiteCutReporterOptions,
} from 'suitecut/reporter'

suitecut/types

The complete manifest, event, artifact, media, geometry, diagnostic, and identity model.

TypeScript
import {
  SUITECUT_EVENT_ATTACHMENT,
  SUITECUT_MANIFEST_SCHEMA_VERSION,
  type EpochMilliseconds,
  type FilePath,
  type ISODateTime,
  type Milliseconds,
  type MimeType,
  type SuiteCutActiveScreencast,
  type SuiteCutAnimationOptions,
  type SuiteCutArtifact,
  type SuiteCutArtifactId,
  type SuiteCutArtifactRole,
  type SuiteCutAttempt,
  type SuiteCutAttemptClock,
  type SuiteCutAttemptId,
  type SuiteCutAudioStream,
  type SuiteCutBorderStyle,
  type SuiteCutCapturedArtifact,
  type SuiteCutCapturedCheckpointArtifact,
  type SuiteCutCapturedNarrationArtifact,
  type SuiteCutCapturedVideo,
  type SuiteCutCheckpointEvent,
  type SuiteCutCheckpointOptions,
  type SuiteCutDiagnostic,
  type SuiteCutDiagnosticCode,
  type SuiteCutDiagnosticLevel,
  type SuiteCutEasing,
  type SuiteCutError,
  type SuiteCutEvent,
  type SuiteCutEventAttachment,
  type SuiteCutEventBase,
  type SuiteCutEventId,
  type SuiteCutExecutionStep,
  type SuiteCutFixture,
  type SuiteCutHighlightEvent,
  type SuiteCutHighlightMode,
  type SuiteCutHighlightOptions,
  type SuiteCutHoldEvent,
  type SuiteCutHoldReason,
  type SuiteCutManifest,
  type SuiteCutMedia,
  type SuiteCutMediaId,
  type SuiteCutMediaStream,
  type SuiteCutNarrationEvent,
  type SuiteCutNarrationOptions,
  type SuiteCutNarrationProvider,
  type SuiteCutNarrationVoice,
  type SuiteCutPage,
  type SuiteCutPageEventBase,
  type SuiteCutPageSelectionEvent,
  type SuiteCutPageSelectionReason,
  type SuiteCutPageId,
  type SuiteCutPageKind,
  type SuiteCutPathKind,
  type SuiteCutPoint,
  type SuiteCutPointerButton,
  type SuiteCutPointerButtonEvent,
  type SuiteCutPointerMoveEvent,
  type SuiteCutPointerType,
  type SuiteCutRecordingSession,
  type SuiteCutRect,
  type SuiteCutRunStatus,
  type SuiteCutScrollAlignment,
  type SuiteCutScrollBehavior,
  type SuiteCutScrollOptions,
  type SuiteCutSize,
  type SuiteCutSourceLocation,
  type SuiteCutStepCategory,
  type SuiteCutStepId,
  type SuiteCutStepOutcome,
  type SuiteCutTest,
  type SuiteCutTestId,
  type SuiteCutTestStatus,
  type SuiteCutTypeOptions,
  type SuiteCutVideoStream,
  type SuiteCutVideoTiming,
  type SuiteCutViewport,
  type SuiteCutVisualAnimation,
  type SuiteCutZoomEvent,
  type SuiteCutZoomOptions,
} from 'suitecut/types'

Playwright Test

Import from suitecut/test. test extends Playwright Test with thesuitecut fixture and two options. expect is Playwright's normal assertion API.

  • suitecut: the recording controls documented below.
  • suitecutCapture: viewport, device scale, source size, frame rate, quality, narration tail, and streaming options.
  • suitecutAudioPlugins: external provider references loaded in the narration worker.

Fixture methods

TypeScript
interface SuiteCutFixture {
  selectPage(page: Page): void
  narrate(text: string, options?: SuiteCutNarrationOptions): Promise<void>
  checkpoint(label: string, options?: SuiteCutCheckpointOptions): Promise<void>
  hold(durationMs: number): Promise<void>
  highlight(locator: Locator, options?: SuiteCutHighlightOptions): Promise<void>
  zoom(locator: Locator, options?: SuiteCutZoomOptions): Promise<void>
  hover(locator: Locator, options?: SuiteCutPointerActionOptions): Promise<void>
  click(locator: Locator, options?: SuiteCutPointerActionOptions): Promise<void>
  type(locator: Locator, text: string, options?: SuiteCutTypeOptions): Promise<void>
  scrollTo(locator: Locator, options?: SuiteCutScrollOptions): Promise<void>
  scrollTop(options?: SuiteCutScrollOptions): Promise<void>
}

selectPage(page): void

Selects the main page, popup, or secondary page used by later narration, checkpoints, holds, andscrollTop(). Locator methods select their locator's page automatically. Closing a selected popup returns selection to its opener when possible.

narrate(text, options?): Promise<void>

Synthesizes speech locally, records its audio, displays a caption, and waits for the measured clip plus the configured narration tail. Synthesis time is excluded from the recording clock. Thetext must not be empty.

  • provider: kokoro by default, macos-say, or a configured audio plugin ID.
  • voice: af_heart for Kokoro; the native provider uses its system default when omitted.
  • speed: 0.5 through 2; default 1.
  • caption: override the spoken text shown on screen. Use an empty string to hide the caption without removing audio.

checkpoint(label, options?): Promise<void>

Marks the current page state and attaches a WebM clip cut from the same page screencast used by the final render. The label must not be empty. durationMs sets the recording window; the default is 500 milliseconds and the maximum is 10000.

hold(durationMs): Promise<void>

Keeps the selected browser page recording its current state. The duration is in milliseconds and must be greater than zero.

highlight(locator, options?): Promise<void>

Measures a visible locator and records the complete highlight animation in the selected browser. Hidden or geometry-less locators fail clearly.

  • durationMs: total duration; default 1200.
  • mode: outline by default, fill, or spotlight.
  • geometry: element by default, or content to tightly wrap rendered text and controls inside a block.
  • paddingPx: 8; borderWidthPx: 4.
  • borderStyle: solid by default, or dashed.
  • borderColor: #7C3AED; borderRadiusPx: 10.
  • fillColor: #7C3AED; fillOpacity: 0.08.
  • backdropColor: #000000; backdropOpacity: 0.45.
  • label: optional text displayed above the target.
  • enter: default { type: 'fade', durationMs: 180, easing: 'ease-out' }.
  • exit: default { type: 'fade', durationMs: 140, easing: 'ease-in' }.

Animation type accepts none, fade, scale, orfade-scale. Easing accepts linear, ease-in,ease-out, or ease-in-out. A none phase is instantaneous. Scale emphasis never transforms the highlight box, so its border stays aligned throughout the phase.

Action zoom

highlight(), hover(), and click() accept zoom: trueor a zoom options object. Zoom is off by default. The camera enters before the action, stays close until it completes, and exits afterward. holdMs adds dwell time after the action. Action zooms share the camera queue with zoom() and work in renders and live streams.

TypeScript
await suitecut.highlight(details, { zoom: true })
await suitecut.click(publishButton, { zoom: { scale: 1.25, paddingPx: 32 } })

The recorded cursor changes between arrow, pointer, and text shapes based on the element under it. Disabled controls use the arrow. Zoom crops the captured image, so capture at a higher resolution when you need more detail. Upscaling a low-resolution source cannot restore missing detail.

zoom(locator, options?): Promise<void>

Scrolls the locator into view and records a continuously evaluated camera move. SuiteCut centers edge targets, pads beyond the captured browser frame when needed, and limits the requested scale when necessary to retain available target padding. Concurrent zoom calls run in call order.

  • scale: 1 through 1.25; default 1.15.
  • geometry: element by default, or content to center rendered text and controls inside a block.
  • paddingPx: minimum retained target padding; default 24.
  • holdMs: time at the closest scale; default 900.
  • enter: default { type: 'scale', durationMs: 260, easing: 'ease-out' }.
  • exit: default { type: 'scale', durationMs: 220, easing: 'ease-in-out' }.

Zoom accepts the same animation values as highlight. none disables a phase;fade, scale, and fade-scale use eased camera interpolation.

hover(locator, options?): Promise<void>

Scrolls the locator into view, moves the recorded cursor to its center, performs a real Playwright hover, waits for resulting application animations by default, and settles.

  • moveDurationMs: 450.
  • settleMs: 120.
  • waitForAnimations: true.
  • animationTimeoutMs: 2000.

click(locator, options?): Promise<void>

Uses the same options as hover(), performs a real click, and records a 280 ms ripple. The ripple and optional application-animation wait run together. Click-driven navigation is supported.

type(locator, text, options?): Promise<void>

Scrolls the field into view and enters text one character at a time through Playwright's keyboard events. The source recording shows each character as it appears. The text must contain at least one character.

  • delayMs: time between characters; default 70.
  • settleMs: wait after the last character; default 250.
  • clearExisting: replace the current value before typing; default true. Set it to false to type at the current caret.

scrollTo(locator, options?): Promise<void>

Calls native scrollIntoView() and waits for the target to remain stable for three animation frames.

  • behavior: smooth by default, or auto.
  • block: center by default; also start, end, or nearest.
  • inline: nearest by default; also start, center, or end.
  • timeoutMs: 2000; settleMs: 120.

scrollTop(options?): Promise<void>

Scrolls the selected window to the origin. It uses behavior, timeoutMs, andsettleMs with the defaults above. block and inline are accepted for the shared options type but do not affect a window-to-origin scroll.

Capture options

Set suitecutCapture through test.use() or Playwright Test configuration. Plain Playwright scripts pass the same object as capture to record() ordefineSuiteCut().

  • viewport: default 1600x900; maximum 7680x4320.
  • deviceScaleFactor: physical pixels per CSS pixel from 1 through 4. A 1920x1080 viewport at 2 renders 3840x2160 pixels while keeping CSS layout and responsive breakpoints at 1920x1080.
  • size: encoded source size, defaulting to the viewport. With deviceScaleFactor, SuiteCut downsamples the physical render to this size with Lanczos filtering. Without a device scale, the existing larger proportional size behavior remains available for compatibility. Both size dimensions must be even and no larger than 7680x4320.
  • framesPerSecond: 30 or 60; default 30.
  • quality: capture JPEG quality 1 through 100; default 100.
  • narrationTailMs: non-negative post-narration pause; default 350.

Set capture.stream to publish H.264 video with silent AAC audio over RTMP or RTMPS. This selects streaming-only mode, with no source recordings or checkpoint clips. See live streaming for options, including the boolean audio flag, reconnect behavior, cancellation, and supported effects. Streaming JPEG quality defaults to 90.

Reporter options

  • outputFile: default .suitecut/latest-run.json. TheSUITECUT_MANIFEST_PATH environment variable takes precedence.
  • pathKind: absolute by default, or manifest-relative.
  • includeStepCategories: optional allowlist of hook, fixture,pw:api, expect, test.step, test.attach, orunknown. Retained descendants reconnect to the nearest retained ancestor.

Recording options

Import record or defineSuiteCut from suitecut/playwright. Each call owns one browser, context, main page, and recording. It writes one manifest attempt with no test steps.

TypeScript
record(
  name: string,
  callback: SuiteCutRecordingCallback,
  options?: SuiteCutRecordOptions,
): Promise<SuiteCutRecordResult>

defineSuiteCut<Extensions extends object = object>(
  defaults?: SuiteCutDefinitionOptions<Extensions>,
): SuiteCutRecorder<Extensions>
  • browserName: chromium, firefox, or webkit.
  • launch: Playwright launch options.
  • context: Playwright browser context options. Do not set recordVideo; SuiteCut owns the page screencasts.
  • capture: the capture options listed above.
  • output.directory: artifact directory. The default is a unique directory under.suitecut/recordings.
  • output.manifestPath: default .suitecut/latest-run.json.
  • output.pathKind: absolute by default, or manifest-relative.
  • signal: an AbortSignal that cancels setup, capture, narration, and owned browser resources. Setup and recording callbacks receive the same signal.

SuiteCutRecordResult

A successful recording returns attemptId, testId, the decodedmanifest, its manifestPath, and the outputDirectory.defineSuiteCut() can add typed setup values and reverse-order cleanup callbacks.

Renderer

renderSuiteCut(request) selects one recorded attempt, invokes FFmpeg, writes the requested video, and writes <output>.suitecut.json. It returns the same render report.

TypeScript
const report = await renderSuiteCut({
  manifestPath: '.suitecut/latest-run.json',
  outputPath: '.suitecut/videos/tour.mp4',
  selection: { testId, retry: 0 },
  config: {
    narrationEnabled: true,
    resultHoldMs: 500,
    failureMode: 'strict',
    output: {
      container: 'mp4',
      width: 3840,
      height: 2160,
      framesPerSecond: 60,
      quality: 'high',
    },
  },
})

The request accepts manifestPath, outputPath, optional test and retry selection, optional render configuration, and an optional signal. Aborting stops the owned FFmpeg process and rejects with the signal reason. The report includes timing edits, diagnostics, selected IDs, output status, and the FFmpeg command result.

Audio plugin helpers

  • defineSuiteCutAudioPlugin(plugin) preserves the plugin type without wrapping the runtime object.
  • audioPluginReference(reference) validates a provider ID, module name, and optional JSON settings before the worker loads them.
  • encodePcm16Wav(samples, sampleRate) converts a mono Float32Array into a 16-bit PCM WAV byte array.
  • SuiteCutAudioPlugin.synthesize(request) receives text, voice, speed, output path, and plugin settings. It resolves after writing the WAV file.
  • Optional SuiteCutAudioPlugin.dispose() releases plugin-owned models, workers, files, or subprocesses when the narration worker closes normally.

The audio plugin guide shows package installation and provider setup.

Streaming API

SuiteCutStreamOptions configures capture.stream. Supply an RTMP or RTMPSurl, optional size, and bitrateKbps from 100 to 50,000. Audio defaults to false; true requires the standalone Chromium recorder.adaptiveBitrate defaults to enabled. reconnect accepts falseor SuiteCutReconnectOptions with initialDelayMs, maxDelayMs, and maxAttempts. onDiagnostic receives LiveStreamDiagnostic. See the streaming guide for limits and recovery behavior.

Word timing artifacts

decodeWordTimingArtifact(value) validates a saved word-timing artifact.SuiteCutWordTimingArtifact uses schemaVersion: 1 andtype: 'word-timings'. Entries include character offsets and relativestartMs/endMs; sourceEventId links to the narration event. Use timings only when spoken words map to the displayed text.

Command-line flags

suitecut install installs pinned FFmpeg and FFprobe into the OS cache.suitecut doctor verifies media tools and required codecs and protocols offline. Explicit media-tool environment paths take priority over the managed cache and system PATH.

suitecut test [--manifest path] -- [Playwright options] forwards Playwright arguments and installs the SuiteCut reporter. suitecut render requires--manifest <path> and --output <path>.

  • --test-id <id>: select a test; default is the first.
  • --retry <number>: select an attempt; default is the latest.
  • --container <mp4|webm|mov|mkv>: default comes from the output extension.
  • --format: deprecated alias for --container.
  • --video-codec: default libvpx-vp9 for WebM, libx264 otherwise.
  • --audio-codec: default libopus for WebM, aac otherwise.
  • --pixel-format: default yuv422p10le for ProRes, yuv420p otherwise.
  • --color-range <auto|full|limited>: default auto.
  • --width and --height: default 1920x1080; supply both, even, maximum 7680x4320.
  • --fps <30|60>: default 30.
  • --quality <standard|high|master>: default standard.
  • --result-hold-ms: non-negative final-frame hold; default 0.
  • --background-color: default #0B1020; three- or six-digit hex or the basic names black, white, red, green, blue, and yellow.
  • --failure-mode <strict|best-effort>: default strict. Best-effort can omit unavailable narration and records an OPTIONAL_TRACK_OMITTED warning; required video failures remain fatal.
  • --ffmpeg-path: explicit FFmpeg executable path.
  • --no-narration: omit narration audio; recorded captions remain.

A recorded test

TypeScript
import { expect, test } from 'suitecut/test'

test('opens the account', async ({ page, suitecut }) => {
  await page.goto('/account')
  await suitecut.narrate('The account page is open.')

  const billing = page.getByRole('link', { name: 'Billing' })
  await suitecut.highlight(billing, { label: 'Open billing' })
  await suitecut.click(billing)
  await suitecut.hold(500)
  await suitecut.checkpoint('Billing page')
})
Report an issue ↗MIT licensed · CEF + Playwright