browsecraft 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/wait.ts","../src/locator.ts","../src/page.ts","../src/browser.ts","../src/test.ts"],"names":["cpus","BiDiSession","join","mkdir","writeFile"],"mappings":"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","file":"chunk-KIPQFK3Y.cjs","sourcesContent":["// ============================================================================\n// Browsecraft - Configuration\n// Zero config by default. Override only what you need.\n// ============================================================================\n\nimport { cpus } from 'node:os';\nimport type { BrowserName } from 'browsecraft-bidi';\n\n/** Full configuration with all options */\nexport interface BrowsecraftConfig {\n\t/** Which browser to use (default: 'chrome') */\n\tbrowser: BrowserName;\n\t/** Run in headless mode (default: true) */\n\theadless: boolean;\n\t/** Global timeout for actions in ms (default: 30000) */\n\ttimeout: number;\n\t/** How many times to retry a failed test (default: 0) */\n\tretries: number;\n\t/** Take screenshots: 'always', 'on-failure', or 'never' (default: 'on-failure') */\n\tscreenshot: 'always' | 'on-failure' | 'never';\n\t/** Base URL prepended to all page.goto() calls (default: '') */\n\tbaseURL: string;\n\t/** Custom browser executable path */\n\texecutablePath?: string;\n\t/** Viewport size (default: 1280x720) */\n\tviewport: { width: number; height: number };\n\t/** Start the browser window maximized (headed mode only, default: false) */\n\tmaximized: boolean;\n\t/** Number of parallel workers (default: CPU cores / 2) */\n\tworkers: number;\n\t/** Test file pattern (default: '**\\/*.test.{ts,js,mts,mjs}') */\n\ttestMatch: string;\n\t/** Output directory for reports/screenshots (default: '.browsecraft') */\n\toutputDir: string;\n\t/** AI mode: 'auto' detects GitHub Models availability, 'off' disables (default: 'auto') */\n\tai: 'auto' | 'off' | AIConfig;\n\t/** Enable verbose debug logging (default: false) */\n\tdebug: boolean;\n}\n\nexport interface AIConfig {\n\tprovider: 'github-models';\n\t/** Model to use (default: 'openai/gpt-4o-mini') */\n\tmodel?: string;\n\t/** Explicit GitHub token (overrides env vars) */\n\ttoken?: string;\n}\n\n/** Users provide a partial config -- everything has smart defaults */\nexport type UserConfig = Partial<BrowsecraftConfig>;\n\n/** Smart defaults -- works out of the box with zero config */\nconst DEFAULTS: BrowsecraftConfig = {\n\tbrowser: 'chrome',\n\theadless: true,\n\ttimeout: 30_000,\n\tretries: 0,\n\tscreenshot: 'on-failure',\n\tbaseURL: '',\n\tviewport: { width: 1280, height: 720 },\n\tmaximized: false,\n\tworkers: Math.max(1, Math.floor((typeof cpus === 'function' ? cpus().length : 4) / 2)),\n\ttestMatch: '**/*.test.{ts,js,mts,mjs}',\n\toutputDir: '.browsecraft',\n\tai: 'auto',\n\tdebug: false,\n};\n\n/**\n * Define your Browsecraft config with full type safety and IntelliSense.\n * This function is optional -- it's just a type helper for your IDE.\n *\n * ```ts\n * // browsecraft.config.ts\n * import { defineConfig } from 'browsecraft';\n *\n * export default defineConfig({\n * browser: 'firefox',\n * timeout: 60_000,\n * });\n * ```\n */\nexport function defineConfig(config: UserConfig): UserConfig {\n\treturn config;\n}\n\n/**\n * Resolve user config by merging with defaults.\n * This is used internally -- users never call this.\n */\nexport function resolveConfig(userConfig?: UserConfig): BrowsecraftConfig {\n\tif (!userConfig) return { ...DEFAULTS };\n\n\treturn {\n\t\t...DEFAULTS,\n\t\t...userConfig,\n\t\tviewport: userConfig.viewport ?? DEFAULTS.viewport,\n\t};\n}\n","// ============================================================================\n// Browsecraft - Auto Wait Engine\n// Automatically waits for elements to be ready before interacting.\n// Users never write sleep() or waitFor() -- it just works.\n// ============================================================================\n\nimport type { BiDiSession } from 'browsecraft-bidi';\n\nexport interface WaitOptions {\n\t/** Max time to wait in ms */\n\ttimeout: number;\n\t/** How often to poll in ms */\n\tinterval?: number;\n}\n\n/**\n * Poll a condition until it returns a truthy value or times out.\n * This is the foundation of auto-waiting -- every action uses this.\n *\n * @param description - What we're waiting for (for error messages)\n * @param fn - The function to poll. Return truthy when done.\n * @param options - Timeout and interval settings\n */\nexport async function waitFor<T>(\n\tdescription: string,\n\tfn: () => Promise<T | null | false>,\n\toptions: WaitOptions,\n): Promise<T> {\n\tconst { timeout, interval = 100 } = options;\n\tconst startTime = Date.now();\n\n\tlet lastError: Error | null = null;\n\n\twhile (Date.now() - startTime < timeout) {\n\t\ttry {\n\t\t\tconst result = await fn();\n\t\t\tif (result !== null && result !== false) {\n\t\t\t\treturn result;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tlastError = err instanceof Error ? err : new Error(String(err));\n\t\t}\n\t\tawait sleep(interval);\n\t}\n\n\tconst elapsed = Date.now() - startTime;\n\tconst errorMsg = lastError ? `\\nLast error: ${lastError.message}` : '';\n\tthrow new Error(\n\t\t`Timed out after ${elapsed}ms waiting for: ${description}${errorMsg}`,\n\t);\n}\n\n/**\n * Wait for a page to reach a specific load state.\n */\nexport async function waitForLoadState(\n\tsession: BiDiSession,\n\tcontextId: string,\n\tstate: 'load' | 'domcontentloaded' = 'load',\n\ttimeout: number = 30_000,\n): Promise<void> {\n\t// Check if already loaded by evaluating document.readyState\n\tconst result = await session.script.evaluate({\n\t\texpression: 'document.readyState',\n\t\ttarget: { context: contextId },\n\t\tawaitPromise: false,\n\t});\n\n\tif (result.type === 'success' && result.result) {\n\t\tconst readyState = (result.result as { value?: string }).value;\n\t\tif (state === 'domcontentloaded' && (readyState === 'interactive' || readyState === 'complete')) {\n\t\t\treturn;\n\t\t}\n\t\tif (state === 'load' && readyState === 'complete') {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Subscribe and wait for the event\n\tconst eventName = state === 'load'\n\t\t? 'browsingContext.load'\n\t\t: 'browsingContext.domContentLoaded';\n\n\tawait session.subscribe([eventName], [contextId]);\n\n\ttry {\n\t\tawait session.waitForEvent(\n\t\t\teventName,\n\t\t\t(event) => (event.params as { context?: string }).context === contextId,\n\t\t\ttimeout,\n\t\t);\n\t} finally {\n\t\tawait session.unsubscribe([eventName], [contextId]).catch(() => {});\n\t}\n}\n\n/**\n * Simple sleep utility.\n */\nexport function sleep(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n","// ============================================================================\n// Browsecraft - Smart Locator\n// The magic behind page.click('Submit') -- finds elements the way humans do.\n//\n// Resolution chain:\n// 1. Accessibility: role + name (button named \"Submit\")\n// 2. Inner text: visible text content\n// 3. Label: form labels (for inputs)\n// 4. CSS selector: fallback for power users\n// ============================================================================\n\nimport type { BiDiSession, Locator, NodeRemoteValue } from 'browsecraft-bidi';\nimport { waitFor, type WaitOptions } from './wait.js';\n\n/** What the user passes to click(), fill(), get() */\nexport type ElementTarget = string | LocatorOptions;\n\n/** Advanced locator options (for when you need precision) */\nexport interface LocatorOptions {\n\t/** Find by ARIA role (e.g., 'button', 'link', 'textbox') */\n\trole?: string;\n\t/** Find by accessible name or visible text */\n\tname?: string;\n\t/** Find by <label> text (for form inputs) */\n\tlabel?: string;\n\t/** Find by visible text content */\n\ttext?: string;\n\t/** Find by data-testid attribute */\n\ttestId?: string;\n\t/** Find by CSS selector */\n\tselector?: string;\n\t/** Require exact text match (default: false = partial match) */\n\texact?: boolean;\n\t/** Which match to use if multiple found (0-based, default: 0) */\n\tindex?: number;\n}\n\n/** Result of locating an element */\nexport interface LocatedElement {\n\t/** The node reference for BiDi commands */\n\tnode: NodeRemoteValue;\n\t/** How we found it (for debugging/logging) */\n\tstrategy: string;\n}\n\n/**\n * Find an element using the smart resolution chain.\n * This auto-waits until the element is found or timeout.\n *\n * @param session - BiDi session\n * @param contextId - Browsing context (tab/frame)\n * @param target - What to find: string or LocatorOptions\n * @param options - Wait options\n */\nexport async function locateElement(\n\tsession: BiDiSession,\n\tcontextId: string,\n\ttarget: ElementTarget,\n\toptions: WaitOptions,\n): Promise<LocatedElement> {\n\tconst opts = normalizeTarget(target);\n\n\treturn waitFor(\n\t\tdescribeTarget(target),\n\t\tasync () => {\n\t\t\t// Try each strategy in order\n\t\t\tconst strategies = buildStrategies(opts);\n\n\t\t\tfor (const { locator, strategy, isLabelLookup } of strategies) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await session.browsingContext.locateNodes({\n\t\t\t\t\t\tcontext: contextId,\n\t\t\t\t\t\tlocator,\n\t\t\t\t\t\tmaxNodeCount: (opts.index ?? 0) + 10, // fetch extra for label resolution\n\t\t\t\t\t});\n\n\t\t\t\t\tif (result.nodes.length > 0) {\n\t\t\t\t\t\t// If this is a label lookup, we need to find <label> elements\n\t\t\t\t\t\t// and resolve their `for` attribute to the associated input\n\t\t\t\t\t\tif (isLabelLookup) {\n\t\t\t\t\t\t\tconst resolved = await resolveLabelsToInputs(session, contextId, result.nodes);\n\t\t\t\t\t\t\tif (resolved) {\n\t\t\t\t\t\t\t\treturn { node: resolved, strategy };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst nodeIndex = opts.index ?? 0;\n\t\t\t\t\t\tconst node = result.nodes[nodeIndex];\n\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\treturn { node, strategy };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// This strategy didn't work -- try the next one\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null; // Not found yet -- waitFor will retry\n\t\t},\n\t\toptions,\n\t);\n}\n\n/**\n * Find ALL matching elements (no auto-wait, returns immediately).\n */\nexport async function locateAllElements(\n\tsession: BiDiSession,\n\tcontextId: string,\n\ttarget: ElementTarget,\n): Promise<LocatedElement[]> {\n\tconst opts = normalizeTarget(target);\n\tconst strategies = buildStrategies(opts);\n\n\tfor (const { locator, strategy } of strategies) {\n\t\ttry {\n\t\t\tconst result = await session.browsingContext.locateNodes({\n\t\t\t\tcontext: contextId,\n\t\t\t\tlocator,\n\t\t\t\tmaxNodeCount: 1000,\n\t\t\t});\n\n\t\t\tif (result.nodes.length > 0) {\n\t\t\t\treturn result.nodes.map((node) => ({ node, strategy }));\n\t\t\t}\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\treturn [];\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Convert a string target into LocatorOptions */\nfunction normalizeTarget(target: ElementTarget): LocatorOptions {\n\tif (typeof target === 'string') {\n\t\treturn { name: target };\n\t}\n\treturn target;\n}\n\n/** Human-readable description of what we're looking for */\nfunction describeTarget(target: ElementTarget): string {\n\tif (typeof target === 'string') {\n\t\treturn `element \"${target}\"`;\n\t}\n\n\tconst parts: string[] = [];\n\tif (target.role) parts.push(`role=\"${target.role}\"`);\n\tif (target.name) parts.push(`name=\"${target.name}\"`);\n\tif (target.text) parts.push(`text=\"${target.text}\"`);\n\tif (target.label) parts.push(`label=\"${target.label}\"`);\n\tif (target.testId) parts.push(`testId=\"${target.testId}\"`);\n\tif (target.selector) parts.push(`selector=\"${target.selector}\"`);\n\n\treturn `element [${parts.join(', ')}]`;\n}\n\n/** Build an ordered list of BiDi locator strategies to try */\nfunction buildStrategies(opts: LocatorOptions): Array<{ locator: Locator; strategy: string; isLabelLookup?: boolean }> {\n\tconst strategies: Array<{ locator: Locator; strategy: string; isLabelLookup?: boolean }> = [];\n\tconst matchType = opts.exact ? 'full' : 'partial';\n\n\t// If user specified a specific strategy, only use that one\n\tif (opts.selector) {\n\t\tstrategies.push({\n\t\t\tlocator: { type: 'css', value: opts.selector },\n\t\t\tstrategy: 'css',\n\t\t});\n\t\treturn strategies;\n\t}\n\n\tif (opts.testId) {\n\t\tstrategies.push({\n\t\t\tlocator: { type: 'css', value: `[data-testid=\"${opts.testId}\"]` },\n\t\t\tstrategy: 'testId',\n\t\t});\n\t\treturn strategies;\n\t}\n\n\t// Smart resolution chain for string targets\n\tconst name = opts.name ?? opts.text;\n\n\tif (name) {\n\t\t// Strategy 1: Accessibility -- find by role + name\n\t\t// This is the most robust way to find elements\n\t\tif (opts.role) {\n\t\t\tstrategies.push({\n\t\t\t\tlocator: {\n\t\t\t\t\ttype: 'accessibility',\n\t\t\t\t\tvalue: { role: opts.role, name },\n\t\t\t\t},\n\t\t\t\tstrategy: `accessibility[role=\"${opts.role}\", name=\"${name}\"]`,\n\t\t\t});\n\t\t} else {\n\t\t\t// Try common interactive roles with this name\n\t\t\tfor (const role of ['button', 'link', 'menuitem', 'tab']) {\n\t\t\t\tstrategies.push({\n\t\t\t\t\tlocator: {\n\t\t\t\t\t\ttype: 'accessibility',\n\t\t\t\t\t\tvalue: { role, name },\n\t\t\t\t\t},\n\t\t\t\t\tstrategy: `accessibility[role=\"${role}\", name=\"${name}\"]`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Strategy 2: Inner text -- find by visible text content\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'innerText',\n\t\t\t\tvalue: name,\n\t\t\t\tmatchType,\n\t\t\t\tignoreCase: !opts.exact,\n\t\t\t},\n\t\t\tstrategy: `innerText(\"${name}\")`,\n\t\t});\n\n\t\t// Strategy 3: CSS fallback -- maybe it's a selector\n\t\tif (name.match(/^[#.\\[a-z]/i)) {\n\t\t\tstrategies.push({\n\t\t\t\tlocator: { type: 'css', value: name },\n\t\t\t\tstrategy: `css(\"${name}\")`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Label strategy (for form inputs)\n\tif (opts.label) {\n\t\t// Find by aria-label\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'accessibility',\n\t\t\t\tvalue: { name: opts.label },\n\t\t\t},\n\t\t\tstrategy: `label(\"${opts.label}\")`,\n\t\t});\n\n\t\t// Find by associated <label> via CSS (aria-label, placeholder, or label[for])\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'css',\n\t\t\t\tvalue: `[aria-label=\"${opts.label}\"], [placeholder=\"${opts.label}\"]`,\n\t\t\t},\n\t\t\tstrategy: `label-css(\"${opts.label}\")`,\n\t\t});\n\n\t\t// Find input associated via <label for=\"...\"> by text\n\t\t// This uses a JS-based approach: find <label> by innerText, get its `for` attr,\n\t\t// then return the input with that id. We do this via innerText locator on the label\n\t\t// and resolve it in the locateElement flow below.\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'innerText',\n\t\t\t\tvalue: opts.label,\n\t\t\t\tmatchType: matchType,\n\t\t\t\tignoreCase: !opts.exact,\n\t\t\t},\n\t\t\tstrategy: `label-text(\"${opts.label}\")`,\n\t\t\tisLabelLookup: true,\n\t\t});\n\t}\n\n\t// Role-only strategy\n\tif (opts.role && !name) {\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'accessibility',\n\t\t\t\tvalue: { role: opts.role },\n\t\t\t},\n\t\t\tstrategy: `role(\"${opts.role}\")`,\n\t\t});\n\t}\n\n\treturn strategies;\n}\n\n/**\n * Given a set of nodes found by innerText (which may include <label> elements),\n * find ones that are <label> elements and resolve their `for` attribute\n * to the associated input element.\n */\nasync function resolveLabelsToInputs(\n\tsession: BiDiSession,\n\tcontextId: string,\n\tnodes: NodeRemoteValue[],\n): Promise<NodeRemoteValue | null> {\n\tfor (const node of nodes) {\n\t\tif (!node.sharedId) continue;\n\n\t\ttry {\n\t\t\t// Check if this node is a <label> and if so, resolve its associated input\n\t\t\tconst result = await session.script.callFunction({\n\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\t// If the element is a <label> with a 'for' attribute, find the associated input\n\t\t\t\t\tif (el.tagName === 'LABEL') {\n\t\t\t\t\t\tconst forId = el.getAttribute('for');\n\t\t\t\t\t\tif (forId) {\n\t\t\t\t\t\t\tconst input = document.getElementById(forId);\n\t\t\t\t\t\t\tif (input) return input;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Also check for implicit label association (input nested inside label)\n\t\t\t\t\t\tconst nested = el.querySelector('input, textarea, select');\n\t\t\t\t\t\tif (nested) return nested;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t}`,\n\t\t\t\ttarget: { context: contextId },\n\t\t\t\targuments: [{ sharedId: node.sharedId, handle: node.handle }],\n\t\t\t\tawaitPromise: false,\n\t\t\t\tresultOwnership: 'root',\n\t\t\t});\n\n\t\t\tif (\n\t\t\t\tresult.type === 'success' &&\n\t\t\t\tresult.result?.type === 'node' &&\n\t\t\t\t(result.result as NodeRemoteValue).sharedId\n\t\t\t) {\n\t\t\t\treturn result.result as NodeRemoteValue;\n\t\t\t}\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\treturn null;\n}\n","// ============================================================================\n// Browsecraft - Page API\n// The main class users interact with. Designed to be dead simple.\n//\n// page.goto('https://example.com')\n// page.click('Submit')\n// page.fill('Email', 'user@test.com')\n// ============================================================================\n\nimport type {\n\tBiDiSession,\n\tNodeRemoteValue,\n\tSharedReference,\n\tScriptEvaluateResult,\n\tStorageCookie,\n\tNetworkSetCookieHeader,\n} from 'browsecraft-bidi';\nimport { locateElement, locateAllElements, type ElementTarget, type LocatedElement } from './locator.js';\nimport { waitFor, waitForLoadState, type WaitOptions } from './wait.js';\nimport type { BrowsecraftConfig } from './config.js';\n\n/** Options for page.goto() */\nexport interface GotoOptions {\n\t/** Wait until page reaches this state (default: 'complete') */\n\twaitUntil?: 'none' | 'interactive' | 'complete';\n\t/** Timeout in ms (default: config.timeout) */\n\ttimeout?: number;\n}\n\n/** Options for page.fill() */\nexport interface FillOptions {\n\t/** Timeout in ms (default: config.timeout) */\n\ttimeout?: number;\n}\n\n/** Options for page.click() */\nexport interface ClickOptions {\n\t/** Timeout in ms (default: config.timeout) */\n\ttimeout?: number;\n\t/** Mouse button (default: 0 = left) */\n\tbutton?: number;\n\t/** Number of clicks (default: 1, use 2 for double-click) */\n\tclickCount?: number;\n}\n\n/** Mock response definition */\nexport interface MockResponse {\n\t/** HTTP status code */\n\tstatus?: number;\n\t/** Response headers */\n\theaders?: Record<string, string>;\n\t/** Response body (string or object that will be JSON-stringified) */\n\tbody?: string | Record<string, unknown>;\n\t/** Content type (default: 'application/json' for objects, 'text/plain' for strings) */\n\tcontentType?: string;\n}\n\n/**\n * Page represents a single browser tab/page.\n * This is the main API surface users interact with.\n *\n * Every action auto-waits for the element to be ready.\n * No sleep(). No waitFor(). It just works.\n */\nexport class Page {\n\t/** @internal */\n\treadonly session: BiDiSession;\n\t/** @internal */\n\treadonly contextId: string;\n\t/** @internal */\n\tprivate config: BrowsecraftConfig;\n\t/** @internal */\n\tprivate interceptIds: string[] = [];\n\t/** @internal -- event listener unsubscribe functions for cleanup */\n\tprivate eventCleanups: Array<() => void> = [];\n\n\tconstructor(session: BiDiSession, contextId: string, config: BrowsecraftConfig) {\n\t\tthis.session = session;\n\t\tthis.contextId = contextId;\n\t\tthis.config = config;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Navigation\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Navigate to a URL.\n\t *\n\t * ```ts\n\t * await page.goto('https://example.com');\n\t * await page.goto('/login'); // uses baseURL from config\n\t * ```\n\t */\n\tasync goto(url: string, options?: GotoOptions): Promise<void> {\n\t\tconst fullUrl = this.resolveURL(url);\n\t\tconst waitUntil = options?.waitUntil ?? 'complete';\n\n\t\tawait this.session.browsingContext.navigate({\n\t\t\tcontext: this.contextId,\n\t\t\turl: fullUrl,\n\t\t\twait: waitUntil,\n\t\t});\n\t}\n\n\t/**\n\t * Reload the current page.\n\t */\n\tasync reload(options?: GotoOptions): Promise<void> {\n\t\tawait this.session.browsingContext.reload({\n\t\t\tcontext: this.contextId,\n\t\t\twait: options?.waitUntil ?? 'complete',\n\t\t});\n\t}\n\n\t/**\n\t * Go back in browser history.\n\t */\n\tasync goBack(): Promise<void> {\n\t\tawait this.session.browsingContext.traverseHistory({\n\t\t\tcontext: this.contextId,\n\t\t\tdelta: -1,\n\t\t});\n\t}\n\n\t/**\n\t * Go forward in browser history.\n\t */\n\tasync goForward(): Promise<void> {\n\t\tawait this.session.browsingContext.traverseHistory({\n\t\t\tcontext: this.contextId,\n\t\t\tdelta: 1,\n\t\t});\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Element interaction - the \"stupidly simple\" API\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Click an element. Finds it by text, role, or selector -- auto-waits.\n\t *\n\t * ```ts\n\t * await page.click('Submit'); // by text\n\t * await page.click({ role: 'button', name: 'Submit' }); // precise\n\t * await page.click({ selector: '#my-button' }); // CSS\n\t * ```\n\t */\n\tasync click(target: ElementTarget, options?: ClickOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\n\t\tawait this.scrollIntoViewAndClick(located, options);\n\t}\n\n\t/**\n\t * Fill a text input. First arg finds the input, second is the value.\n\t *\n\t * ```ts\n\t * await page.fill('Email', 'user@test.com'); // by label\n\t * await page.fill('Search', 'browsecraft'); // by placeholder\n\t * await page.fill({ selector: '#email' }, 'test'); // by CSS\n\t * ```\n\t */\n\tasync fill(target: ElementTarget, value: string, options?: FillOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\n\t\t// For string targets, treat as label/placeholder for inputs\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\t// Clear existing value and type new one\n\t\tconst ref = this.getSharedRef(located.node);\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(element, value) {\n\t\t\t\telement.focus();\n\t\t\t\t// Use native setter to bypass React/Vue/Angular internal value trackers.\n\t\t\t\t// Frameworks like React override the value property on input elements,\n\t\t\t\t// so setting element.value directly doesn't trigger their state updates.\n\t\t\t\tconst proto = element.tagName === 'TEXTAREA'\n\t\t\t\t\t? HTMLTextAreaElement.prototype\n\t\t\t\t\t: HTMLInputElement.prototype;\n\t\t\t\tconst nativeSetter = Object.getOwnPropertyDescriptor(proto, 'value')?.set;\n\t\t\t\tif (nativeSetter) {\n\t\t\t\t\tnativeSetter.call(element, '');\n\t\t\t\t\tnativeSetter.call(element, value);\n\t\t\t\t} else {\n\t\t\t\t\telement.value = '';\n\t\t\t\t\telement.value = value;\n\t\t\t\t}\n\t\t\t\telement.dispatchEvent(new Event('input', { bubbles: true }));\n\t\t\t\telement.dispatchEvent(new Event('change', { bubbles: true }));\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref, { type: 'string', value }],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/**\n\t * Type text character by character (triggers keyboard events).\n\t * Use this instead of fill() when you need realistic keyboard input.\n\t *\n\t * ```ts\n\t * await page.type('Search', 'browsecraft');\n\t * ```\n\t */\n\tasync type(target: ElementTarget, text: string, options?: FillOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\t// Focus the element first\n\t\tconst ref = this.getSharedRef(located.node);\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.focus(); }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\t// Type each character\n\t\tconst actions = [];\n\t\tfor (const char of text) {\n\t\t\tactions.push({ type: 'keyDown' as const, value: char });\n\t\t\tactions.push({ type: 'keyUp' as const, value: char });\n\t\t}\n\n\t\tawait this.session.input.performActions({\n\t\t\tcontext: this.contextId,\n\t\t\tactions: [{ type: 'key', id: 'keyboard', actions }],\n\t\t});\n\t}\n\n\t/**\n\t * Select an option from a <select> dropdown.\n\t *\n\t * ```ts\n\t * await page.select('Country', 'United States');\n\t * ```\n\t */\n\tasync select(target: ElementTarget, value: string, options?: FillOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(element, value) {\n\t\t\t\tconst options = Array.from(element.options);\n\t\t\t\tconst option = options.find(o => o.value === value || o.text === value || o.textContent.trim() === value);\n\t\t\t\tif (option) {\n\t\t\t\t\telement.value = option.value;\n\t\t\t\t\telement.dispatchEvent(new Event('change', { bubbles: true }));\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error('Option \"' + value + '\" not found in <select>');\n\t\t\t\t}\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref, { type: 'string', value }],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/**\n\t * Check a checkbox or radio button.\n\t *\n\t * ```ts\n\t * await page.check('I agree to the terms');\n\t * ```\n\t */\n\tasync check(target: ElementTarget, options?: ClickOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\t// Only click if not already checked\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.checked; }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tconst isChecked = result.type === 'success' &&\n\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t(result.result as { value: boolean }).value === true;\n\n\t\tif (!isChecked) {\n\t\t\tawait this.scrollIntoViewAndClick(located, options);\n\t\t}\n\t}\n\n\t/**\n\t * Uncheck a checkbox.\n\t */\n\tasync uncheck(target: ElementTarget, options?: ClickOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.checked; }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tconst isChecked = result.type === 'success' &&\n\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t(result.result as { value: boolean }).value === true;\n\n\t\tif (isChecked) {\n\t\t\tawait this.scrollIntoViewAndClick(located, options);\n\t\t}\n\t}\n\n\t/**\n\t * Hover over an element.\n\t *\n\t * ```ts\n\t * await page.hover('Profile Menu');\n\t * ```\n\t */\n\tasync hover(target: ElementTarget, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\t// Scroll into view first so coordinates are accurate\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.scrollIntoView({ block: \"center\", behavior: \"instant\" }); }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\t// Dispatch mouseover/mouseenter events via JS for reliability,\n\t\t// then also move the real pointer for CSS :hover effects\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\tel.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true }));\n\t\t\t\tel.dispatchEvent(new MouseEvent('mouseover', { bubbles: true }));\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\t// Also move the real pointer (needed for CSS :hover pseudo-class)\n\t\tconst pos = await this.getElementCenter(ref);\n\t\tawait this.session.input.performActions({\n\t\t\tcontext: this.contextId,\n\t\t\tactions: [{\n\t\t\t\ttype: 'pointer',\n\t\t\t\tid: 'mouse',\n\t\t\t\tparameters: { pointerType: 'mouse' },\n\t\t\t\tactions: [\n\t\t\t\t\t{ type: 'pointerMove', x: pos.x, y: pos.y, origin: 'viewport' },\n\t\t\t\t],\n\t\t\t}],\n\t\t});\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Finding elements (for assertions and inspection)\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Get a single element. Returns an ElementHandle for assertions.\n\t *\n\t * ```ts\n\t * const heading = page.get('Welcome back!');\n\t * await expect(heading).toBeVisible();\n\t * ```\n\t */\n\tget(target: ElementTarget): ElementHandle {\n\t\treturn new ElementHandle(this, target);\n\t}\n\n\t/**\n\t * Get a locator by visible text. Alias for get() with text matching.\n\t *\n\t * ```ts\n\t * const btn = page.getByText('Submit');\n\t * ```\n\t */\n\tgetByText(text: string, options?: { exact?: boolean }): ElementHandle {\n\t\treturn new ElementHandle(this, { text, exact: options?.exact });\n\t}\n\n\t/**\n\t * Get a locator by ARIA role and optional name.\n\t *\n\t * ```ts\n\t * const btn = page.getByRole('button', { name: 'Submit' });\n\t * ```\n\t */\n\tgetByRole(role: string, options?: { name?: string; exact?: boolean }): ElementHandle {\n\t\treturn new ElementHandle(this, { role, name: options?.name, exact: options?.exact });\n\t}\n\n\t/**\n\t * Get a locator by label text (for form inputs).\n\t *\n\t * ```ts\n\t * const email = page.getByLabel('Email Address');\n\t * ```\n\t */\n\tgetByLabel(label: string, options?: { exact?: boolean }): ElementHandle {\n\t\treturn new ElementHandle(this, { label, exact: options?.exact });\n\t}\n\n\t/**\n\t * Get a locator by data-testid attribute.\n\t *\n\t * ```ts\n\t * const card = page.getByTestId('user-card');\n\t * ```\n\t */\n\tgetByTestId(testId: string): ElementHandle {\n\t\treturn new ElementHandle(this, { testId });\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Page state\n\t// -----------------------------------------------------------------------\n\n\t/** Get the current page URL */\n\tasync url(): Promise<string> {\n\t\tconst result = await this.session.script.evaluate({\n\t\t\texpression: 'window.location.href',\n\t\t\ttarget: { context: this.contextId },\n\t\t\tawaitPromise: false,\n\t\t});\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t/** Get the page title */\n\tasync title(): Promise<string> {\n\t\tconst result = await this.session.script.evaluate({\n\t\t\texpression: 'document.title',\n\t\t\ttarget: { context: this.contextId },\n\t\t\tawaitPromise: false,\n\t\t});\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t/** Get the full page HTML content */\n\tasync content(): Promise<string> {\n\t\tconst result = await this.session.script.evaluate({\n\t\t\texpression: 'document.documentElement.outerHTML',\n\t\t\ttarget: { context: this.contextId },\n\t\t\tawaitPromise: false,\n\t\t});\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Cookies\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Get cookies for the current page's browsing context.\n\t *\n\t * ```ts\n\t * const cookies = await page.cookies();\n\t * const session = cookies.find(c => c.name === 'session_id');\n\t * ```\n\t */\n\tasync cookies(filter?: { name?: string; domain?: string; path?: string }): Promise<StorageCookie[]> {\n\t\tconst result = await this.session.storage.getCookies({\n\t\t\tfilter: filter ? {\n\t\t\t\tname: filter.name,\n\t\t\t\tdomain: filter.domain,\n\t\t\t\tpath: filter.path,\n\t\t\t} : undefined,\n\t\t\tpartition: { type: 'context', context: this.contextId },\n\t\t});\n\t\treturn result.cookies;\n\t}\n\n\t/**\n\t * Set one or more cookies.\n\t *\n\t * ```ts\n\t * await page.setCookies([\n\t * { name: 'token', value: 'abc123', domain: 'example.com' },\n\t * { name: 'theme', value: 'dark', domain: 'example.com' },\n\t * ]);\n\t * ```\n\t */\n\tasync setCookies(cookies: Array<{ name: string; value: string; domain?: string; path?: string; httpOnly?: boolean; secure?: boolean; sameSite?: 'strict' | 'lax' | 'none'; expiry?: number }>): Promise<void> {\n\t\tfor (const cookie of cookies) {\n\t\t\tconst cookieHeader: NetworkSetCookieHeader = {\n\t\t\t\tname: cookie.name,\n\t\t\t\tvalue: { type: 'string', value: cookie.value },\n\t\t\t\tdomain: cookie.domain,\n\t\t\t\tpath: cookie.path,\n\t\t\t\thttpOnly: cookie.httpOnly,\n\t\t\t\tsecure: cookie.secure,\n\t\t\t\tsameSite: cookie.sameSite,\n\t\t\t\texpiry: cookie.expiry,\n\t\t\t};\n\t\t\tawait this.session.storage.setCookie({\n\t\t\t\tcookie: cookieHeader,\n\t\t\t\tpartition: { type: 'context', context: this.contextId },\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Clear all cookies (or those matching a filter).\n\t *\n\t * ```ts\n\t * await page.clearCookies(); // all cookies\n\t * await page.clearCookies({ name: 'session_id' }); // specific cookie\n\t * await page.clearCookies({ domain: 'example.com' }); // by domain\n\t * ```\n\t */\n\tasync clearCookies(filter?: { name?: string; domain?: string; path?: string }): Promise<void> {\n\t\tawait this.session.storage.deleteCookies({\n\t\t\tfilter: filter ? {\n\t\t\t\tname: filter.name,\n\t\t\t\tdomain: filter.domain,\n\t\t\t\tpath: filter.path,\n\t\t\t} : undefined,\n\t\t\tpartition: { type: 'context', context: this.contextId },\n\t\t});\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// JavaScript execution\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Execute JavaScript in the page and return the result.\n\t *\n\t * ```ts\n\t * const title = await page.evaluate('document.title');\n\t * const count = await page.evaluate(() => document.querySelectorAll('li').length);\n\t * ```\n\t */\n\tasync evaluate<T = unknown>(expression: string | (() => T)): Promise<T> {\n\t\tconst expr = typeof expression === 'function'\n\t\t\t? `(${expression.toString()})()`\n\t\t\t: expression;\n\n\t\tconst result = await this.session.script.evaluate({\n\t\t\texpression: expr,\n\t\t\ttarget: { context: this.contextId },\n\t\t\tawaitPromise: true,\n\t\t});\n\n\t\tif (result.type === 'exception') {\n\t\t\tconst errorText = result.exceptionDetails?.text ?? 'Script evaluation failed';\n\t\t\tthrow new Error(errorText);\n\t\t}\n\n\t\treturn this.deserializeRemoteValue(result.result) as T;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Screenshots\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Take a screenshot of the page.\n\t *\n\t * ```ts\n\t * const buffer = await page.screenshot();\n\t * ```\n\t */\n\tasync screenshot(): Promise<Buffer> {\n\t\tconst result = await this.session.browsingContext.captureScreenshot({\n\t\t\tcontext: this.contextId,\n\t\t});\n\n\t\treturn Buffer.from(result.data, 'base64');\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Network mocking\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Mock a network request with a fake response.\n\t *\n\t * ```ts\n\t * await page.mock('POST /api/login', { status: 200, body: { token: 'abc' } });\n\t * await page.mock('GET /api/users', { status: 500 });\n\t * await page.mock('https://api.example.com/data', { body: { items: [] } });\n\t * ```\n\t */\n\tasync mock(pattern: string, response: MockResponse): Promise<void> {\n\t\t// Parse \"METHOD /path\" or just \"/path\" or full URL\n\t\tconst { method, urlPattern } = parseMockPattern(pattern);\n\n\t\t// Subscribe to network events if not already\n\t\tawait this.session.subscribe(\n\t\t\t['network.beforeRequestSent'],\n\t\t\t[this.contextId],\n\t\t);\n\n\t\t// Add intercept\n\t\tconst result = await this.session.network.addIntercept({\n\t\t\tphases: ['beforeRequestSent'],\n\t\t\turlPatterns: [urlPattern],\n\t\t\tcontexts: [this.contextId],\n\t\t});\n\t\tthis.interceptIds.push(result.intercept);\n\n\t\t// Handle intercepted requests\n\t\tconst unsubscribe = this.session.on('network.beforeRequestSent', async (event) => {\n\t\t\tconst params = event.params as {\n\t\t\t\tcontext: string;\n\t\t\t\trequest: { request: string; method: string };\n\t\t\t\tisBlocked: boolean;\n\t\t\t\tintercepts?: string[];\n\t\t\t};\n\n\t\t\tif (!params.isBlocked || params.context !== this.contextId) return;\n\t\t\tif (!params.intercepts?.includes(result.intercept)) return;\n\n\t\t\t// Check method if specified\n\t\t\tif (method && params.request.method.toUpperCase() !== method.toUpperCase()) {\n\t\t\t\tawait this.session.network.continueRequest({ request: params.request.request });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Provide the mock response\n\t\t\tconst headers = buildMockHeaders(response);\n\t\t\tconst body = buildMockBody(response);\n\n\t\t\tawait this.session.network.provideResponse({\n\t\t\t\trequest: params.request.request,\n\t\t\t\tstatusCode: response.status ?? 200,\n\t\t\t\theaders,\n\t\t\t\tbody: body ? { type: 'string', value: body } : undefined,\n\t\t\t});\n\t\t});\n\t\tthis.eventCleanups.push(unsubscribe);\n\t}\n\n\t/**\n\t * Remove all network mocks and clean up event listeners.\n\t */\n\tasync clearMocks(): Promise<void> {\n\t\tfor (const id of this.interceptIds) {\n\t\t\tawait this.session.network.removeIntercept({ intercept: id }).catch(() => {});\n\t\t}\n\t\tthis.interceptIds = [];\n\n\t\tfor (const cleanup of this.eventCleanups) {\n\t\t\tcleanup();\n\t\t}\n\t\tthis.eventCleanups = [];\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Dialog handling\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Accept the next dialog (alert, confirm, prompt).\n\t *\n\t * ```ts\n\t * await page.acceptDialog();\n\t * page.click('Delete'); // triggers confirm dialog\n\t * ```\n\t */\n\tasync acceptDialog(text?: string): Promise<void> {\n\t\tawait this.session.subscribe(['browsingContext.userPromptOpened'], [this.contextId]);\n\n\t\tawait this.session.waitForEvent(\n\t\t\t'browsingContext.userPromptOpened',\n\t\t\t(e) => (e.params as { context: string }).context === this.contextId,\n\t\t);\n\n\t\tawait this.session.browsingContext.handleUserPrompt({\n\t\t\tcontext: this.contextId,\n\t\t\taccept: true,\n\t\t\tuserText: text,\n\t\t});\n\t}\n\n\t/**\n\t * Dismiss the next dialog.\n\t */\n\tasync dismissDialog(): Promise<void> {\n\t\tawait this.session.subscribe(['browsingContext.userPromptOpened'], [this.contextId]);\n\n\t\tawait this.session.waitForEvent(\n\t\t\t'browsingContext.userPromptOpened',\n\t\t\t(e) => (e.params as { context: string }).context === this.contextId,\n\t\t);\n\n\t\tawait this.session.browsingContext.handleUserPrompt({\n\t\t\tcontext: this.contextId,\n\t\t\taccept: false,\n\t\t});\n\t}\n\n\t/**\n\t * Double-click an element.\n\t *\n\t * ```ts\n\t * await page.dblclick('Edit');\n\t * ```\n\t */\n\tasync dblclick(target: ElementTarget, options?: ClickOptions): Promise<void> {\n\t\tawait this.click(target, { ...options, clickCount: 2 });\n\t}\n\n\t/**\n\t * Tap an element (touch gesture).\n\t *\n\t * ```ts\n\t * await page.tap('Menu');\n\t * ```\n\t */\n\tasync tap(target: ElementTarget, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\t// Scroll into view\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.scrollIntoView({ block: \"center\", behavior: \"instant\" }); }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tconst pos = await this.getElementCenter(ref);\n\n\t\tawait this.session.input.performActions({\n\t\t\tcontext: this.contextId,\n\t\t\tactions: [{\n\t\t\t\ttype: 'pointer',\n\t\t\t\tid: 'touch',\n\t\t\t\tparameters: { pointerType: 'touch' },\n\t\t\t\tactions: [\n\t\t\t\t\t{ type: 'pointerMove', x: pos.x, y: pos.y, origin: 'viewport' },\n\t\t\t\t\t{ type: 'pointerDown', button: 0 },\n\t\t\t\t\t{ type: 'pointerUp', button: 0 },\n\t\t\t\t] as any,\n\t\t\t}],\n\t\t});\n\t}\n\n\t/**\n\t * Focus an element.\n\t *\n\t * ```ts\n\t * await page.focus('Email');\n\t * ```\n\t */\n\tasync focus(target: ElementTarget, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.focus(); }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/**\n\t * Remove focus from an element.\n\t *\n\t * ```ts\n\t * await page.blur('Email');\n\t * ```\n\t */\n\tasync blur(target: ElementTarget, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.blur(); }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/**\n\t * Get the visible inner text of an element (like element.innerText).\n\t *\n\t * ```ts\n\t * const text = await page.innerText('h1');\n\t * ```\n\t */\n\tasync innerText(target: ElementTarget, options?: { timeout?: number }): Promise<string> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.innerText || \"\"; }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t/**\n\t * Get the innerHTML of an element.\n\t *\n\t * ```ts\n\t * const html = await page.innerHTML('.container');\n\t * ```\n\t */\n\tasync innerHTML(target: ElementTarget, options?: { timeout?: number }): Promise<string> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.innerHTML || \"\"; }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t/**\n\t * Get the current value of an input/textarea/select.\n\t *\n\t * ```ts\n\t * const email = await page.inputValue('Email');\n\t * ```\n\t */\n\tasync inputValue(target: ElementTarget, options?: { timeout?: number }): Promise<string> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.value ?? \"\"; }',\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\treturn this.extractStringResult(result) ?? '';\n\t}\n\n\t/**\n\t * Select multiple options from a <select multiple> dropdown.\n\t *\n\t * ```ts\n\t * await page.selectOption('Colors', ['red', 'blue']);\n\t * ```\n\t */\n\tasync selectOption(target: ElementTarget, values: string | string[], options?: FillOptions): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget = typeof target === 'string'\n\t\t\t? { label: target, name: target }\n\t\t\t: target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\t\tconst valuesArray = Array.isArray(values) ? values : [values];\n\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(element, values) {\n\t\t\t\tconst opts = Array.from(element.options);\n\t\t\t\tfor (const opt of opts) {\n\t\t\t\t\topt.selected = values.some(v => opt.value === v || opt.text === v || opt.textContent.trim() === v);\n\t\t\t\t}\n\t\t\t\telement.dispatchEvent(new Event('change', { bubbles: true }));\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref, { type: 'array', value: valuesArray.map(v => ({ type: 'string' as const, value: v })) }],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/**\n\t * Drag an element to another element or position.\n\t *\n\t * ```ts\n\t * await page.dragTo('Draggable', 'Drop Zone');\n\t * ```\n\t */\n\tasync dragTo(source: ElementTarget, dest: ElementTarget, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\n\t\tconst sourceLoc = await locateElement(this.session, this.contextId, source, { timeout });\n\t\tconst sourceRef = this.getSharedRef(sourceLoc.node);\n\t\tconst sourcePos = await this.getElementCenter(sourceRef);\n\n\t\tconst destLoc = await locateElement(this.session, this.contextId, dest, { timeout });\n\t\tconst destRef = this.getSharedRef(destLoc.node);\n\t\tconst destPos = await this.getElementCenter(destRef);\n\n\t\tawait this.session.input.performActions({\n\t\t\tcontext: this.contextId,\n\t\t\tactions: [{\n\t\t\t\ttype: 'pointer',\n\t\t\t\tid: 'mouse',\n\t\t\t\tparameters: { pointerType: 'mouse' },\n\t\t\t\tactions: [\n\t\t\t\t\t{ type: 'pointerMove', x: sourcePos.x, y: sourcePos.y, origin: 'viewport' },\n\t\t\t\t\t{ type: 'pointerDown', button: 0 },\n\t\t\t\t\t{ type: 'pointerMove', x: destPos.x, y: destPos.y, origin: 'viewport', duration: 300 },\n\t\t\t\t\t{ type: 'pointerUp', button: 0 },\n\t\t\t\t] as any,\n\t\t\t}],\n\t\t});\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Waiting (explicit -- but usually you don't need these)\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Wait for an element matching the target to appear in the DOM.\n\t *\n\t * ```ts\n\t * await page.waitForSelector('.loaded');\n\t * await page.waitForSelector({ role: 'dialog' });\n\t * ```\n\t */\n\tasync waitForSelector(target: ElementTarget, options?: { timeout?: number; state?: 'attached' | 'visible' | 'hidden' }): Promise<ElementHandle> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst state = options?.state ?? 'visible';\n\n\t\tif (state === 'hidden') {\n\t\t\t// Wait for the element to disappear\n\t\t\tawait waitFor(\n\t\t\t\t`element to be hidden`,\n\t\t\t\tasync () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst elements = await locateAllElements(this.session, this.contextId, target);\n\t\t\t\t\t\tif (elements.length === 0) return true;\n\n\t\t\t\t\t\t// Check visibility\n\t\t\t\t\t\tconst ref = this.getSharedRef(elements[0]!.node);\n\t\t\t\t\t\tconst result = await this.session.script.callFunction({\n\t\t\t\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\t\t\t\tconst style = window.getComputedStyle(el);\n\t\t\t\t\t\t\t\treturn style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0';\n\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\ttarget: { context: this.contextId },\n\t\t\t\t\t\t\targuments: [ref],\n\t\t\t\t\t\t\tawaitPromise: false,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst isHidden = result.type === 'success' &&\n\t\t\t\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t\t\t\t\treturn isHidden ? true : null;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn true; // Element gone = hidden\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ timeout },\n\t\t\t);\n\t\t\treturn new ElementHandle(this, target);\n\t\t}\n\n\t\t// Wait for element to appear\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\n\t\tif (state === 'visible') {\n\t\t\t// Also verify it's visible\n\t\t\tconst ref = this.getSharedRef(located.node);\n\t\t\tawait waitFor(\n\t\t\t\t`element to be visible`,\n\t\t\t\tasync () => {\n\t\t\t\t\tconst result = await this.session.script.callFunction({\n\t\t\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\t\t\tconst style = window.getComputedStyle(el);\n\t\t\t\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\t\t\t\treturn style.display !== 'none' && style.visibility !== 'hidden' &&\n\t\t\t\t\t\t\t\tstyle.opacity !== '0' && rect.width > 0 && rect.height > 0;\n\t\t\t\t\t\t}`,\n\t\t\t\t\t\ttarget: { context: this.contextId },\n\t\t\t\t\t\targuments: [ref],\n\t\t\t\t\t\tawaitPromise: false,\n\t\t\t\t\t});\n\t\t\t\t\tconst isVisible = result.type === 'success' &&\n\t\t\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t\t\t\treturn isVisible ? true : null;\n\t\t\t\t},\n\t\t\t\t{ timeout },\n\t\t\t);\n\t\t}\n\n\t\treturn new ElementHandle(this, target);\n\t}\n\n\t/**\n\t * Wait for a JavaScript function to return a truthy value.\n\t *\n\t * ```ts\n\t * await page.waitForFunction('document.querySelectorAll(\"li\").length > 5');\n\t * await page.waitForFunction(() => window.appReady === true);\n\t * ```\n\t */\n\tasync waitForFunction<T = unknown>(\n\t\texpression: string | (() => T),\n\t\toptions?: { timeout?: number },\n\t): Promise<T> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst expr = typeof expression === 'function'\n\t\t\t? `(${expression.toString()})()`\n\t\t\t: expression;\n\n\t\treturn waitFor(\n\t\t\t'function to return truthy',\n\t\t\tasync () => {\n\t\t\t\tconst result = await this.session.script.evaluate({\n\t\t\t\t\texpression: expr,\n\t\t\t\t\ttarget: { context: this.contextId },\n\t\t\t\t\tawaitPromise: true,\n\t\t\t\t});\n\n\t\t\t\tif (result.type === 'exception') return null;\n\n\t\t\t\tconst value = this.deserializeRemoteValue(result.result);\n\t\t\t\treturn value ? (value as T) : null;\n\t\t\t},\n\t\t\t{ timeout },\n\t\t);\n\t}\n\n\t/**\n\t * Wait for a specific URL. Usually you use expect(page).toHaveURL() instead.\n\t */\n\tasync waitForURL(url: string | RegExp, options?: { timeout?: number }): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\n\t\tawait waitFor(\n\t\t\t`URL to match ${url}`,\n\t\t\tasync () => {\n\t\t\t\tconst currentUrl = await this.url();\n\t\t\t\tif (typeof url === 'string') {\n\t\t\t\t\treturn currentUrl.includes(url) ? true : null;\n\t\t\t\t}\n\t\t\t\treturn url.test(currentUrl) ? true : null;\n\t\t\t},\n\t\t\t{ timeout },\n\t\t);\n\t}\n\n\t/**\n\t * Wait for the page to finish loading.\n\t */\n\tasync waitForLoadState(state?: 'load' | 'domcontentloaded'): Promise<void> {\n\t\tawait waitForLoadState(this.session, this.contextId, state, this.config.timeout);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Lifecycle\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Close this page/tab.\n\t */\n\tasync close(): Promise<void> {\n\t\t// Clean up all mocks and event listeners\n\t\tawait this.clearMocks();\n\n\t\tawait this.session.browsingContext.close({ context: this.contextId });\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Keyboard shortcuts\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Press a keyboard key.\n\t *\n\t * ```ts\n\t * await page.press('Enter');\n\t * await page.press('Control+a');\n\t * ```\n\t */\n\tasync press(key: string): Promise<void> {\n\t\tconst keys = key.split('+');\n\t\tconst actions: Array<{ type: 'keyDown'; value: string } | { type: 'keyUp'; value: string }> = [];\n\n\t\t// Press modifiers down\n\t\tfor (const k of keys) {\n\t\t\tactions.push({ type: 'keyDown', value: mapKey(k) });\n\t\t}\n\t\t// Release in reverse order\n\t\tfor (const k of keys.reverse()) {\n\t\t\tactions.push({ type: 'keyUp', value: mapKey(k) });\n\t\t}\n\n\t\tawait this.session.input.performActions({\n\t\t\tcontext: this.contextId,\n\t\t\tactions: [{ type: 'key', id: 'keyboard', actions }],\n\t\t});\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Private helpers\n\t// -----------------------------------------------------------------------\n\n\t/** Resolve a relative URL against the baseURL */\n\tprivate resolveURL(url: string): string {\n\t\tif (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('about:') || url.startsWith('data:')) {\n\t\t\treturn url;\n\t\t}\n\t\tconst base = this.config.baseURL.replace(/\\/$/, '');\n\t\tconst path = url.startsWith('/') ? url : `/${url}`;\n\t\treturn base ? `${base}${path}` : url;\n\t}\n\n\t/** Get a shared reference from a located node */\n\tprivate getSharedRef(node: NodeRemoteValue): SharedReference {\n\t\tif (node.sharedId) {\n\t\t\treturn { sharedId: node.sharedId, handle: node.handle };\n\t\t}\n\t\tthrow new Error('Element has no shared reference. This is a bug in Browsecraft.');\n\t}\n\n\t/** Get the center coordinates of an element */\n\tprivate async getElementCenter(ref: SharedReference): Promise<{ x: number; y: number }> {\n\t\tconst result = await this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\tif (rect.width === 0 && rect.height === 0) {\n\t\t\t\t\tthrow new Error('Element has zero size -- it may be hidden or not rendered');\n\t\t\t\t}\n\t\t\t\treturn { x: Math.round(rect.x + rect.width / 2), y: Math.round(rect.y + rect.height / 2) };\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'exception') {\n\t\t\tconst errorText = result.exceptionDetails?.text ?? 'Failed to get element position';\n\t\t\tthrow new Error(`Cannot interact with element: ${errorText}`);\n\t\t}\n\n\t\tif (result.type === 'success' && result.result?.type === 'object') {\n\t\t\tconst val = result.result.value as unknown;\n\t\t\tif (Array.isArray(val)) {\n\t\t\t\t// BiDi serializes objects as [[\"key\", value], ...] pairs\n\t\t\t\tconst map = new Map(val as [string, unknown][]);\n\t\t\t\tconst xVal = map.get('x');\n\t\t\t\tconst yVal = map.get('y');\n\t\t\t\tconst x = typeof xVal === 'object' && xVal !== null && 'value' in xVal ? (xVal as { value: number }).value : null;\n\t\t\t\tconst y = typeof yVal === 'object' && yVal !== null && 'value' in yVal ? (yVal as { value: number }).value : null;\n\t\t\t\tif (x !== null && y !== null) {\n\t\t\t\t\treturn { x, y };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t'Cannot get element position: unexpected response from browser. ' +\n\t\t\t'The element may not be visible or may not have a bounding rectangle.',\n\t\t);\n\t}\n\n\t/**\n\t * Scroll element into view and click it.\n\t *\n\t * Uses JavaScript `.click()` as the primary mechanism because it is\n\t * immune to viewport coordinate mismatches, DPI scaling, layout shifts,\n\t * and Chrome BiDi's unreliable element-origin support. This works\n\t * identically in headless and headed mode, with or without slowMo delays.\n\t *\n\t * The element is scrolled into view first so it's visible in headed mode\n\t * (important when users are watching the test run).\n\t */\n\tprivate async scrollIntoViewAndClick(located: LocatedElement, options?: ClickOptions): Promise<void> {\n\t\tconst ref = this.getSharedRef(located.node);\n\t\tconst clickCount = options?.clickCount ?? 1;\n\n\t\t// Scroll element into view so it's visible (especially in headed mode).\n\t\t// Use JS click for reliability — it dispatches the click event directly\n\t\t// on the element regardless of viewport coordinates or layout shifts.\n\t\tawait this.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(el, clickCount) {\n\t\t\t\tel.scrollIntoView({ block: \"center\", behavior: \"instant\" });\n\t\t\t\tfor (let i = 0; i < clickCount; i++) {\n\t\t\t\t\tel.click();\n\t\t\t\t}\n\t\t\t}`,\n\t\t\ttarget: { context: this.contextId },\n\t\t\targuments: [ref, { type: 'number', value: clickCount }],\n\t\t\tawaitPromise: false,\n\t\t});\n\t}\n\n\t/** Extract a string from a script evaluation result */\n\tprivate extractStringResult(result: ScriptEvaluateResult): string | null {\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Convert a BiDi RemoteValue back to a JS value */\n\tprivate deserializeRemoteValue(value: unknown): unknown {\n\t\tif (!value || typeof value !== 'object') return value;\n\t\tconst v = value as { type: string; value?: unknown };\n\t\tswitch (v.type) {\n\t\t\tcase 'undefined': return undefined;\n\t\t\tcase 'null': return null;\n\t\t\tcase 'string': return v.value;\n\t\t\tcase 'number': {\n\t\t\t\tconst n = v.value;\n\t\t\t\tif (n === 'NaN') return Number.NaN;\n\t\t\t\tif (n === '-0') return -0;\n\t\t\t\tif (n === 'Infinity') return Number.POSITIVE_INFINITY;\n\t\t\t\tif (n === '-Infinity') return Number.NEGATIVE_INFINITY;\n\t\t\t\treturn n;\n\t\t\t}\n\t\t\tcase 'boolean': return v.value;\n\t\t\tcase 'bigint': return BigInt(v.value as string);\n\t\t\tcase 'array': {\n\t\t\t\tif (Array.isArray(v.value)) {\n\t\t\t\t\treturn (v.value as unknown[]).map((item) => this.deserializeRemoteValue(item));\n\t\t\t\t}\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tcase 'object': {\n\t\t\t\tif (Array.isArray(v.value)) {\n\t\t\t\t\tconst obj: Record<string, unknown> = {};\n\t\t\t\t\tfor (const [key, val] of v.value as [string, unknown][]) {\n\t\t\t\t\t\tobj[key] = this.deserializeRemoteValue(val);\n\t\t\t\t\t}\n\t\t\t\t\treturn obj;\n\t\t\t\t}\n\t\t\t\treturn {};\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn v.value ?? null;\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// ElementHandle -- returned by page.get() for use with assertions\n// ---------------------------------------------------------------------------\n\n/**\n * A lazy reference to an element. Does not locate the element until\n * you interact with it or assert on it.\n */\nexport class ElementHandle {\n\t/** @internal */\n\treadonly page: Page;\n\t/** @internal */\n\treadonly target: ElementTarget;\n\n\tconstructor(page: Page, target: ElementTarget) {\n\t\tthis.page = page;\n\t\tthis.target = target;\n\t}\n\n\t/** Click this element */\n\tasync click(options?: ClickOptions): Promise<void> {\n\t\tawait this.page.click(this.target, options);\n\t}\n\n\t/** Fill this element with text */\n\tasync fill(value: string, options?: FillOptions): Promise<void> {\n\t\tawait this.page.fill(this.target, value, options);\n\t}\n\n\t/** Get the visible text content of this element */\n\tasync textContent(): Promise<string> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\tconst result = await this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.textContent || \"\"; }',\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/** Get an attribute value */\n\tasync getAttribute(name: string): Promise<string | null> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\tconst result = await this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(el, name) { return el.getAttribute(name); }`,\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref, { type: 'string', value: name }],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn null;\n\t}\n\n\t/** Check if the element is visible on the page */\n\tasync isVisible(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst located = await this.locate(5000);\n\t\t\tconst ref = this.getRef(located);\n\n\t\t\tconst result = await this.page.session.script.callFunction({\n\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\tconst style = window.getComputedStyle(el);\n\t\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\t\treturn style.display !== 'none' &&\n\t\t\t\t\t\tstyle.visibility !== 'hidden' &&\n\t\t\t\t\t\tstyle.opacity !== '0' &&\n\t\t\t\t\t\trect.width > 0 &&\n\t\t\t\t\t\trect.height > 0;\n\t\t\t\t}`,\n\t\t\t\ttarget: { context: this.page.contextId },\n\t\t\t\targuments: [ref],\n\t\t\t\tawaitPromise: false,\n\t\t\t});\n\n\t\t\treturn result.type === 'success' &&\n\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Count matching elements */\n\tasync count(): Promise<number> {\n\t\tconst elements = await locateAllElements(this.page.session, this.page.contextId, this.target);\n\t\treturn elements.length;\n\t}\n\n\t/** Get the visible inner text (like element.innerText, not textContent) */\n\tasync innerText(): Promise<string> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\tconst result = await this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.innerText || \"\"; }',\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/** Get the innerHTML of this element */\n\tasync innerHTML(): Promise<string> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\tconst result = await this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.innerHTML || \"\"; }',\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/** Get the current value of an input/textarea/select */\n\tasync inputValue(): Promise<string> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\tconst result = await this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { return el.value ?? \"\"; }',\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'string') {\n\t\t\treturn (result.result as { value: string }).value;\n\t\t}\n\t\treturn '';\n\t}\n\n\t/** Check if the element is enabled (not disabled) */\n\tasync isEnabled(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst located = await this.locate(5000);\n\t\t\tconst ref = this.getRef(located);\n\n\t\t\tconst result = await this.page.session.script.callFunction({\n\t\t\t\tfunctionDeclaration: 'function(el) { return !el.disabled; }',\n\t\t\t\ttarget: { context: this.page.contextId },\n\t\t\t\targuments: [ref],\n\t\t\t\tawaitPromise: false,\n\t\t\t});\n\n\t\t\treturn result.type === 'success' &&\n\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Check if a checkbox/radio is checked */\n\tasync isChecked(): Promise<boolean> {\n\t\ttry {\n\t\t\tconst located = await this.locate(5000);\n\t\t\tconst ref = this.getRef(located);\n\n\t\t\tconst result = await this.page.session.script.callFunction({\n\t\t\t\tfunctionDeclaration: 'function(el) { return !!el.checked; }',\n\t\t\t\ttarget: { context: this.page.contextId },\n\t\t\t\targuments: [ref],\n\t\t\t\tawaitPromise: false,\n\t\t\t});\n\n\t\t\treturn result.type === 'success' &&\n\t\t\t\tresult.result?.type === 'boolean' &&\n\t\t\t\t(result.result as { value: boolean }).value === true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/** Get the bounding box of the element */\n\tasync boundingBox(): Promise<{ x: number; y: number; width: number; height: number } | null> {\n\t\ttry {\n\t\t\tconst located = await this.locate(5000);\n\t\t\tconst ref = this.getRef(located);\n\n\t\t\tconst result = await this.page.session.script.callFunction({\n\t\t\t\tfunctionDeclaration: `function(el) {\n\t\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\t\treturn { x: rect.x, y: rect.y, width: rect.width, height: rect.height };\n\t\t\t\t}`,\n\t\t\t\ttarget: { context: this.page.contextId },\n\t\t\t\targuments: [ref],\n\t\t\t\tawaitPromise: false,\n\t\t\t});\n\n\t\t\tif (result.type === 'success' && result.result?.type === 'object') {\n\t\t\t\tconst val = result.result.value as unknown;\n\t\t\t\tif (Array.isArray(val)) {\n\t\t\t\t\tconst map = new Map(val as [string, unknown][]);\n\t\t\t\t\tconst extract = (key: string) => {\n\t\t\t\t\t\tconst v = map.get(key);\n\t\t\t\t\t\treturn typeof v === 'object' && v !== null && 'value' in v ? (v as { value: number }).value : 0;\n\t\t\t\t\t};\n\t\t\t\t\treturn { x: extract('x'), y: extract('y'), width: extract('width'), height: extract('height') };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/** Take a screenshot of just this element */\n\tasync screenshot(): Promise<Buffer> {\n\t\tconst located = await this.locate();\n\t\tconst ref = this.getRef(located);\n\n\t\t// Scroll into view first\n\t\tawait this.page.session.script.callFunction({\n\t\t\tfunctionDeclaration: 'function(el) { el.scrollIntoView({ block: \"center\", behavior: \"instant\" }); }',\n\t\t\ttarget: { context: this.page.contextId },\n\t\t\targuments: [ref],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\t// Get bounding box for clipping\n\t\tconst box = await this.boundingBox();\n\t\tif (!box || box.width === 0 || box.height === 0) {\n\t\t\tthrow new Error('Cannot screenshot element: element has no size or is not visible');\n\t\t}\n\n\t\tconst result = await this.page.session.browsingContext.captureScreenshot({\n\t\t\tcontext: this.page.contextId,\n\t\t\tclip: {\n\t\t\t\ttype: 'box',\n\t\t\t\tx: box.x,\n\t\t\t\ty: box.y,\n\t\t\t\twidth: box.width,\n\t\t\t\theight: box.height,\n\t\t\t},\n\t\t} as any);\n\n\t\treturn Buffer.from(result.data, 'base64');\n\t}\n\n\t/** Double-click this element */\n\tasync dblclick(options?: ClickOptions): Promise<void> {\n\t\tawait this.page.dblclick(this.target, options);\n\t}\n\n\t/** Hover over this element */\n\tasync hover(options?: { timeout?: number }): Promise<void> {\n\t\tawait this.page.hover(this.target, options);\n\t}\n\n\t/** Type text into this element character by character */\n\tasync type(text: string, options?: FillOptions): Promise<void> {\n\t\tawait this.page.type(this.target, text, options);\n\t}\n\n\t/** Focus this element */\n\tasync focus(options?: { timeout?: number }): Promise<void> {\n\t\tawait this.page.focus(this.target, options);\n\t}\n\n\t/** Remove focus from this element */\n\tasync blur(options?: { timeout?: number }): Promise<void> {\n\t\tawait this.page.blur(this.target, options);\n\t}\n\n\t/** @internal Locate the element with auto-wait */\n\tasync locate(timeout?: number): Promise<LocatedElement> {\n\t\treturn locateElement(\n\t\t\tthis.page.session,\n\t\t\tthis.page.contextId,\n\t\t\tthis.target,\n\t\t\t{ timeout: timeout ?? 30_000 },\n\t\t);\n\t}\n\n\tprivate getRef(located: LocatedElement): SharedReference {\n\t\tif (located.node.sharedId) {\n\t\t\treturn { sharedId: located.node.sharedId, handle: located.node.handle };\n\t\t}\n\t\tthrow new Error('Element has no shared reference');\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Map friendly key names to WebDriver key codes */\nfunction mapKey(key: string): string {\n\tconst keyMap: Record<string, string> = {\n\t\tEnter: '\\uE007',\n\t\tTab: '\\uE004',\n\t\tEscape: '\\uE00C',\n\t\tBackspace: '\\uE003',\n\t\tDelete: '\\uE017',\n\t\tArrowUp: '\\uE013',\n\t\tArrowDown: '\\uE015',\n\t\tArrowLeft: '\\uE012',\n\t\tArrowRight: '\\uE014',\n\t\tHome: '\\uE011',\n\t\tEnd: '\\uE010',\n\t\tPageUp: '\\uE00E',\n\t\tPageDown: '\\uE00F',\n\t\tControl: '\\uE009',\n\t\tAlt: '\\uE00A',\n\t\tShift: '\\uE008',\n\t\tMeta: '\\uE03D',\n\t\tSpace: ' ',\n\t};\n\treturn keyMap[key] ?? key;\n}\n\n/** Parse \"GET /api/users\" or \"/api/users\" or \"https://...\" into method + urlPattern */\nfunction parseMockPattern(pattern: string): { method: string | null; urlPattern: { type: 'string'; pattern: string } | { type: 'pattern'; pathname?: string; protocol?: string; hostname?: string } } {\n\tconst methodMatch = pattern.match(/^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s+(.+)$/i);\n\tif (methodMatch) {\n\t\tconst method = methodMatch[1]!.toUpperCase();\n\t\tconst path = methodMatch[2]!;\n\t\tif (path.startsWith('http')) {\n\t\t\treturn { method, urlPattern: { type: 'string', pattern: path } };\n\t\t}\n\t\treturn { method, urlPattern: { type: 'pattern', pathname: path } };\n\t}\n\n\tif (pattern.startsWith('http')) {\n\t\treturn { method: null, urlPattern: { type: 'string', pattern } };\n\t}\n\n\treturn { method: null, urlPattern: { type: 'pattern', pathname: pattern } };\n}\n\n/** Build response headers for a mock */\nfunction buildMockHeaders(response: MockResponse): Array<{ name: string; value: { type: 'string'; value: string } }> {\n\tconst headers: Array<{ name: string; value: { type: 'string'; value: string } }> = [];\n\n\t// Content-Type\n\tlet contentType = response.contentType;\n\tif (!contentType) {\n\t\tif (typeof response.body === 'object' && response.body !== null) {\n\t\t\tcontentType = 'application/json';\n\t\t} else if (typeof response.body === 'string') {\n\t\t\tcontentType = 'text/plain';\n\t\t}\n\t}\n\tif (contentType) {\n\t\theaders.push({ name: 'Content-Type', value: { type: 'string', value: contentType } });\n\t}\n\n\t// Custom headers\n\tif (response.headers) {\n\t\tfor (const [name, value] of Object.entries(response.headers)) {\n\t\t\theaders.push({ name, value: { type: 'string', value } });\n\t\t}\n\t}\n\n\treturn headers;\n}\n\n/** Build response body string */\nfunction buildMockBody(response: MockResponse): string | null {\n\tif (response.body === undefined || response.body === null) return null;\n\tif (typeof response.body === 'string') return response.body;\n\treturn JSON.stringify(response.body);\n}\n","// ============================================================================\n// Browsecraft - Browser Class\n// Manages a browser instance. Creates pages. Handles lifecycle.\n// ============================================================================\n\nimport { BiDiSession, type SessionOptions } from 'browsecraft-bidi';\nimport { Page } from './page.js';\nimport { resolveConfig, type BrowsecraftConfig, type UserConfig } from './config.js';\n\n// ---------------------------------------------------------------------------\n// Shared viewport setup helper (used by both Browser and BrowserContext)\n// ---------------------------------------------------------------------------\n\n/**\n * Configure the viewport for a newly created browsing context.\n *\n * - Headless: uses BiDi setViewport (device metrics emulation).\n * - Headed: uses window.resizeTo() to avoid gray dead-space from emulation.\n * - Maximized: skips all resizing — the browser is already full screen.\n */\nasync function applyViewport(\n\tsession: BiDiSession,\n\tcontextId: string,\n\tconfig: BrowsecraftConfig,\n): Promise<void> {\n\tif (config.maximized && !config.headless) {\n\t\t// Maximized — browser fills the screen, no resizing needed\n\t\treturn;\n\t}\n\n\tif (config.headless) {\n\t\ttry {\n\t\t\tawait session.browsingContext.setViewport({\n\t\t\t\tcontext: contextId,\n\t\t\t\tviewport: config.viewport,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Some browsers/versions may not support setViewport\n\t\t}\n\t\treturn;\n\t}\n\n\t// Headed mode: resize the outer window so its natural content area\n\t// matches the desired viewport (avoids device emulation artifacts).\n\ttry {\n\t\tconst { width, height } = config.viewport;\n\t\tawait session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(targetW, targetH) {\n\t\t\t\tconst chromeW = window.outerWidth - window.innerWidth;\n\t\t\t\tconst chromeH = window.outerHeight - window.innerHeight;\n\t\t\t\twindow.resizeTo(targetW + chromeW, targetH + chromeH);\n\t\t\t}`,\n\t\t\ttarget: { context: contextId },\n\t\t\targuments: [\n\t\t\t\t{ type: 'number', value: width },\n\t\t\t\t{ type: 'number', value: height },\n\t\t\t],\n\t\t\tawaitPromise: false,\n\t\t});\n\t} catch {\n\t\t// Fallback to setViewport if resizeTo fails\n\t\ttry {\n\t\t\tawait session.browsingContext.setViewport({\n\t\t\t\tcontext: contextId,\n\t\t\t\tviewport: config.viewport,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Continue anyway\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Browser\n// ---------------------------------------------------------------------------\n\n/**\n * Browser represents a running browser instance.\n * Use `Browser.launch()` to start one, or let the test() fixtures do it for you.\n *\n * ```ts\n * const browser = await Browser.launch();\n * const page = await browser.newPage();\n * await page.goto('https://example.com');\n * await browser.close();\n * ```\n */\nexport class Browser {\n\t/** @internal */\n\treadonly session: BiDiSession;\n\t/** @internal */\n\tprivate config: BrowsecraftConfig;\n\t/** @internal */\n\tprivate pages: Page[] = [];\n\n\tprivate constructor(session: BiDiSession, config: BrowsecraftConfig) {\n\t\tthis.session = session;\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Launch a new browser instance.\n\t *\n\t * ```ts\n\t * const browser = await Browser.launch(); // Chrome, headless\n\t * const browser = await Browser.launch({ browser: 'firefox', headless: false });\n\t * ```\n\t */\n\tstatic async launch(userConfig?: UserConfig): Promise<Browser> {\n\t\tconst config = resolveConfig(userConfig);\n\n\t\tconst sessionOptions: SessionOptions = {\n\t\t\tbrowser: config.browser,\n\t\t\theadless: config.headless,\n\t\t\texecutablePath: config.executablePath,\n\t\t\tdebug: config.debug,\n\t\t\ttimeout: config.timeout,\n\t\t\tmaximized: config.maximized,\n\t\t};\n\n\t\tconst session = await BiDiSession.launch(sessionOptions);\n\t\treturn new Browser(session, config);\n\t}\n\n\t/**\n\t * Connect to an already-running browser.\n\t *\n\t * ```ts\n\t * const browser = await Browser.connect('ws://localhost:9222/session');\n\t * ```\n\t */\n\tstatic async connect(wsEndpoint: string, userConfig?: UserConfig): Promise<Browser> {\n\t\tconst config = resolveConfig(userConfig);\n\t\tconst session = await BiDiSession.connect(wsEndpoint);\n\t\treturn new Browser(session, config);\n\t}\n\n\t/**\n\t * Create a new page (tab).\n\t *\n\t * ```ts\n\t * const page = await browser.newPage();\n\t * await page.goto('https://example.com');\n\t * ```\n\t */\n\tasync newPage(): Promise<Page> {\n\t\tconst result = await this.session.browsingContext.create({ type: 'tab' });\n\t\tconst contextId = result.context;\n\n\t\tawait applyViewport(this.session, contextId, this.config);\n\n\t\tconst page = new Page(this.session, contextId, this.config);\n\t\tthis.pages.push(page);\n\n\t\t// Clean up pages array when context is destroyed\n\t\tthis.session.on('browsingContext.closed', (event) => {\n\t\t\tconst params = event.params as { context?: string };\n\t\t\tif (params.context === contextId) {\n\t\t\t\tconst idx = this.pages.indexOf(page);\n\t\t\t\tif (idx !== -1) this.pages.splice(idx, 1);\n\t\t\t}\n\t\t});\n\n\t\treturn page;\n\t}\n\n\t/** Get all open pages. */\n\tget openPages(): Page[] {\n\t\treturn [...this.pages];\n\t}\n\n\t/**\n\t * Create an isolated browser context (like incognito).\n\t * Returns a BrowserContext that can create its own pages.\n\t */\n\tasync newContext(): Promise<BrowserContext> {\n\t\ttry {\n\t\t\tconst result = await this.session.send('browser.createUserContext', {});\n\t\t\tconst userContext = (result as { userContext: string }).userContext;\n\t\t\treturn new BrowserContext(this.session, this.config, userContext);\n\t\t} catch (err) {\n\t\t\tconsole.warn(\n\t\t\t\t'[browsecraft] Warning: browser.createUserContext is not supported. ' +\n\t\t\t\t'Pages will share cookies/storage. ' +\n\t\t\t\t(err instanceof Error ? err.message : String(err)),\n\t\t\t);\n\t\t\treturn new BrowserContext(this.session, this.config, null);\n\t\t}\n\t}\n\n\t/** Close the browser and clean up all resources. */\n\tasync close(): Promise<void> {\n\t\tfor (const page of this.pages) {\n\t\t\tawait page.close().catch(() => {});\n\t\t}\n\t\tthis.pages = [];\n\t\tawait this.session.close();\n\t}\n\n\t/** Whether the browser is still connected */\n\tget isConnected(): boolean {\n\t\treturn this.session.isConnected;\n\t}\n\n\t/** Get the resolved config */\n\tgetConfig(): BrowsecraftConfig {\n\t\treturn { ...this.config };\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// BrowserContext -- isolated context (like incognito mode)\n// ---------------------------------------------------------------------------\n\n/**\n * An isolated browser context. Pages created in different contexts\n * don't share cookies, storage, or cache.\n */\nexport class BrowserContext {\n\t/** @internal */\n\tprivate session: BiDiSession;\n\t/** @internal */\n\tprivate config: BrowsecraftConfig;\n\t/** @internal */\n\tprivate userContext: string | null;\n\t/** @internal */\n\tprivate pages: Page[] = [];\n\n\tconstructor(session: BiDiSession, config: BrowsecraftConfig, userContext: string | null) {\n\t\tthis.session = session;\n\t\tthis.config = config;\n\t\tthis.userContext = userContext;\n\t}\n\n\t/** Create a new page in this context. */\n\tasync newPage(): Promise<Page> {\n\t\tconst params: Record<string, unknown> = { type: 'tab' };\n\t\tif (this.userContext) {\n\t\t\tparams.userContext = this.userContext;\n\t\t}\n\n\t\tconst result = await this.session.browsingContext.create(params as any);\n\t\tconst contextId = result.context;\n\n\t\tawait applyViewport(this.session, contextId, this.config);\n\n\t\tconst page = new Page(this.session, contextId, this.config);\n\t\tthis.pages.push(page);\n\t\treturn page;\n\t}\n\n\t/** Close this context and all its pages. */\n\tasync close(): Promise<void> {\n\t\tfor (const page of this.pages) {\n\t\t\tawait page.close().catch(() => {});\n\t\t}\n\t\tthis.pages = [];\n\n\t\tif (this.userContext) {\n\t\t\tawait this.session.send('browser.removeUserContext', {\n\t\t\t\tuserContext: this.userContext,\n\t\t\t}).catch(() => {});\n\t\t}\n\t}\n}\n","// ============================================================================\n// Browsecraft - Test Function\n// The core test authoring API. Uses fixture injection to provide page, browser, etc.\n//\n// import { test, expect } from 'browsecraft';\n//\n// test('user can log in', async ({ page }) => {\n// await page.goto('/login');\n// await page.fill('Email', 'user@test.com');\n// await page.fill('Password', 'secret');\n// await page.click('Sign In');\n// await expect(page).toHaveURL('/dashboard');\n// });\n// ============================================================================\n\nimport { Browser, BrowserContext } from './browser.js';\nimport { Page } from './page.js';\nimport { resolveConfig } from './config.js';\nimport type { UserConfig } from './config.js';\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Fixtures available in every test */\nexport interface TestFixtures {\n\t/** A fresh page in a new browser context. Auto-closed after the test. */\n\tpage: Page;\n\t/** The browser context for this test. */\n\tcontext: BrowserContext;\n\t/** The browser instance (shared across tests in a worker). */\n\tbrowser: Browser;\n}\n\n/** A single test case, registered by test() */\nexport interface TestCase {\n\t/** Test title */\n\ttitle: string;\n\t/** The test function */\n\tfn: (fixtures: TestFixtures) => Promise<void>;\n\t/** Test options */\n\toptions: TestOptions;\n\t/** File this test was defined in */\n\tfile?: string;\n\t/** Suite/describe path (e.g., ['Login', 'form validation']) */\n\tsuitePath: string[];\n\t/** Whether this test is skipped */\n\tskip: boolean;\n\t/** Whether only this test should run */\n\tonly: boolean;\n}\n\n/** Options for individual tests */\nexport interface TestOptions {\n\t/** Override timeout for this specific test */\n\ttimeout?: number;\n\t/** Number of retries for this specific test */\n\tretries?: number;\n\t/** Tags for filtering (e.g., ['smoke', 'regression']) */\n\ttags?: string[];\n}\n\n/** Internal test registry -- the runner reads from here */\nexport const testRegistry: TestCase[] = [];\n\n/** Current suite stack for describe() nesting */\nconst suiteStack: string[] = [];\n\n/** Track which beforeAll hooks have already been executed */\nconst executedBeforeAllHooks = new Set<string>();\n\n/** Track which afterAll hooks have already been executed */\nconst executedAfterAllHooks = new Set<string>();\n\n// ---------------------------------------------------------------------------\n// test() -- the main API\n// ---------------------------------------------------------------------------\n\n/**\n * Define a browser test.\n *\n * ```ts\n * import { test, expect } from 'browsecraft';\n *\n * test('user can log in', async ({ page }) => {\n * await page.goto('/login');\n * await page.fill('Email', 'user@test.com');\n * await page.fill('Password', 'secret');\n * await page.click('Sign In');\n * await expect(page).toHaveURL('/dashboard');\n * });\n * ```\n */\nexport function test(title: string, fn: (fixtures: TestFixtures) => Promise<void>): void;\nexport function test(title: string, options: TestOptions, fn: (fixtures: TestFixtures) => Promise<void>): void;\nexport function test(\n\ttitle: string,\n\tfnOrOptions: ((fixtures: TestFixtures) => Promise<void>) | TestOptions,\n\tmaybeFn?: (fixtures: TestFixtures) => Promise<void>,\n): void {\n\tconst fn = typeof fnOrOptions === 'function' ? fnOrOptions : maybeFn!;\n\tconst options = typeof fnOrOptions === 'function' ? {} : fnOrOptions;\n\n\ttestRegistry.push({\n\t\ttitle,\n\t\tfn,\n\t\toptions,\n\t\tsuitePath: [...suiteStack],\n\t\tskip: false,\n\t\tonly: false,\n\t});\n}\n\n/**\n * Skip a test.\n *\n * ```ts\n * test.skip('broken test', async ({ page }) => { ... });\n * ```\n */\ntest.skip = function skipTest(\n\ttitle: string,\n\tfn: (fixtures: TestFixtures) => Promise<void>,\n): void {\n\ttestRegistry.push({\n\t\ttitle,\n\t\tfn,\n\t\toptions: {},\n\t\tsuitePath: [...suiteStack],\n\t\tskip: true,\n\t\tonly: false,\n\t});\n};\n\n/**\n * Only run this test (skip all others).\n *\n * ```ts\n * test.only('focused test', async ({ page }) => { ... });\n * ```\n */\ntest.only = function onlyTest(\n\ttitle: string,\n\tfn: (fixtures: TestFixtures) => Promise<void>,\n): void {\n\ttestRegistry.push({\n\t\ttitle,\n\t\tfn,\n\t\toptions: {},\n\t\tsuitePath: [...suiteStack],\n\t\tskip: false,\n\t\tonly: true,\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// describe() -- grouping tests\n// ---------------------------------------------------------------------------\n\n/**\n * Group related tests together.\n *\n * ```ts\n * describe('Login', () => {\n * test('shows form', async ({ page }) => { ... });\n * test('validates email', async ({ page }) => { ... });\n * });\n * ```\n */\nexport function describe(title: string, fn: () => void): void {\n\tsuiteStack.push(title);\n\tfn();\n\tsuiteStack.pop();\n}\n\n/**\n * Skip a describe block.\n */\ndescribe.skip = function skipDescribe(title: string, fn: () => void): void {\n\tsuiteStack.push(title);\n\t// Register all tests inside as skipped\n\tconst startIndex = testRegistry.length;\n\tfn();\n\tfor (let i = startIndex; i < testRegistry.length; i++) {\n\t\ttestRegistry[i]!.skip = true;\n\t}\n\tsuiteStack.pop();\n};\n\n/**\n * Only run tests in this describe block.\n */\ndescribe.only = function onlyDescribe(title: string, fn: () => void): void {\n\tsuiteStack.push(title);\n\tconst startIndex = testRegistry.length;\n\tfn();\n\tfor (let i = startIndex; i < testRegistry.length; i++) {\n\t\ttestRegistry[i]!.only = true;\n\t}\n\tsuiteStack.pop();\n};\n\n// ---------------------------------------------------------------------------\n// Hooks\n// ---------------------------------------------------------------------------\n\n/** Before/after hooks for a describe block */\nexport type HookFn = (fixtures: TestFixtures) => Promise<void>;\n\nconst hooks = {\n\tbeforeAll: [] as Array<{ fn: HookFn; suitePath: string[] }>,\n\tafterAll: [] as Array<{ fn: HookFn; suitePath: string[] }>,\n\tbeforeEach: [] as Array<{ fn: HookFn; suitePath: string[] }>,\n\tafterEach: [] as Array<{ fn: HookFn; suitePath: string[] }>,\n};\n\n/**\n * Run before all tests in the current describe block.\n */\nexport function beforeAll(fn: HookFn): void {\n\thooks.beforeAll.push({ fn, suitePath: [...suiteStack] });\n}\n\n/**\n * Run after all tests in the current describe block.\n */\nexport function afterAll(fn: HookFn): void {\n\thooks.afterAll.push({ fn, suitePath: [...suiteStack] });\n}\n\n/**\n * Run before each test in the current describe block.\n */\nexport function beforeEach(fn: HookFn): void {\n\thooks.beforeEach.push({ fn, suitePath: [...suiteStack] });\n}\n\n/**\n * Run after each test in the current describe block.\n */\nexport function afterEach(fn: HookFn): void {\n\thooks.afterEach.push({ fn, suitePath: [...suiteStack] });\n}\n\n/** Get hooks for a test (used by the runner) */\nexport function getHooks() {\n\treturn { ...hooks };\n}\n\n// ---------------------------------------------------------------------------\n// Internal: Run a single test with fixtures\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a single test case with proper fixture setup/teardown.\n * This is called by the test runner.\n */\nexport async function runTest(\n\ttestCase: TestCase,\n\tsharedBrowser?: Browser,\n\tuserConfig?: UserConfig,\n): Promise<TestResult> {\n\tconst startTime = Date.now();\n\tconst config = resolveConfig(userConfig);\n\n\tif (testCase.skip) {\n\t\treturn {\n\t\t\ttitle: testCase.title,\n\t\t\tsuitePath: testCase.suitePath,\n\t\t\tstatus: 'skipped',\n\t\t\tduration: 0,\n\t\t};\n\t}\n\n\tlet browser: Browser | undefined;\n\tlet context: BrowserContext | undefined;\n\tlet page: Page | undefined;\n\n\ttry {\n\t\t// Use shared browser if provided, otherwise launch a new one\n\t\tbrowser = sharedBrowser ?? await Browser.launch();\n\t\tcontext = await browser.newContext();\n\t\tpage = await context.newPage();\n\n\t\tconst fixtures: TestFixtures = { page, context, browser };\n\n\t\t// Run beforeAll hooks (only for hooks that haven't been run yet for this suite)\n\t\tconst applicableBeforeAll = hooks.beforeAll.filter(h =>\n\t\t\tisHookApplicable(h.suitePath, testCase.suitePath),\n\t\t);\n\t\tfor (const hook of applicableBeforeAll) {\n\t\t\tconst hookKey = `${hook.suitePath.join('>')}:${hooks.beforeAll.indexOf(hook)}`;\n\t\t\tif (!executedBeforeAllHooks.has(hookKey)) {\n\t\t\t\tawait hook.fn(fixtures);\n\t\t\t\texecutedBeforeAllHooks.add(hookKey);\n\t\t\t}\n\t\t}\n\n\t\t// Run beforeEach hooks\n\t\tconst applicableBeforeEach = hooks.beforeEach.filter(h =>\n\t\t\tisHookApplicable(h.suitePath, testCase.suitePath),\n\t\t);\n\t\tfor (const hook of applicableBeforeEach) {\n\t\t\tawait hook.fn(fixtures);\n\t\t}\n\n\t\t// Run the test\n\t\tconst timeout = testCase.options.timeout ?? config.timeout;\n\t\tawait Promise.race([\n\t\t\ttestCase.fn(fixtures),\n\t\t\tnew Promise<never>((_, reject) =>\n\t\t\t\tsetTimeout(() => reject(new Error(`Test timed out after ${timeout}ms`)), timeout),\n\t\t\t),\n\t\t]);\n\n\t\t// Run afterEach hooks\n\t\tconst applicableAfterEach = hooks.afterEach.filter(h =>\n\t\t\tisHookApplicable(h.suitePath, testCase.suitePath),\n\t\t);\n\t\tfor (const hook of applicableAfterEach) {\n\t\t\tawait hook.fn(fixtures);\n\t\t}\n\n\t\t// Take screenshot on success if config says 'always'\n\t\tlet screenshotPath: string | undefined;\n\t\tif (config.screenshot === 'always' && page) {\n\t\t\tscreenshotPath = await captureScreenshot(page, testCase, config.outputDir).catch(() => undefined);\n\t\t}\n\n\t\tconst duration = Date.now() - startTime;\n\t\treturn {\n\t\t\ttitle: testCase.title,\n\t\t\tsuitePath: testCase.suitePath,\n\t\t\tstatus: 'passed',\n\t\t\tduration,\n\t\t\tscreenshotPath,\n\t\t};\n\t} catch (error) {\n\t\tconst duration = Date.now() - startTime;\n\n\t\t// Capture screenshot on failure if configured\n\t\tlet screenshotPath: string | undefined;\n\t\tif ((config.screenshot === 'on-failure' || config.screenshot === 'always') && page) {\n\t\t\tscreenshotPath = await captureScreenshot(page, testCase, config.outputDir).catch(() => undefined);\n\t\t}\n\n\t\treturn {\n\t\t\ttitle: testCase.title,\n\t\t\tsuitePath: testCase.suitePath,\n\t\t\tstatus: 'failed',\n\t\t\tduration,\n\t\t\terror: error instanceof Error ? error : new Error(String(error)),\n\t\t\tscreenshotPath,\n\t\t};\n\t} finally {\n\t\t// Clean up context (page is closed when context closes)\n\t\tawait context?.close().catch(() => {});\n\t\t// Only close browser if we launched it\n\t\tif (!sharedBrowser && browser) {\n\t\t\tawait browser.close().catch(() => {});\n\t\t}\n\t}\n}\n\n/**\n * Run afterAll hooks for the given suite path.\n * Called by the runner after all tests in a suite have completed.\n */\nexport async function runAfterAllHooks(\n\tsuitePath: string[],\n\tfixtures: TestFixtures,\n): Promise<void> {\n\tconst applicableAfterAll = hooks.afterAll.filter(h =>\n\t\tisHookApplicable(h.suitePath, suitePath),\n\t);\n\tfor (const hook of applicableAfterAll) {\n\t\tconst hookKey = `${hook.suitePath.join('>')}:${hooks.afterAll.indexOf(hook)}`;\n\t\tif (!executedAfterAllHooks.has(hookKey)) {\n\t\t\tawait hook.fn(fixtures);\n\t\t\texecutedAfterAllHooks.add(hookKey);\n\t\t}\n\t}\n}\n\n/**\n * Reset all hooks and registries (for test isolation between files).\n */\nexport function resetTestState(): void {\n\ttestRegistry.length = 0;\n\thooks.beforeAll.length = 0;\n\thooks.afterAll.length = 0;\n\thooks.beforeEach.length = 0;\n\thooks.afterEach.length = 0;\n\texecutedBeforeAllHooks.clear();\n\texecutedAfterAllHooks.clear();\n\tsuiteStack.length = 0;\n}\n\n/** Check if a hook applies to a test based on suite nesting */\nfunction isHookApplicable(hookSuitePath: string[], testSuitePath: string[]): boolean {\n\tif (hookSuitePath.length === 0) return true; // Global hook applies to all\n\tif (hookSuitePath.length > testSuitePath.length) return false;\n\treturn hookSuitePath.every((s, i) => testSuitePath[i] === s);\n}\n\n/** Capture a screenshot and save it to the output directory */\nasync function captureScreenshot(page: Page, testCase: TestCase, outputDir: string): Promise<string> {\n\t// Build a safe filename from suite path + test title\n\tconst parts = [...testCase.suitePath, testCase.title];\n\tconst safeName = parts\n\t\t.join('-')\n\t\t.replace(/[^a-zA-Z0-9_-]/g, '_')\n\t\t.replace(/_+/g, '_')\n\t\t.slice(0, 200);\n\tconst timestamp = Date.now();\n\tconst filename = `${safeName}-${timestamp}.png`;\n\tconst screenshotDir = join(outputDir, 'screenshots');\n\n\t// Ensure directory exists\n\tawait mkdir(screenshotDir, { recursive: true });\n\n\t// Capture and save\n\tconst buffer = await page.screenshot();\n\tconst filePath = join(screenshotDir, filename);\n\tawait writeFile(filePath, buffer);\n\n\treturn filePath;\n}\n\n/** Result of running a single test */\nexport interface TestResult {\n\ttitle: string;\n\tsuitePath: string[];\n\tstatus: 'passed' | 'failed' | 'skipped';\n\tduration: number;\n\terror?: Error;\n\t/** Path to screenshot file (if captured on failure) */\n\tscreenshotPath?: string;\n}\n"]}