Whether the browser is launched and connected
Current viewport dimensions
Capture ONE frame on demand and push it through the active screencast's frame callback.
CDP's Page.screencastFrame only fires on a viewport REPAINT, so the very first navigation (and
navigations to pages that paint identically) can leave the live view blank until some later change.
This grabs the current viewport via a screenshot (encoded to match the screencast format) and emits
it as the next sequence-numbered frame, so callers can force an immediate refresh right after starting
the stream and after a navigation settles.
No-op (resolves) when no screencast is running or no page is open — safe to call opportunistically.
Capture a screenshot of the current viewport.
Base64-encoded PNG string (no data URI prefix)
Close the browser and release all resources. Safe to call multiple times — subsequent calls are no-ops.
Execute a single browser action.
The action is a discriminated union — implementations should
switch on action.Type for exhaustive handling.
ProtectedExtractExtract the domain (hostname) from a URL string. Shared utility available to all adapter implementations.
Capture the page's accessibility tree, mapped recursively into our own
AccessibilityNode type. Returns null when no page is open or
Playwright produces no snapshot (e.g. a blank page).
Retrieve and flush all buffered diagnostic events captured since the last call. Returns an empty array if the adapter doesn't capture diagnostics or if there are no new events.
Read the page's current text selection via page.evaluate(window.getSelection()). Returns '' when
no page is open or nothing is selected (guarded, never throws on a closed adapter) — the copy-out
source for the remote-browser human clipboard path.
Return the current page title. Returns '' when no page is open (guarded, never throws on a closed adapter).
Read the visible text of the current page (the rendered text of
). Used by consumers that need page text for agent perception without a screenshot. Returns '' when no page is open (guarded, never throws on a closed adapter).Launch the browser with the given configuration. Must be called before any other method.
Navigate to the given URL and wait for the page to load. Respects the NavigationTimeoutMs from BrowserConfig.
Introspect a single element via page.locator(selector). Reports
existence (count() > 0), visibility, inner text, and bounding box.
Never throws on a missing element — returns Exists:false instead.
Bounded by the configured action timeout where Playwright supports it.
Reset per-session state for the given origin while preserving auth tokens.
Intended for shared-context adapters: between tests in the same browser context, cached state from the previous test (IndexedDB metadata cache, sessionStorage, service workers, non-auth localStorage entries) can deadlock the next test's app initialization. This method clears that state so the next test starts clean — but preserves Auth0 / OAuth tokens in localStorage so the user stays logged in.
Default implementation is a no-op. Adapters that own a context across test boundaries (e.g., SharedContextBrowserAdapter) override this.
Best-effort: never throws — all errors are swallowed.
Add cookies to the browser context. Maps our CookieEntry to Playwright's cookie format.
Set extra HTTP headers for all requests to a specific domain.
Uses Playwright's page.route() to intercept requests and inject headers for matching domains. The interceptor is set up once on the first call; subsequent calls just update the headers map.
Headers are additive — calling this multiple times for the same domain merges headers (later calls override conflicting keys).
Set localStorage entries for a specific domain.
If the page is already on the target domain, entries are set directly via page.evaluate(). If not (e.g. on about:blank before first navigation), entries are deferred via page.addInitScript() so they run before page scripts on the next navigation — this avoids the origin mismatch that would occur from navigating to https://{domain} when the actual target is a different origin (e.g. http://localhost:4201).
Start capturing the audio playing inside the browser tab and invoke
onChunk for each encoded slice.
Mechanism (in-page, headless-safe, no OS audio device, no extension): a
capture agent is injected via Playwright page.exposeBinding('__mjAudioChunk', …)
page.addInitScript(…). The agent watches the DOM for <video> / <audio>
elements (a MutationObserver plus an initial scan), taps the FIRST one that
is actively playing with element.captureStream(), and feeds its audio tracks
to an in-page MediaRecorder({ mimeType: 'audio/webm;codecs=opus' }) with a
~250ms timeslice. Each dataavailable blob is base64-encoded and sent back
through the binding, which lands here and is mapped to an AudioCaptureChunk.
The agent restarts the recorder when the active element swaps / plays / pauses.Calling start while a capture is already running is a no-op (the existing capture keeps feeding chunks).
Limitation: only audio routed through a media ELEMENT is captured (covers
YouTube and most video/audio sites). Pure Web-Audio-API sound and DRM/EME
media (where captureStream() is blocked) are NOT captured — a server-side
virtual audio sink is the documented future path for full-fidelity / DRM audio.
Callback invoked with each captured audio chunk.
Start a CDP-backed live screencast of the viewport.
Obtains a CDP session via context.newCDPSession(page), subscribes to
Page.screencastFrame, and for each frame decodes the payload into a
ScreencastFrame (with a monotonic SequenceNumber), invokes
onFrame, then acks the frame via Page.screencastFrameAck so Chromium
continues streaming. Calling start while a screencast is already running
is a no-op (the existing session keeps streaming).
Callback invoked with each decoded frame.
Optionalopts: ScreencastOptionsOptional sizing / quality / format / frame-skip controls.
Stop the active audio capture (if any): ask the in-page agent to tear down
its MediaRecorder + observers, and clear local capture state. Safe to call
when no capture is running. Best-effort — teardown errors are swallowed.
Stop the active screencast (if any): tell Chromium to stop streaming, detach the CDP session, and clear screencast state. Safe to call when no screencast is running. Best-effort — teardown errors are swallowed.
Wait until the page reaches the given load state. No-op when no page is open (guarded, never throws on a closed adapter).
Current URL of the browser page