browsecraft 0.3.0 → 0.4.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.
@@ -14,6 +14,7 @@ var DEFAULTS = {
14
14
  viewport: { width: 1280, height: 720 },
15
15
  maximized: false,
16
16
  workers: Math.max(1, Math.floor((typeof cpus === "function" ? cpus().length : 4) / 2)),
17
+ strategy: "matrix",
17
18
  testMatch: "**/*.test.{ts,js,mts,mjs}",
18
19
  outputDir: ".browsecraft",
19
20
  ai: "auto",
@@ -2296,7 +2297,8 @@ var Browser = class _Browser {
2296
2297
  maximized: config.maximized
2297
2298
  };
2298
2299
  const session = await BiDiSession.launch(sessionOptions);
2299
- return new _Browser(session, config);
2300
+ const browser = new _Browser(session, config);
2301
+ return browser;
2300
2302
  }
2301
2303
  /**
2302
2304
  * Connect to an already-running browser.
@@ -2312,6 +2314,9 @@ var Browser = class _Browser {
2312
2314
  }
2313
2315
  /**
2314
2316
  * Create a new page (tab).
2317
+ * If an idle about:blank tab exists (e.g., Chrome's initial tab), it is
2318
+ * reused instead of creating a new one. This prevents the "double window"
2319
+ * issue in headed mode.
2315
2320
  *
2316
2321
  * ```ts
2317
2322
  * const page = await browser.newPage();
@@ -2319,8 +2324,14 @@ var Browser = class _Browser {
2319
2324
  * ```
2320
2325
  */
2321
2326
  async newPage() {
2322
- const result = await this.session.browsingContext.create({ type: "tab" });
2323
- const contextId = result.context;
2327
+ let contextId;
2328
+ const reused = await this.tryReuseInitialTab();
2329
+ if (reused) {
2330
+ contextId = reused;
2331
+ } else {
2332
+ const result = await this.session.browsingContext.create({ type: "tab" });
2333
+ contextId = result.context;
2334
+ }
2324
2335
  await applyViewport(this.session, contextId, this.config);
2325
2336
  const page = new Page(this.session, contextId, this.config);
2326
2337
  this.pages.push(page);
@@ -2370,6 +2381,25 @@ var Browser = class _Browser {
2370
2381
  getConfig() {
2371
2382
  return { ...this.config };
2372
2383
  }
2384
+ /**
2385
+ * Try to find and reuse an existing about:blank tab (Chrome opens one on startup).
2386
+ * Returns the context ID if found, or null if no idle tab exists.
2387
+ * @internal
2388
+ */
2389
+ async tryReuseInitialTab() {
2390
+ try {
2391
+ const tree = await this.session.browsingContext.getTree();
2392
+ const contexts = tree.contexts ?? [];
2393
+ for (const ctx of contexts) {
2394
+ const alreadyTracked = this.pages.some((p) => p.contextId === ctx.context);
2395
+ if (!alreadyTracked && ctx.url === "about:blank") {
2396
+ return ctx.context;
2397
+ }
2398
+ }
2399
+ } catch {
2400
+ }
2401
+ return null;
2402
+ }
2373
2403
  };
2374
2404
  var BrowserContext = class {
2375
2405
  /** @internal */
@@ -2615,6 +2645,6 @@ async function captureScreenshot(page, testCase, outputDir) {
2615
2645
  return filePath;
2616
2646
  }
2617
2647
 
2618
- export { BrowsecraftError, Browser, BrowserContext, ElementHandle, ElementNotActionableError, ElementNotFoundError, NetworkError, Page, TimeoutError, afterAll, afterEach, beforeAll, beforeEach, defineConfig, describe, resetTestState, resolveConfig, runAfterAllHooks, runTest, test, testRegistry };
2619
- //# sourceMappingURL=chunk-3OBA6D2X.js.map
2620
- //# sourceMappingURL=chunk-3OBA6D2X.js.map
2648
+ export { BrowsecraftError, Browser, BrowserContext, ElementHandle, ElementNotActionableError, ElementNotFoundError, NetworkError, Page, TimeoutError, afterAll, afterEach, beforeAll, beforeEach, defineConfig, describe, resetTestState, resolveConfig, runAfterAllHooks, runTest, sleep, test, testRegistry, waitFor };
2649
+ //# sourceMappingURL=chunk-P3F7FGFM.js.map
2650
+ //# sourceMappingURL=chunk-P3F7FGFM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/wait.ts","../src/locator.ts","../src/page.ts","../src/browser.ts","../src/test.ts"],"names":["describeTarget","params"],"mappings":"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","file":"chunk-P3F7FGFM.js","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/** Execution strategy for multi-browser runs */\nexport type ExecutionStrategy = 'parallel' | 'sequential' | 'matrix';\n\n/** Full configuration with all options */\nexport interface BrowsecraftConfig {\n\t/** Which browser to use (default: 'chrome') */\n\tbrowser: BrowserName;\n\t/**\n\t * Run tests across multiple browsers simultaneously.\n\t * Overrides `browser` when set.\n\t *\n\t * ```ts\n\t * defineConfig({\n\t * browsers: ['chrome', 'firefox', 'edge'],\n\t * workers: 2, // 2 instances per browser = 6 total\n\t * strategy: 'matrix', // every scenario on every browser\n\t * });\n\t * ```\n\t */\n\tbrowsers?: 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/**\n\t * Number of parallel workers per browser (default: CPU cores / 2).\n\t * When using `browsers: ['chrome', 'firefox']` with `workers: 3`,\n\t * you get 3 Chrome + 3 Firefox = 6 total worker instances.\n\t */\n\tworkers: number;\n\t/**\n\t * Execution strategy for multi-browser runs (default: 'matrix').\n\t *\n\t * - `'parallel'`: All workers share one queue. Fastest, but a scenario\n\t * may only run on one browser.\n\t * - `'sequential'`: One browser at a time. Each gets all scenarios.\n\t * - `'matrix'`: Every scenario on every browser. Full cross-browser\n\t * coverage. Total runs = scenarios × browsers.\n\t */\n\tstrategy: ExecutionStrategy;\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\t/** BDD configuration for Gherkin feature files */\n\tbdd?: BddConfig;\n}\n\n/** Configuration for BDD (Gherkin) test execution */\nexport interface BddConfig {\n\t// Glob pattern for feature files (default: 'features/**\\/*.feature')\n\tfeatures?: string;\n\t// Glob pattern for step definition files (default: 'steps/**\\/*.{ts,js,mts,mjs}')\n\tsteps?: string;\n\t/** Whether to register the 38 built-in step definitions (default: true) */\n\tbuiltInSteps?: 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\tstrategy: 'matrix',\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 - Rich Error System\n// When something fails, tell the user WHY and WHAT TO DO about it.\n//\n// Instead of: \"Timed out after 30000ms\"\n// We say: \"Could not click 'Submit' — found the element but it was disabled.\n// Hint: wait for the form to finish loading, or check if the button\n// is conditionally enabled.\"\n// ============================================================================\n\n/** Element state snapshot at the time of failure */\nexport interface ElementState {\n\t/** Whether the element was found in the DOM */\n\tfound: boolean;\n\t/** Whether the element is visible (display, visibility, opacity, size) */\n\tvisible?: boolean;\n\t/** Whether the element is enabled (not disabled) */\n\tenabled?: boolean;\n\t/** Tag name (e.g., 'BUTTON', 'INPUT') */\n\ttagName?: string;\n\t/** Text content preview */\n\ttextPreview?: string;\n\t/** Bounding box */\n\tboundingBox?: { x: number; y: number; width: number; height: number };\n\t/** Whether the element is obscured by another element */\n\tobscured?: boolean;\n\t/** The element that is obscuring this one */\n\tobscuredBy?: string;\n\t/** Classes on the element */\n\tclasses?: string;\n\t/** id attribute */\n\tid?: string;\n}\n\n/**\n * Base error class for all Browsecraft errors.\n * Rich context helps users diagnose issues immediately.\n */\nexport class BrowsecraftError extends Error {\n\toverride readonly name: string = 'BrowsecraftError';\n\n\t/** What action was being performed */\n\treadonly action: string;\n\t/** What target was being acted on */\n\treadonly target: string;\n\t/** Element state at the time of failure */\n\treadonly elementState?: ElementState;\n\t/** Hint for how to fix the issue */\n\treadonly hint?: string;\n\t/** How long we waited before giving up (ms) */\n\treadonly elapsed?: number;\n\n\tconstructor(options: {\n\t\taction: string;\n\t\ttarget: string;\n\t\tmessage: string;\n\t\telementState?: ElementState;\n\t\thint?: string;\n\t\telapsed?: number;\n\t\tcause?: Error;\n\t}) {\n\t\tconst parts: string[] = [];\n\t\tparts.push(`Could not ${options.action} '${options.target}'`);\n\t\tparts.push(`— ${options.message}`);\n\n\t\tif (options.elementState) {\n\t\t\tparts.push('');\n\t\t\tparts.push(formatElementState(options.elementState));\n\t\t}\n\n\t\tif (options.hint) {\n\t\t\tparts.push('');\n\t\t\tparts.push(`Hint: ${options.hint}`);\n\t\t}\n\n\t\tif (options.elapsed !== undefined) {\n\t\t\tparts.push(`(waited ${options.elapsed}ms)`);\n\t\t}\n\n\t\tsuper(parts.join('\\n'));\n\t\tthis.action = options.action;\n\t\tthis.target = options.target;\n\t\tthis.elementState = options.elementState;\n\t\tthis.hint = options.hint;\n\t\tthis.elapsed = options.elapsed;\n\t\tif (options.cause) {\n\t\t\tthis.cause = options.cause;\n\t\t}\n\t}\n}\n\n/**\n * Error thrown when an element cannot be found.\n */\nexport class ElementNotFoundError extends BrowsecraftError {\n\toverride readonly name = 'ElementNotFoundError';\n\n\tconstructor(options: {\n\t\taction: string;\n\t\ttarget: string;\n\t\telapsed?: number;\n\t\tsuggestions?: string[];\n\t}) {\n\t\tconst hint = options.suggestions?.length\n\t\t\t? `Did you mean one of these?\\n${options.suggestions.map((s) => ` - ${s}`).join('\\n')}`\n\t\t\t: 'Check that the element exists on the page and the text/selector is correct.';\n\n\t\tsuper({\n\t\t\taction: options.action,\n\t\t\ttarget: options.target,\n\t\t\tmessage: 'no matching element found on the page.',\n\t\t\telementState: { found: false },\n\t\t\thint,\n\t\t\telapsed: options.elapsed,\n\t\t});\n\t}\n}\n\n/**\n * Error thrown when an element is found but not actionable.\n */\nexport class ElementNotActionableError extends BrowsecraftError {\n\toverride readonly name = 'ElementNotActionableError';\n\treadonly reason: 'not-visible' | 'disabled' | 'obscured' | 'zero-size' | 'detached';\n\n\tconstructor(options: {\n\t\taction: string;\n\t\ttarget: string;\n\t\treason: 'not-visible' | 'disabled' | 'obscured' | 'zero-size' | 'detached';\n\t\telementState: ElementState;\n\t\telapsed?: number;\n\t}) {\n\t\tconst messages: Record<string, string> = {\n\t\t\t'not-visible':\n\t\t\t\t'the element was found but is not visible (display:none, visibility:hidden, opacity:0, or zero size).',\n\t\t\tdisabled: 'the element was found but is disabled.',\n\t\t\tobscured: `the element was found but is obscured by another element${options.elementState.obscuredBy ? ` (${options.elementState.obscuredBy})` : ''}.`,\n\t\t\t'zero-size': 'the element was found but has zero width/height.',\n\t\t\tdetached: 'the element was found but is no longer attached to the DOM.',\n\t\t};\n\n\t\tconst hints: Record<string, string> = {\n\t\t\t'not-visible': 'Wait for a loading state to complete, or check CSS visibility rules.',\n\t\t\tdisabled:\n\t\t\t\t'Wait for the element to become enabled, or check if a prerequisite action is needed first.',\n\t\t\tobscured:\n\t\t\t\t'Scroll the page, close overlapping modals/tooltips, or use { force: true } to bypass.',\n\t\t\t'zero-size': 'Check if the element has proper dimensions. It may be collapsed or off-screen.',\n\t\t\tdetached:\n\t\t\t\t'The element was removed from the DOM while waiting. This often happens with dynamic content.',\n\t\t};\n\n\t\tsuper({\n\t\t\taction: options.action,\n\t\t\ttarget: options.target,\n\t\t\tmessage: messages[options.reason] ?? `the element is not actionable (${options.reason}).`,\n\t\t\telementState: options.elementState,\n\t\t\thint: hints[options.reason],\n\t\t\telapsed: options.elapsed,\n\t\t});\n\n\t\tthis.reason = options.reason;\n\t}\n}\n\n/**\n * Error thrown when a network operation fails.\n */\nexport class NetworkError extends BrowsecraftError {\n\toverride readonly name = 'NetworkError';\n\n\tconstructor(options: { action: string; target: string; message: string; elapsed?: number }) {\n\t\tsuper({\n\t\t\taction: options.action,\n\t\t\ttarget: options.target,\n\t\t\tmessage: options.message,\n\t\t\thint: 'Check that the URL pattern is correct and network interception is set up before navigation.',\n\t\t\telapsed: options.elapsed,\n\t\t});\n\t}\n}\n\n/**\n * Error thrown when a timeout occurs.\n */\nexport class TimeoutError extends BrowsecraftError {\n\toverride readonly name = 'TimeoutError';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatElementState(state: ElementState): string {\n\tif (!state.found) return 'Element state: NOT FOUND in DOM';\n\n\tconst lines: string[] = ['Element state:'];\n\tif (state.tagName) lines.push(` Tag: <${state.tagName.toLowerCase()}>`);\n\tif (state.id) lines.push(` Id: #${state.id}`);\n\tif (state.classes) lines.push(` Classes: ${state.classes}`);\n\tif (state.textPreview) lines.push(` Text: \"${state.textPreview}\"`);\n\tif (state.visible !== undefined) lines.push(` Visible: ${state.visible}`);\n\tif (state.enabled !== undefined) lines.push(` Enabled: ${state.enabled}`);\n\tif (state.obscured !== undefined) lines.push(` Obscured: ${state.obscured}`);\n\tif (state.boundingBox) {\n\t\tconst b = state.boundingBox;\n\t\tlines.push(` Position: (${b.x}, ${b.y}) Size: ${b.width}x${b.height}`);\n\t}\n\treturn lines.join('\\n');\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// Actionability checks (like Playwright):\n// - Visible: element has non-zero size, not display:none/visibility:hidden\n// - Enabled: element is not disabled\n// - Stable: element's bounding box hasn't changed between two animation frames\n// - Not obscured: element receives pointer events at its center point\n// ============================================================================\n\nimport type { BiDiSession, NodeRemoteValue, SharedReference } from 'browsecraft-bidi';\nimport type { ElementState } from './errors.js';\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(`Timed out after ${elapsed}ms waiting for: ${description}${errorMsg}`);\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 = 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 (\n\t\t\tstate === 'domcontentloaded' &&\n\t\t\t(readyState === 'interactive' || readyState === 'complete')\n\t\t) {\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' ? 'browsingContext.load' : '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// ============================================================================\n// Actionability Checks\n// These ensure an element is truly ready for interaction.\n// ============================================================================\n\n/** Result of an actionability check */\nexport interface ActionabilityResult {\n\t/** Whether the element is actionable */\n\tactionable: boolean;\n\t/** Why it's not actionable */\n\treason?: 'not-visible' | 'disabled' | 'obscured' | 'zero-size' | 'detached';\n\t/** Full element state snapshot */\n\tstate: ElementState;\n}\n\n/**\n * Check if an element is actionable (visible, enabled, stable, not obscured).\n * This runs entirely in the browser via a single script evaluation for performance.\n */\nexport async function checkActionability(\n\tsession: BiDiSession,\n\tcontextId: string,\n\tref: SharedReference,\n\tchecks: {\n\t\t/** Check visibility (default: true) */\n\t\tvisible?: boolean;\n\t\t/** Check enabled state (default: true for inputs/buttons) */\n\t\tenabled?: boolean;\n\t\t/** Check that nothing obscures the element (default: false — expensive) */\n\t\tnotObscured?: boolean;\n\t} = {},\n): Promise<ActionabilityResult> {\n\tconst doVisible = checks.visible !== false;\n\tconst doEnabled = checks.enabled !== false;\n\tconst doObscured = checks.notObscured === true;\n\n\ttry {\n\t\tconst result = await session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(el, doVisible, doEnabled, doObscured) {\n\t\t\t\t// Check if element is still in the DOM\n\t\t\t\tif (!el.isConnected) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tactionable: false,\n\t\t\t\t\t\treason: 'detached',\n\t\t\t\t\t\tstate: { found: true, visible: false, enabled: false }\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tconst style = window.getComputedStyle(el);\n\t\t\t\tconst rect = el.getBoundingClientRect();\n\t\t\t\tconst tagName = el.tagName || '';\n\t\t\t\tconst textPreview = (el.innerText || el.textContent || '').slice(0, 80).trim();\n\t\t\t\tconst classes = el.className || '';\n\t\t\t\tconst id = el.id || '';\n\n\t\t\t\tconst state = {\n\t\t\t\t\tfound: true,\n\t\t\t\t\ttagName: tagName,\n\t\t\t\t\ttextPreview: textPreview,\n\t\t\t\t\tclasses: typeof classes === 'string' ? classes : '',\n\t\t\t\t\tid: id,\n\t\t\t\t\tboundingBox: {\n\t\t\t\t\t\tx: Math.round(rect.x),\n\t\t\t\t\t\ty: Math.round(rect.y),\n\t\t\t\t\t\twidth: Math.round(rect.width),\n\t\t\t\t\t\theight: Math.round(rect.height)\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Visibility check\n\t\t\t\tif (doVisible) {\n\t\t\t\t\tconst isVisible = style.display !== 'none'\n\t\t\t\t\t\t&& style.visibility !== 'hidden'\n\t\t\t\t\t\t&& style.opacity !== '0'\n\t\t\t\t\t\t&& rect.width > 0\n\t\t\t\t\t\t&& rect.height > 0;\n\n\t\t\t\t\tstate.visible = isVisible;\n\n\t\t\t\t\tif (!isVisible) {\n\t\t\t\t\t\tif (rect.width === 0 || rect.height === 0) {\n\t\t\t\t\t\t\treturn { actionable: false, reason: 'zero-size', state: state };\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { actionable: false, reason: 'not-visible', state: state };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Enabled check (only for form elements)\n\t\t\t\tif (doEnabled) {\n\t\t\t\t\tconst formTags = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA', 'FIELDSET'];\n\t\t\t\t\tconst isFormElement = formTags.includes(tagName);\n\t\t\t\t\tconst isDisabled = isFormElement && el.disabled === true;\n\t\t\t\t\tstate.enabled = !isDisabled;\n\n\t\t\t\t\tif (isDisabled) {\n\t\t\t\t\t\treturn { actionable: false, reason: 'disabled', state: state };\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Obscured check (elementFromPoint)\n\t\t\t\tif (doObscured) {\n\t\t\t\t\tconst cx = rect.x + rect.width / 2;\n\t\t\t\t\tconst cy = rect.y + rect.height / 2;\n\t\t\t\t\tconst topEl = document.elementFromPoint(cx, cy);\n\n\t\t\t\t\tif (topEl && topEl !== el && !el.contains(topEl)) {\n\t\t\t\t\t\tstate.obscured = true;\n\t\t\t\t\t\tstate.obscuredBy = '<' + topEl.tagName.toLowerCase()\n\t\t\t\t\t\t\t+ (topEl.id ? '#' + topEl.id : '')\n\t\t\t\t\t\t\t+ (topEl.className ? '.' + topEl.className.split(' ').join('.') : '')\n\t\t\t\t\t\t\t+ '>';\n\t\t\t\t\t\treturn { actionable: false, reason: 'obscured', state: state };\n\t\t\t\t\t}\n\t\t\t\t\tstate.obscured = false;\n\t\t\t\t}\n\n\t\t\t\tstate.visible = true;\n\t\t\t\tstate.enabled = true;\n\t\t\t\treturn { actionable: true, state: state };\n\t\t\t}`,\n\t\t\ttarget: { context: contextId },\n\t\t\targuments: [\n\t\t\t\tref,\n\t\t\t\t{ type: 'boolean', value: doVisible },\n\t\t\t\t{ type: 'boolean', value: doEnabled },\n\t\t\t\t{ type: 'boolean', value: doObscured },\n\t\t\t],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'object') {\n\t\t\treturn deserializeActionabilityResult(result.result.value);\n\t\t}\n\n\t\t// Fallback if script returned unexpected type\n\t\treturn {\n\t\t\tactionable: true,\n\t\t\tstate: { found: true, visible: true, enabled: true },\n\t\t};\n\t} catch {\n\t\t// If the script fails entirely, the element may be detached\n\t\treturn {\n\t\t\tactionable: false,\n\t\t\treason: 'detached',\n\t\t\tstate: { found: true, visible: false, enabled: false },\n\t\t};\n\t}\n}\n\n/**\n * Wait for an element to become actionable (visible + enabled).\n * Returns the final actionability state.\n */\nexport async function waitForActionable(\n\tsession: BiDiSession,\n\tcontextId: string,\n\tref: SharedReference,\n\tdescription: string,\n\toptions: WaitOptions,\n\tchecks?: {\n\t\tvisible?: boolean;\n\t\tenabled?: boolean;\n\t\tnotObscured?: boolean;\n\t},\n): Promise<ActionabilityResult> {\n\tlet lastResult: ActionabilityResult | null = null;\n\n\ttry {\n\t\treturn await waitFor(\n\t\t\t`${description} to be actionable`,\n\t\t\tasync () => {\n\t\t\t\tconst result = await checkActionability(session, contextId, ref, checks);\n\t\t\t\tlastResult = result;\n\t\t\t\treturn result.actionable ? result : null;\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t} catch {\n\t\t// Return the last known state for error reporting\n\t\treturn (\n\t\t\tlastResult ?? {\n\t\t\t\tactionable: false,\n\t\t\t\treason: 'not-visible',\n\t\t\t\tstate: { found: true },\n\t\t\t}\n\t\t);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Deserialize the BiDi object format [[key, {type, value}], ...] into a plain object.\n */\nfunction deserializeActionabilityResult(value: unknown): ActionabilityResult {\n\tif (!Array.isArray(value)) {\n\t\treturn { actionable: true, state: { found: true } };\n\t}\n\n\tconst map = new Map<string, unknown>();\n\tfor (const entry of value as [string, unknown][]) {\n\t\tif (Array.isArray(entry) && entry.length === 2) {\n\t\t\tconst val = entry[1] as { type?: string; value?: unknown };\n\t\t\tmap.set(entry[0], val && typeof val === 'object' && 'value' in val ? val.value : val);\n\t\t}\n\t}\n\n\tconst stateRaw = map.get('state');\n\tlet state: ElementState = { found: true };\n\n\tif (Array.isArray(stateRaw)) {\n\t\tconst stateMap = new Map<string, unknown>();\n\t\tfor (const entry of stateRaw as [string, unknown][]) {\n\t\t\tif (Array.isArray(entry) && entry.length === 2) {\n\t\t\t\tconst val = entry[1] as { type?: string; value?: unknown };\n\t\t\t\tstateMap.set(entry[0], val && typeof val === 'object' && 'value' in val ? val.value : val);\n\t\t\t}\n\t\t}\n\n\t\t// Parse bounding box\n\t\tlet boundingBox: ElementState['boundingBox'];\n\t\tconst bbRaw = stateMap.get('boundingBox');\n\t\tif (Array.isArray(bbRaw)) {\n\t\t\tconst bbMap = new Map<string, unknown>();\n\t\t\tfor (const entry of bbRaw as [string, unknown][]) {\n\t\t\t\tif (Array.isArray(entry) && entry.length === 2) {\n\t\t\t\t\tconst val = entry[1] as { type?: string; value?: unknown };\n\t\t\t\t\tbbMap.set(entry[0], val && typeof val === 'object' && 'value' in val ? val.value : val);\n\t\t\t\t}\n\t\t\t}\n\t\t\tboundingBox = {\n\t\t\t\tx: (bbMap.get('x') as number) ?? 0,\n\t\t\t\ty: (bbMap.get('y') as number) ?? 0,\n\t\t\t\twidth: (bbMap.get('width') as number) ?? 0,\n\t\t\t\theight: (bbMap.get('height') as number) ?? 0,\n\t\t\t};\n\t\t}\n\n\t\tstate = {\n\t\t\tfound: true,\n\t\t\tvisible: stateMap.get('visible') as boolean | undefined,\n\t\t\tenabled: stateMap.get('enabled') as boolean | undefined,\n\t\t\ttagName: stateMap.get('tagName') as string | undefined,\n\t\t\ttextPreview: stateMap.get('textPreview') as string | undefined,\n\t\t\tclasses: stateMap.get('classes') as string | undefined,\n\t\t\tid: stateMap.get('id') as string | undefined,\n\t\t\tobscured: stateMap.get('obscured') as boolean | undefined,\n\t\t\tobscuredBy: stateMap.get('obscuredBy') as string | undefined,\n\t\t\tboundingBox,\n\t\t};\n\t}\n\n\treturn {\n\t\tactionable: (map.get('actionable') as boolean) ?? true,\n\t\treason: map.get('reason') as ActionabilityResult['reason'],\n\t\tstate,\n\t};\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 { ElementNotFoundError } from './errors.js';\nimport { type WaitOptions, waitFor } from './wait.js';\n\n/**\n * Elements that only appear in <head> and should never be returned\n * as visible/interactable elements. BiDi innerText locator can match\n * <title> (e.g., searching for \"Example Domain\" matches <title>Example Domain</title>),\n * which is always invisible and non-interactable.\n */\nconst HEAD_ONLY_ELEMENTS = new Set([\n\t'title',\n\t'meta',\n\t'link',\n\t'style',\n\t'base',\n\t'head',\n\t'noscript', // can appear in head too\n]);\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\tconst description = describeTarget(target);\n\tconst startTime = Date.now();\n\n\ttry {\n\t\treturn await waitFor(\n\t\t\tdescription,\n\t\t\tasync () => {\n\t\t\t\t// Try each strategy in order\n\t\t\t\tconst strategies = buildStrategies(opts);\n\n\t\t\t\tfor (const { locator, strategy, isLabelLookup } of strategies) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await session.browsingContext.locateNodes({\n\t\t\t\t\t\t\tcontext: contextId,\n\t\t\t\t\t\t\tlocator,\n\t\t\t\t\t\t\tmaxNodeCount: (opts.index ?? 0) + 10, // fetch extra for label resolution\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Filter out <head>-only elements (title, meta, style, etc.)\n\t\t\t\t\t\t// BiDi innerText locator can match <title> which is never interactable\n\t\t\t\t\t\tconst nodes = result.nodes.filter(\n\t\t\t\t\t\t\t(n) => !HEAD_ONLY_ELEMENTS.has(n.value?.localName ?? ''),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (nodes.length > 0) {\n\t\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\t// and resolve their `for` attribute to the associated input\n\t\t\t\t\t\t\tif (isLabelLookup) {\n\t\t\t\t\t\t\t\tconst resolved = await resolveLabelsToInputs(session, contextId, nodes);\n\t\t\t\t\t\t\t\tif (resolved) {\n\t\t\t\t\t\t\t\t\treturn { node: resolved, strategy };\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst nodeIndex = opts.index ?? 0;\n\t\t\t\t\t\t\tconst node = nodes[nodeIndex];\n\t\t\t\t\t\t\tif (node) {\n\t\t\t\t\t\t\t\treturn { node, strategy };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\n\t\t\t\treturn null; // Not found yet -- waitFor will retry\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t} catch (err) {\n\t\tconst elapsed = Date.now() - startTime;\n\n\t\t// Try to find similar elements for suggestions\n\t\tconst suggestions = await findSimilarElements(session, contextId, target);\n\n\t\tthrow new ElementNotFoundError({\n\t\t\taction: 'find',\n\t\t\ttarget: typeof target === 'string' ? target : description,\n\t\t\telapsed,\n\t\t\tsuggestions,\n\t\t});\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\tconst nodes = result.nodes.filter((n) => !HEAD_ONLY_ELEMENTS.has(n.value?.localName ?? ''));\n\n\t\t\tif (nodes.length > 0) {\n\t\t\t\treturn nodes.map((node) => ({ node, strategy }));\n\t\t\t}\n\t\t} catch {}\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(\n\topts: LocatorOptions,\n): 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: data-testid -- maybe it's a test ID\n\t\tstrategies.push({\n\t\t\tlocator: {\n\t\t\t\ttype: 'css',\n\t\t\t\tvalue: `[data-testid=\"${name}\"], [data-test=\"${name}\"], [data-test-id=\"${name}\"]`,\n\t\t\t},\n\t\t\tstrategy: `data-testid(\"${name}\")`,\n\t\t});\n\n\t\t// Strategy 4: 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}\n\n\treturn null;\n}\n\n/**\n * Try to find similar elements on the page to provide suggestions\n * when an element is not found.\n */\nasync function findSimilarElements(\n\tsession: BiDiSession,\n\tcontextId: string,\n\ttarget: ElementTarget,\n): Promise<string[]> {\n\tconst searchText =\n\t\ttypeof target === 'string' ? target : (target.name ?? target.text ?? target.label ?? '');\n\tif (!searchText) return [];\n\n\ttry {\n\t\tconst result = await session.script.callFunction({\n\t\t\tfunctionDeclaration: `function(searchText) {\n\t\t\t\tconst suggestions = [];\n\t\t\t\tconst lower = searchText.toLowerCase();\n\n\t\t\t\t// Look at all interactive elements and visible text\n\t\t\t\tconst interactiveSelectors = 'button, a, input, select, textarea, [role=\"button\"], [role=\"link\"], [role=\"tab\"], [role=\"menuitem\"]';\n\t\t\t\tconst elements = document.querySelectorAll(interactiveSelectors);\n\n\t\t\t\tfor (const el of elements) {\n\t\t\t\t\tconst text = (el.innerText || el.textContent || '').trim();\n\t\t\t\t\tconst ariaLabel = el.getAttribute('aria-label') || '';\n\t\t\t\t\tconst placeholder = el.getAttribute('placeholder') || '';\n\t\t\t\t\tconst value = el.getAttribute('value') || '';\n\t\t\t\t\tconst title = el.getAttribute('title') || '';\n\n\t\t\t\t\tconst candidates = [text, ariaLabel, placeholder, value, title].filter(Boolean);\n\t\t\t\t\tfor (const c of candidates) {\n\t\t\t\t\t\tif (c.toLowerCase().includes(lower.slice(0, 3)) || lower.includes(c.toLowerCase().slice(0, 3))) {\n\t\t\t\t\t\t\tconst tag = el.tagName.toLowerCase();\n\t\t\t\t\t\t\tconst desc = c.length > 40 ? c.slice(0, 40) + '...' : c;\n\t\t\t\t\t\t\tsuggestions.push('<' + tag + '> \"' + desc + '\"');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (suggestions.length >= 5) break;\n\t\t\t\t}\n\n\t\t\t\treturn suggestions;\n\t\t\t}`,\n\t\t\ttarget: { context: contextId },\n\t\t\targuments: [{ type: 'string', value: searchText }],\n\t\t\tawaitPromise: false,\n\t\t});\n\n\t\tif (result.type === 'success' && result.result?.type === 'array') {\n\t\t\tconst arr = result.result.value as Array<{ type: string; value: string }>;\n\t\t\treturn arr.filter((item) => item?.type === 'string').map((item) => item.value);\n\t\t}\n\t} catch {}\n\n\treturn [];\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\tNetworkSetCookieHeader,\n\tNodeRemoteValue,\n\tScriptEvaluateResult,\n\tSharedReference,\n\tStorageCookie,\n} from 'browsecraft-bidi';\nimport type { BrowsecraftConfig } from './config.js';\nimport { ElementNotActionableError } from './errors.js';\nimport {\n\ttype ElementTarget,\n\ttype LocatedElement,\n\tlocateAllElements,\n\tlocateElement,\n} from './locator.js';\nimport {\n\ttype ActionabilityResult,\n\ttype WaitOptions,\n\twaitFor,\n\twaitForActionable,\n\twaitForLoadState,\n} from './wait.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/** Request info passed to intercept handlers */\nexport interface InterceptedRequest {\n\t/** The full URL of the request */\n\turl: string;\n\t/** HTTP method (GET, POST, etc.) */\n\tmethod: string;\n\t/** Request headers */\n\theaders: Record<string, 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.ensureActionable(located, 'click', target, { timeout });\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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\tawait this.ensureActionable(located, 'fill', target, { 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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\tawait this.ensureActionable(located, 'type', target, { 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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : target;\n\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\tawait this.ensureActionable(located, 'select', target, { timeout });\n\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\n\t\tawait this.ensureActionable(located, 'check', target, { timeout });\n\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 =\n\t\t\tresult.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\n\t\tawait this.ensureActionable(located, 'uncheck', target, { timeout });\n\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 =\n\t\t\tresult.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\n\t\tawait this.ensureActionable(located, 'hover', target, { timeout });\n\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:\n\t\t\t\t'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\t{\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\tid: 'mouse',\n\t\t\t\t\tparameters: { pointerType: 'mouse' },\n\t\t\t\t\tactions: [{ 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<\n\t\tStorageCookie[]\n\t> {\n\t\tconst result = await this.session.storage.getCookies({\n\t\t\tfilter: filter\n\t\t\t\t? {\n\t\t\t\t\t\tname: filter.name,\n\t\t\t\t\t\tdomain: filter.domain,\n\t\t\t\t\t\tpath: filter.path,\n\t\t\t\t\t}\n\t\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(\n\t\tcookies: Array<{\n\t\t\tname: string;\n\t\t\tvalue: string;\n\t\t\tdomain?: string;\n\t\t\tpath?: string;\n\t\t\thttpOnly?: boolean;\n\t\t\tsecure?: boolean;\n\t\t\tsameSite?: 'strict' | 'lax' | 'none';\n\t\t\texpiry?: number;\n\t\t}>,\n\t): 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\t? {\n\t\t\t\t\t\tname: filter.name,\n\t\t\t\t\t\tdomain: filter.domain,\n\t\t\t\t\t\tpath: filter.path,\n\t\t\t\t\t}\n\t\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' ? `(${expression.toString()})()` : 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(['network.beforeRequestSent'], [this.contextId]);\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\n\t\tawait this.ensureActionable(located, 'tap', target, { timeout });\n\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:\n\t\t\t\t'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\t{\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\tid: 'touch',\n\t\t\t\t\tparameters: { pointerType: 'touch' },\n\t\t\t\t\tactions: [\n\t\t\t\t\t\t{ type: 'pointerMove', x: pos.x, y: pos.y, origin: 'viewport' },\n\t\t\t\t\t\t{ type: 'pointerDown', button: 0 },\n\t\t\t\t\t\t{ type: 'pointerUp', button: 0 },\n\t\t\t\t\t] as any,\n\t\t\t\t},\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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\tawait this.ensureActionable(located, 'focus', target, { timeout, enabled: false });\n\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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : 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 =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : 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(\n\t\ttarget: ElementTarget,\n\t\tvalues: string | string[],\n\t\toptions?: FillOptions,\n\t): Promise<void> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst resolvedTarget: ElementTarget =\n\t\t\ttypeof target === 'string' ? { label: target, name: target } : target;\n\t\tconst located = await locateElement(this.session, this.contextId, resolvedTarget, { timeout });\n\n\t\tawait this.ensureActionable(located, 'selectOption', target, { timeout });\n\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: [\n\t\t\t\tref,\n\t\t\t\t{ type: 'array', value: valuesArray.map((v) => ({ type: 'string' as const, value: v })) },\n\t\t\t],\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(\n\t\tsource: ElementTarget,\n\t\tdest: ElementTarget,\n\t\toptions?: { timeout?: number },\n\t): 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\t{\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\tid: 'mouse',\n\t\t\t\t\tparameters: { pointerType: 'mouse' },\n\t\t\t\t\tactions: [\n\t\t\t\t\t\t{ type: 'pointerMove', x: sourcePos.x, y: sourcePos.y, origin: 'viewport' },\n\t\t\t\t\t\t{ type: 'pointerDown', button: 0 },\n\t\t\t\t\t\t{ type: 'pointerMove', x: destPos.x, y: destPos.y, origin: 'viewport', duration: 300 },\n\t\t\t\t\t\t{ type: 'pointerUp', button: 0 },\n\t\t\t\t\t] as any,\n\t\t\t\t},\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(\n\t\ttarget: ElementTarget,\n\t\toptions?: { timeout?: number; state?: 'attached' | 'visible' | 'hidden' },\n\t): 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 =\n\t\t\t\t\t\t\tresult.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 =\n\t\t\t\t\t\tresult.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' ? `(${expression.toString()})()` : 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// English API aliases — reads like instructions to a person\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Navigate to a URL. English-friendly alias for goto().\n\t *\n\t * ```ts\n\t * await page.go('https://example.com');\n\t * await page.go('/login');\n\t * ```\n\t */\n\tasync go(url: string, options?: GotoOptions): Promise<void> {\n\t\treturn this.goto(url, options);\n\t}\n\n\t/**\n\t * Assert that an element with the given text is visible on the page.\n\t * Returns the ElementHandle for further assertions.\n\t *\n\t * ```ts\n\t * await page.see('Welcome back!');\n\t * await page.see('Products');\n\t * await page.see({ role: 'heading', name: 'Dashboard' });\n\t * ```\n\t */\n\tasync see(target: ElementTarget, options?: { timeout?: number }): Promise<ElementHandle> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst startTime = Date.now();\n\n\t\t// Step 1: Locate the element (auto-waits for it to exist in DOM)\n\t\tconst located = await locateElement(this.session, this.contextId, target, { timeout });\n\t\tconst ref = this.getSharedRef(located.node);\n\n\t\t// Step 2: Poll until the element is visible (handles CSS transitions, lazy rendering, etc.)\n\t\tconst elapsed = Date.now() - startTime;\n\t\tconst remaining = Math.max(timeout - elapsed, 5000);\n\t\tawait waitFor(\n\t\t\t`${describeTarget(target)} to be visible`,\n\t\t\tasync () => {\n\t\t\t\ttry {\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\tif (\n\t\t\t\t\t\tresult.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\t) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\treturn null;\n\t\t\t\t} catch {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ timeout: remaining },\n\t\t);\n\n\t\treturn new ElementHandle(this, target);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Network interception & observation\n\t// -----------------------------------------------------------------------\n\n\t/**\n\t * Intercept network requests matching a pattern. Calls your handler\n\t * for each matching request, letting you modify or respond to it.\n\t *\n\t * ```ts\n\t * await page.intercept('POST /api/login', async (request) => {\n\t * // Modify request, or provide a response\n\t * return { status: 200, body: { token: 'abc' } };\n\t * });\n\t * ```\n\t */\n\tasync intercept(\n\t\tpattern: string,\n\t\thandler: (\n\t\t\trequest: InterceptedRequest,\n\t\t) => Promise<MockResponse | undefined> | MockResponse | undefined,\n\t): Promise<void> {\n\t\tconst { method, urlPattern } = parseMockPattern(pattern);\n\n\t\tawait this.session.subscribe(['network.beforeRequestSent'], [this.contextId]);\n\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\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: {\n\t\t\t\t\trequest: string;\n\t\t\t\t\tmethod: string;\n\t\t\t\t\turl: string;\n\t\t\t\t\theaders: Array<{ name: string; value: { type: string; value: string } }>;\n\t\t\t\t};\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\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\tconst reqInfo: InterceptedRequest = {\n\t\t\t\turl: params.request.url,\n\t\t\t\tmethod: params.request.method,\n\t\t\t\theaders: Object.fromEntries(params.request.headers.map((h) => [h.name, h.value.value])),\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tconst response = await handler(reqInfo);\n\t\t\t\tif (response) {\n\t\t\t\t\tconst headers = buildMockHeaders(response);\n\t\t\t\t\tconst body = buildMockBody(response);\n\t\t\t\t\tawait this.session.network.provideResponse({\n\t\t\t\t\t\trequest: params.request.request,\n\t\t\t\t\t\tstatusCode: response.status ?? 200,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tbody: body ? { type: 'string', value: body } : undefined,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tawait this.session.network.continueRequest({ request: params.request.request });\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tawait this.session.network.continueRequest({ request: params.request.request });\n\t\t\t}\n\t\t});\n\t\tthis.eventCleanups.push(unsubscribe);\n\t}\n\n\t/**\n\t * Wait for a network response matching a URL pattern.\n\t *\n\t * ```ts\n\t * const response = await page.waitForResponse('/api/users');\n\t * console.log(response.status); // 200\n\t * ```\n\t */\n\tasync waitForResponse(\n\t\turlPattern: string | RegExp,\n\t\toptions?: { timeout?: number; method?: string },\n\t): Promise<{ url: string; status: number; method: string }> {\n\t\tconst timeout = options?.timeout ?? this.config.timeout;\n\t\tconst method = options?.method?.toUpperCase();\n\n\t\tawait this.session.subscribe(['network.responseCompleted'], [this.contextId]);\n\n\t\ttry {\n\t\t\tconst event = await this.session.waitForEvent(\n\t\t\t\t'network.responseCompleted',\n\t\t\t\t(e) => {\n\t\t\t\t\tconst params = e.params as {\n\t\t\t\t\t\tcontext: string;\n\t\t\t\t\t\trequest: { method: string; url: string };\n\t\t\t\t\t\tresponse: { status: number };\n\t\t\t\t\t};\n\t\t\t\t\tif (params.context !== this.contextId) return false;\n\t\t\t\t\tif (method && params.request.method.toUpperCase() !== method) return false;\n\n\t\t\t\t\tconst url = params.request.url;\n\t\t\t\t\tif (typeof urlPattern === 'string') {\n\t\t\t\t\t\treturn url.includes(urlPattern);\n\t\t\t\t\t}\n\t\t\t\t\treturn urlPattern.test(url);\n\t\t\t\t},\n\t\t\t\ttimeout,\n\t\t\t);\n\n\t\t\tconst params = event.params as {\n\t\t\t\trequest: { method: string; url: string };\n\t\t\t\tresponse: { status: number };\n\t\t\t};\n\t\t\treturn {\n\t\t\t\turl: params.request.url,\n\t\t\t\tstatus: params.response.status,\n\t\t\t\tmethod: params.request.method,\n\t\t\t};\n\t\t} finally {\n\t\t\tawait this.session\n\t\t\t\t.unsubscribe(['network.responseCompleted'], [this.contextId])\n\t\t\t\t.catch(() => {});\n\t\t}\n\t}\n\n\t/**\n\t * Block network requests matching URL patterns (e.g., ads, analytics).\n\t *\n\t * ```ts\n\t * await page.blockRequests(['*.google-analytics.com*', '*.doubleclick.net*']);\n\t * await page.blockRequests(['/api/telemetry']);\n\t * ```\n\t */\n\tasync blockRequests(patterns: string[]): Promise<void> {\n\t\tawait this.session.subscribe(['network.beforeRequestSent'], [this.contextId]);\n\n\t\tfor (const pattern of patterns) {\n\t\t\tconst urlPattern = pattern.startsWith('http')\n\t\t\t\t? { type: 'string' as const, pattern }\n\t\t\t\t: { type: 'pattern' as const, pathname: pattern };\n\n\t\t\tconst result = await this.session.network.addIntercept({\n\t\t\t\tphases: ['beforeRequestSent'],\n\t\t\t\turlPatterns: [urlPattern],\n\t\t\t\tcontexts: [this.contextId],\n\t\t\t});\n\t\t\tthis.interceptIds.push(result.intercept);\n\n\t\t\tconst unsubscribe = this.session.on('network.beforeRequestSent', async (event) => {\n\t\t\t\tconst params = event.params as {\n\t\t\t\t\tcontext: string;\n\t\t\t\t\trequest: { request: string; url: string };\n\t\t\t\t\tisBlocked: boolean;\n\t\t\t\t\tintercepts?: string[];\n\t\t\t\t};\n\n\t\t\t\tif (!params.isBlocked || params.context !== this.contextId) return;\n\t\t\t\tif (!params.intercepts?.includes(result.intercept)) return;\n\n\t\t\t\t// Fail the request (block it)\n\t\t\t\tawait this.session.network.failRequest({ request: params.request.request });\n\t\t\t});\n\t\t\tthis.eventCleanups.push(unsubscribe);\n\t\t}\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\t\t\t[];\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/**\n\t * Ensure an element is actionable (visible + enabled) before interacting.\n\t * Throws a rich ElementNotActionableError if it's not ready within the timeout.\n\t */\n\tprivate async ensureActionable(\n\t\tlocated: LocatedElement,\n\t\taction: string,\n\t\ttarget: ElementTarget,\n\t\toptions: { timeout: number; enabled?: boolean },\n\t): Promise<void> {\n\t\tconst ref = this.getSharedRef(located.node);\n\t\tconst targetDesc = typeof target === 'string' ? target : describeTarget(target);\n\n\t\tconst result = await waitForActionable(\n\t\t\tthis.session,\n\t\t\tthis.contextId,\n\t\t\tref,\n\t\t\ttargetDesc,\n\t\t\t{ timeout: Math.min(options.timeout, 5000) },\n\t\t\t{\n\t\t\t\tvisible: true,\n\t\t\t\tenabled: options.enabled !== false,\n\t\t\t},\n\t\t);\n\n\t\tif (!result.actionable && result.reason) {\n\t\t\tthrow new ElementNotActionableError({\n\t\t\t\taction,\n\t\t\t\ttarget: targetDesc,\n\t\t\t\treason: result.reason,\n\t\t\t\telementState: result.state,\n\t\t\t\telapsed: options.timeout,\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Resolve a relative URL against the baseURL */\n\tprivate resolveURL(url: string): string {\n\t\tif (\n\t\t\turl.startsWith('http://') ||\n\t\t\turl.startsWith('https://') ||\n\t\t\turl.startsWith('about:') ||\n\t\t\turl.startsWith('data:')\n\t\t) {\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 =\n\t\t\t\t\ttypeof xVal === 'object' && xVal !== null && 'value' in xVal\n\t\t\t\t\t\t? (xVal as { value: number }).value\n\t\t\t\t\t\t: null;\n\t\t\t\tconst y =\n\t\t\t\t\ttypeof yVal === 'object' && yVal !== null && 'value' in yVal\n\t\t\t\t\t\t? (yVal as { value: number }).value\n\t\t\t\t\t\t: 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\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(\n\t\tlocated: LocatedElement,\n\t\toptions?: ClickOptions,\n\t): 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':\n\t\t\t\treturn undefined;\n\t\t\tcase 'null':\n\t\t\t\treturn null;\n\t\t\tcase 'string':\n\t\t\t\treturn 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':\n\t\t\t\treturn v.value;\n\t\t\tcase 'bigint':\n\t\t\t\treturn 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 (\n\t\t\t\tresult.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\t);\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 (\n\t\t\t\tresult.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\t);\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 (\n\t\t\t\tresult.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\t);\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\n\t\t\t\t\t\t\t? (v as { value: number }).value\n\t\t\t\t\t\t\t: 0;\n\t\t\t\t\t};\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: extract('x'),\n\t\t\t\t\t\ty: extract('y'),\n\t\t\t\t\t\twidth: extract('width'),\n\t\t\t\t\t\theight: extract('height'),\n\t\t\t\t\t};\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:\n\t\t\t\t'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(this.page.session, this.page.contextId, this.target, {\n\t\t\ttimeout: 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/** Human-readable description of a target (for error messages) */\nfunction describeTarget(target: ElementTarget): string {\n\tif (typeof target === 'string') return target;\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\treturn `[${parts.join(', ')}]`;\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): {\n\tmethod: string | null;\n\turlPattern:\n\t\t| { type: 'string'; pattern: string }\n\t\t| { type: 'pattern'; pathname?: string; protocol?: string; hostname?: string };\n} {\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(\n\tresponse: MockResponse,\n): 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 { type BrowsecraftConfig, type UserConfig, resolveConfig } from './config.js';\nimport { Page } from './page.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\tconst browser = new Browser(session, config);\n\n\t\treturn browser;\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 * If an idle about:blank tab exists (e.g., Chrome's initial tab), it is\n\t * reused instead of creating a new one. This prevents the \"double window\"\n\t * issue in headed mode.\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\tlet contextId: string;\n\n\t\t// Try to reuse the initial about:blank tab to avoid double windows in headed mode\n\t\tconst reused = await this.tryReuseInitialTab();\n\t\tif (reused) {\n\t\t\tcontextId = reused;\n\t\t} else {\n\t\t\tconst result = await this.session.browsingContext.create({ type: 'tab' });\n\t\t\tcontextId = result.context;\n\t\t}\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. Pages will share cookies/storage. ${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\t/**\n\t * Try to find and reuse an existing about:blank tab (Chrome opens one on startup).\n\t * Returns the context ID if found, or null if no idle tab exists.\n\t * @internal\n\t */\n\tprivate async tryReuseInitialTab(): Promise<string | null> {\n\t\ttry {\n\t\t\tconst tree = await this.session.browsingContext.getTree();\n\t\t\tconst contexts = tree.contexts ?? [];\n\t\t\tfor (const ctx of contexts) {\n\t\t\t\t// Only reuse tabs we haven't already wrapped as a Page\n\t\t\t\tconst alreadyTracked = this.pages.some((p) => (p as any).contextId === ctx.context);\n\t\t\t\tif (!alreadyTracked && ctx.url === 'about:blank') {\n\t\t\t\t\treturn ctx.context;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// getTree not supported — fall through to create\n\t\t}\n\t\treturn null;\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\n\t\t\t\t.send('browser.removeUserContext', {\n\t\t\t\t\tuserContext: this.userContext,\n\t\t\t\t})\n\t\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 { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { Browser, type BrowserContext } from './browser.js';\nimport { resolveConfig } from './config.js';\nimport type { UserConfig } from './config.js';\nimport type { Page } from './page.js';\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(\n\ttitle: string,\n\toptions: TestOptions,\n\tfn: (fixtures: TestFixtures) => Promise<void>,\n): 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(title: string, fn: (fixtures: TestFixtures) => Promise<void>): 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(title: string, fn: (fixtures: TestFixtures) => Promise<void>): 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(\n\t\t\t\t() => undefined,\n\t\t\t);\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(\n\t\t\t\t() => undefined,\n\t\t\t);\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(suitePath: string[], fixtures: TestFixtures): Promise<void> {\n\tconst applicableAfterAll = hooks.afterAll.filter((h) => isHookApplicable(h.suitePath, suitePath));\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(\n\tpage: Page,\n\ttestCase: TestCase,\n\toutputDir: string,\n): 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"]}