/** * Playwright browser driver — the OPTIONAL, lazily-loaded automation backend * (T1742 · epic T11456 · SG-TOOLS). * * The `browser_*` tools' execution backend. Playwright is an OPTIONAL dependency * (publish-surface discipline · D11136): it is NEVER a hard dependency of * `@cleocode/core`. Like `node-pty` (see {@link ./pty.js}), it is deliberately * NOT declared in `core`'s `dependencies` / `optionalDependencies` and is loaded * ONLY via a dynamic `import()` whose specifier is held in a variable — so * neither the bundler nor TS treats the missing package as a hard, * statically-resolved dependency, the published `@cleocode/core` carries no * Playwright weight, and `core` builds + tests pass with Playwright NOT installed. * An environment that wants the browser tools opts in by installing `playwright` * itself (`pnpm add playwright && pnpm exec playwright install chromium`). * * Import-time side-effect-free: NO top-level `playwright` import; the browser is * launched lazily on the first navigation through a {@link BrowserSession}. When * Playwright is absent, {@link isPlaywrightAvailable} resolves `false` and the * browser tools' availability predicate hides them with an install hint — * nothing throws at import. * * @epic T11456 * @task T1742 * @see ./pty.js — the analogous optional-native-dep (node-pty) lazy-load pattern */ import type { AccessibilityNode, BrowserNavigateInput, BrowserPageState } from '@cleocode/contracts/tools/web-tools'; /** * The npm install hint surfaced to the model when a browser tool is unavailable * because Playwright is not installed. Playwright is an OPTIONAL dep — the * browser tools are registered regardless, but report unavailable until this * runs (AC8). */ export declare const PLAYWRIGHT_INSTALL_HINT: string; /** A keyboard handle (`page.keyboard`). */ interface PwKeyboard { press(key: string): Promise; } /** A located element handle (`page.locator(...)`). */ interface PwLocator { click(options?: { timeout?: number; }): Promise; fill(value: string, options?: { timeout?: number; }): Promise; focus(options?: { timeout?: number; }): Promise; } /** The accessibility snapshot surface (`page.accessibility`). */ interface PwAccessibility { snapshot(): Promise; } /** A Playwright `Page`. */ interface PwPage { goto(url: string, options?: { waitUntil?: 'load' | 'domcontentloaded' | 'networkidle'; timeout?: number; }): Promise; url(): string; title(): Promise; locator(selector: string): PwLocator; readonly keyboard: PwKeyboard; readonly accessibility: PwAccessibility; screenshot(options?: { fullPage?: boolean; }): Promise; evaluate(fn: string): Promise; } /** A Playwright `Browser`. */ interface PwBrowser { newPage(): Promise; close(): Promise; } /** The `chromium` browser-type launcher. */ interface PwBrowserType { launch(options?: { headless?: boolean; }): Promise; } /** The minimal shape of the `playwright` module we depend on. */ interface PlaywrightModule { readonly chromium: PwBrowserType; } export declare function isPlaywrightAvailable(): Promise; /** * Reset the cached Playwright-availability probe. * * EXPORTED FOR TESTS ONLY — lets a unit test toggle the mocked availability of * the optional dep between cases without a fresh module graph. * * @internal */ export declare function __resetPlaywrightAvailabilityCache(): void; /** * The injectable factory the {@link BrowserSession} uses to obtain a Playwright * module. Defaults to the real lazy {@link loadPlaywright}; unit tests inject a * fake so NO real browser is ever launched (AC9). */ export type PlaywrightLoader = () => Promise; /** * A single browser session: lazily launches a headless Chromium on the first * navigation, then reuses the same page for subsequent interactions. Holds no * Playwright reference until {@link BrowserSession.navigate} is first called, so * constructing one is free and import-time side-effect-free. * * The browser tools share ONE session per registry run (created by the browser * tool family at registration). All Playwright access funnels through here so * the lazy-load + teardown live in one place. */ export declare class BrowserSession { #private; /** * @param load - Optional Playwright loader (defaults to the real lazy import). * Tests pass a fake that returns a mock module — no real browser launches. */ constructor(load?: PlaywrightLoader); /** * Navigate to a URL (launching the browser on first call). * * @param input - {@link BrowserNavigateInput}. * @returns The page state after navigation. */ navigate(input: BrowserNavigateInput): Promise; /** * Click the element matching `selector`. * * @param selector - CSS / Playwright selector. * @param timeoutMs - Per-action timeout. * @returns The page state after the click. */ click(selector: string, timeoutMs?: number): Promise; /** * Type `text` into the element matching `selector`. * * @param selector - CSS / Playwright selector. * @param text - Text to enter (`fill` replaces the field's content). * @param timeoutMs - Per-action timeout. * @returns The page state after typing. */ type(selector: string, text: string, timeoutMs?: number): Promise; /** * Press a key / chord, optionally focusing `selector` first. * * @param key - Playwright key syntax (e.g. `Enter`, `Control+A`). * @param selector - Optional element to focus before pressing. * @param timeoutMs - Per-action timeout (for the focus step). * @returns The page state after the keypress. */ press(key: string, selector?: string, timeoutMs?: number): Promise; /** * Capture the page's accessibility tree. * * @returns The page state plus the accessibility tree root (or `null`). */ snapshot(): Promise; /** * Scroll the page vertically by `amountPx` in `direction` and report the new * scroll offset. * * @param direction - `up` or `down`. * @param amountPx - Pixels to scroll (defaults to ~one viewport). * @returns The page state plus the post-scroll `scrollY`. */ scroll(direction: 'up' | 'down', amountPx?: number): Promise; /** * Capture a screenshot of the current page as base64-encoded PNG bytes. * * @param fullPage - Capture the full scrollable page when `true`. * @returns The page state plus the base64 PNG and the page state. */ screenshot(fullPage?: boolean): Promise; /** Close the browser and release the page (idempotent). */ close(): Promise; } export {}; //# sourceMappingURL=browser-driver.d.ts.map