import { Protocol } from "devtools-protocol";
import type { CDPSessionLike } from "./cdp.js";
import { CdpConnection } from "./cdp.js";
import { Frame } from "./frame.js";
import { FrameLocator } from "./frameLocator.js";
import { LoadState, SnapshotResult, PageSnapshotOptions } from "../types/public/page.js";
import { Response } from "./response.js";
import { ConsoleListener } from "./consoleMessage.js";
import type { StagehandAPIClient } from "../api.js";
import { LocalBrowserLaunchOptions } from "../types/public/index.js";
import type { ScreenshotOptions } from "../types/public/screenshotTypes.js";
import { InitScriptSource } from "../types/private/index.js";
export declare class Page {
    private readonly conn;
    private readonly mainSession;
    private readonly _targetId;
    /** Every CDP child session this page owns (top-level + adopted OOPIF sessions). */
    private readonly sessions;
    /** Unified truth for frame topology + ownership. */
    private readonly registry;
    /** A convenience wrapper bound to the current main frame id (top-level session). */
    private mainFrameWrapper;
    /** Compact ordinal per frameId (used by snapshot encoding). */
    private frameOrdinals;
    private nextOrdinal;
    /** cache Frames per frameId so everyone uses the same one */
    private readonly frameCache;
    private readonly browserIsRemote;
    /** Stable id for Frames created by this Page (use top-level TargetId). */
    private readonly pageId;
    /** Cached current URL for synchronous page.url() */
    private _currentUrl;
    private navigationCommandSeq;
    private latestNavigationCommandId;
    private readonly networkManager;
    /** Optional API client for routing page operations to the API */
    private readonly apiClient;
    private readonly consoleListeners;
    private readonly consoleHandlers;
    /** Document-start scripts installed across every session this page owns. */
    private readonly initScripts;
    private constructor();
    private installInitScriptOnSession;
    private applyInitScriptsToSession;
    registerInitScript(source: string): Promise<void>;
    seedInitScript(source: string): void;
    private cursorEnabled;
    private ensureCursorScript;
    enableCursorOverlay(): Promise<void>;
    private updateCursor;
    addInitScript<Arg>(script: InitScriptSource<Arg>, arg?: Arg): Promise<void>;
    /**
     * Factory: create Page and seed registry with the shallow tree from Page.getFrameTree.
     * Assumes Page domain is already enabled on the session passed in.
     */
    static create(conn: CdpConnection, session: CDPSessionLike, targetId: string, apiClient?: StagehandAPIClient | null, localBrowserLaunchOptions?: LocalBrowserLaunchOptions | null, browserIsRemote?: boolean): Promise<Page>;
    /**
     * Parent/child session emitted a `frameAttached`.
     * Topology update + ownership stamped to **emitting session**.
     */
    onFrameAttached(frameId: string, parentId: string | null, session: CDPSessionLike): void;
    /**
     * Parent/child session emitted a `frameDetached`.
     */
    onFrameDetached(frameId: string, reason?: "remove" | "swap" | string): void;
    /**
     * Parent/child session emitted a `frameNavigated`.
     * Topology + ownership update. Handles root swaps.
     */
    onFrameNavigated(frame: Protocol.Page.Frame, session: CDPSessionLike): void;
    onNavigatedWithinDocument(frameId: string, url: string, session: CDPSessionLike): void;
    /**
     * An OOPIF child session whose **main** frame id equals the parent iframe’s frameId
     * has been attached; adopt the session into this Page and seed ownership for its subtree.
     */
    adoptOopifSession(childSession: CDPSessionLike, childMainFrameId: string): void;
    /** Detach an adopted child session and prune its subtree */
    detachOopifSession(sessionId: string): void;
    /** Return the owning CDP session for a frameId (falls back to main session) */
    getSessionForFrame(frameId: string): CDPSessionLike;
    /** Always returns a Frame bound to the owning session */
    frameForId(frameId: string): Frame;
    /** Expose a session by id (used by snapshot to resolve session id -> session) */
    getSessionById(id: string): CDPSessionLike | undefined;
    registerSessionForNetwork(session: CDPSessionLike): void;
    unregisterSessionForNetwork(sessionId: string | undefined): void;
    on(event: "console", listener: ConsoleListener): Page;
    once(event: "console", listener: ConsoleListener): Page;
    off(event: "console", listener: ConsoleListener): Page;
    targetId(): string;
    /**
     * Send a CDP command through the main session.
     * Allows external consumers to execute arbitrary Chrome DevTools Protocol commands.
     *
     * @param method - The CDP method name (e.g., "Page.enable", "Runtime.evaluate")
     * @param params - Optional parameters for the CDP command
     * @returns Promise resolving to the typed CDP response
     *
     * @example
     * // Enable the Runtime domain
     * await page.sendCDP("Runtime.enable");
     *
     * @example
     * // Evaluate JavaScript with typed response
     * const result = await page.sendCDP<Protocol.Runtime.EvaluateResponse>(
     *   "Runtime.evaluate",
     *   { expression: "1 + 1" }
     * );
     */
    sendCDP<T = unknown>(method: string, params?: object): Promise<T>;
    /** Seed the cached URL before navigation events converge. */
    seedCurrentUrl(url: string | undefined | null): void;
    mainFrameId(): string;
    mainFrame(): Frame;
    /**
     * Close this top-level page (tab). Best-effort via Target.closeTarget.
     */
    close(): Promise<void>;
    getFullFrameTree(): Protocol.Page.FrameTree;
    asProtocolFrameTree(rootMainFrameId: string): Protocol.Page.FrameTree;
    private ensureOrdinal;
    /** Public getter for snapshot code / handlers. */
    getOrdinal(frameId: string): number;
    listAllFrameIds(): string[];
    private ensureConsoleTaps;
    private installConsoleTap;
    private sessionKey;
    private resolveSessionByKey;
    private teardownConsoleTap;
    private removeAllConsoleTaps;
    private emitConsole;
    /**
     * Navigate the page; optionally wait for a lifecycle state.
     * Waits on the **current** main frame and follows root swaps during navigation.
     */
    goto(url: string, options?: {
        waitUntil?: LoadState;
        timeoutMs?: number;
    }): Promise<Response | null>;
    /**
     * Reload the page; optionally wait for a lifecycle state.
     */
    reload(options?: {
        waitUntil?: LoadState;
        timeoutMs?: number;
        ignoreCache?: boolean;
    }): Promise<Response | null>;
    /**
     * Navigate back in history if possible; optionally wait for a lifecycle state.
     */
    goBack(options?: {
        waitUntil?: LoadState;
        timeoutMs?: number;
    }): Promise<Response | null>;
    /**
     * Navigate forward in history if possible; optionally wait for a lifecycle state.
     */
    goForward(options?: {
        waitUntil?: LoadState;
        timeoutMs?: number;
    }): Promise<Response | null>;
    /**
     * Return the current page URL (synchronous, cached from navigation events).
     */
    url(): string;
    private beginNavigationCommand;
    isCurrentNavigationCommand(id: number): boolean;
    /**
     * Return the current page title.
     * Prefers reading from the active document via Runtime.evaluate to reflect dynamic changes.
     * Falls back to navigation history title if evaluation is unavailable.
     */
    title(): Promise<string>;
    /**
     * Capture a screenshot with Playwright-style options.
     *
     * @param options Optional screenshot configuration.
     * @param options.animations Control CSS/Web animations during capture. Use
     * "disabled" to fast-forward finite animations and pause infinite ones.
     * @param options.caret Either hide the text caret (default) or leave it
     * visible via "initial".
     * @param options.clip Restrict capture to a specific rectangle (in CSS
     * pixels). Cannot be combined with `fullPage`.
     * @param options.fullPage Capture the full scrollable page instead of the
     * current viewport.
     * @param options.mask Array of locators that should be covered with an
     * overlay while the screenshot is taken.
     * @param options.maskColor CSS color used for the mask overlay (default
     * `#FF00FF`).
     * @param options.omitBackground Make the default page background transparent
     * (PNG only).
     * @param options.path File path to write the screenshot to. The file extension
     * determines the image type when `type` is not explicitly provided.
     * @param options.quality JPEG quality (0–100). Only applies when
     * `type === "jpeg"`.
     * @param options.scale Render scale: use "css" for one pixel per CSS pixel,
     * otherwise the default "device" leverages the current device pixel ratio.
     * @param options.style Additional CSS text injected into every frame before
     * capture (removed afterwards).
     * @param options.timeout Maximum capture duration in milliseconds before a
     * timeout error is thrown.
     * @param options.type Image format (`"png"` by default).
     */
    screenshot(options?: ScreenshotOptions): Promise<Buffer>;
    /**
     * Create a locator bound to the current main frame.
     */
    locator(selector: string): ReturnType<Frame["locator"]>;
    /**
     * Deep locator that supports cross-iframe traversal.
     * - Recognizes '>>' hop notation to enter iframe contexts.
     * - Supports deep XPath that includes iframe steps (e.g., '/html/body/iframe[2]//div').
     * Returns a Locator scoped to the appropriate frame.
     */
    deepLocator(selector: string): import("./deepLocator.js").DeepLocatorDelegate;
    /**
     * Frame locator similar to Playwright: targets iframe elements and scopes
     * subsequent locators to that frame. Supports chaining.
     */
    frameLocator(selector: string): FrameLocator;
    /**
     * List all frames belonging to this page as Frame objects bound to their owning sessions.
     * The list is ordered by a stable ordinal assigned during the page lifetime.
     */
    frames(): Frame[];
    /**
     * Wait until the page reaches a lifecycle state on the current main frame.
     * Mirrors Playwright's API signatures.
     */
    waitForLoadState(state: LoadState, timeoutMs?: number): Promise<void>;
    /**
     * Wait for a specified amount of time.
     *
     * @param ms The number of milliseconds to wait.
     */
    waitForTimeout(ms: number): Promise<void>;
    /**
     * Wait for an element matching the selector to appear in the DOM.
     * Uses MutationObserver for efficiency
     * Pierces shadow DOM by default.
     * Supports iframe hop notation with '>>' (e.g., 'iframe#checkout >> .submit-btn').
     *
     * @param selector CSS selector to wait for (supports '>>' for iframe hops)
     * @param options
     * @param options.state Element state to wait for: 'attached' | 'detached' | 'visible' | 'hidden' (default: 'visible')
     * @param options.timeout Maximum time to wait in milliseconds (default: 30000)
     * @param options.pierceShadow Whether to search inside shadow DOM (default: true)
     * @returns True when the condition is met
     * @throws Error if timeout is reached before the condition is met
     */
    waitForSelector(selector: string, options?: {
        state?: "attached" | "detached" | "visible" | "hidden";
        timeout?: number;
        pierceShadow?: boolean;
    }): Promise<boolean>;
    /**
     * Evaluate a function or expression in the current main frame's main world.
     * - If a string is provided, it is treated as a JS expression.
     * - If a function is provided, it is stringified and invoked with the optional argument.
     * - The return value should be JSON-serializable. Non-serializable objects will
     *   best-effort serialize via JSON.stringify inside the page context.
     */
    evaluate<R = unknown, Arg = unknown>(pageFunctionOrExpression: string | ((arg: Arg) => R | Promise<R>), arg?: Arg): Promise<R>;
    /**
     * Force the page viewport to an exact CSS size and device scale factor.
     * Ensures screenshots match width x height pixels when deviceScaleFactor = 1.
     */
    setViewportSize(width: number, height: number, options?: {
        deviceScaleFactor?: number;
    }): Promise<void>;
    /**
     * Click at absolute page coordinates (CSS pixels).
     * Dispatches mouseMoved → mousePressed → mouseReleased via CDP Input domain
     * on the top-level page target's session. Coordinates are relative to the
     * viewport origin (top-left). Does not scroll.
     */
    click(x: number, y: number, options?: {
        button?: "left" | "right" | "middle";
        clickCount?: number;
        returnXpath?: boolean;
    }): Promise<string>;
    /**
     * Hover at absolute page coordinates (CSS pixels).
     * Dispatches mouseMoved via CDP Input domain on the top-level page target's
     * session.
     */
    hover(x: number, y: number, options?: {
        returnXpath?: boolean;
    }): Promise<string>;
    scroll(x: number, y: number, deltaX: number, deltaY: number, options?: {
        returnXpath?: boolean;
    }): Promise<string>;
    /**
     * Drag from (fromX, fromY) to (toX, toY) using mouse events.
     * Sends mouseMoved → mousePressed → mouseMoved (steps) → mouseReleased.
     */
    dragAndDrop(fromX: number, fromY: number, toX: number, toY: number, options?: {
        button?: "left" | "right" | "middle";
        steps?: number;
        delay?: number;
        returnXpath?: boolean;
    }): Promise<[string, string]>;
    /**
     * Type a string by dispatching keyDown/keyUp events per character.
     * Focus must already be on the desired element. Uses CDP Input.dispatchKeyEvent
     * and never falls back to Input.insertText. Optional delay applies between
     * successive characters.
     */
    type(text: string, options?: {
        delay?: number;
        withMistakes?: boolean;
    }): Promise<void>;
    /**
     * Press a single key or key combination (keyDown then keyUp).
     * For printable characters, uses the text path on keyDown; for named keys, sets key/code/VK.
     * Supports key combinations with modifiers like "Cmd+A", "Ctrl+C", "Shift+Tab", etc.
     */
    keyPress(key: string, options?: {
        delay?: number;
    }): Promise<void>;
    snapshot(options?: PageSnapshotOptions): Promise<SnapshotResult>;
    private _pressedModifiers;
    /** Press a key down without releasing it */
    private keyDown;
    /** Release a pressed key */
    private keyUp;
    /** Normalize key names to match CDP expectations */
    private normalizeModifierKey;
    /**
     * Get the map of named keys with their properties
     */
    private getNamedKeys;
    /**
     * Minimal description for printable keys (letters/digits/space) to provide code and VK.
     * Used when non-Shift modifiers are pressed to avoid sending text while keeping accelerator info.
     */
    private describePrintableKey;
    private isMacOS;
    /**
     * Return Chromium mac editing commands (without trailing ':') for a given code like 'KeyA'
     * Only used on macOS to trigger system editing shortcuts (e.g., selectAll, copy, paste...).
     */
    private macCommandsFor;
    /** Resolve the main-world execution context for the current main frame. */
    private mainWorldExecutionContextId;
    private isMainLoadStateReady;
    /**
     * Wait until the **current** main frame reaches a lifecycle state.
     * - Fast path via `document.readyState`.
     * - Event path listens at the session level and compares incoming `frameId`
     *   to `mainFrameId()` **at event time** to follow root swaps.
     */
    waitForMainLoadState(state: LoadState, timeoutMs?: number): Promise<void>;
}
