export type SnapshotItem = { uid: string; role: string; tag: string; name: string; bbox?: { x: number; y: number; w: number; h: number; }; selector?: string; attrs?: Record; /** Set by the iframe snapshot script: "main" or frame index string */ origin?: string; }; export type SnapshotFilterOpts = { compact?: boolean; limit?: number; /** Only include elements whose bbox.y is within the viewport */ viewportOnly?: boolean; /** Viewport height in px (required when viewportOnly is true for effective filtering) */ viewportHeight?: number; /** Filter by attribute: "role=", "tag=", or "name=" */ filter?: string; /** Return only the element matching this exact uid */ uid?: string; }; /** Extract optional string param or return undefined */ export declare const optStr: (p: Record, k: string) => string | undefined; /** Extract optional number param or return undefined */ export declare const optNum: (p: Record, k: string) => number | undefined; /** Extract optional boolean param or return undefined */ export declare const optBool: (p: Record, k: string) => boolean | undefined; /** Extract required string param or throw INVALID_ARG */ export declare function reqStr(p: Record, k: string): string; /** * If the given string looks like a cloak uid (e.g. "u7", "u123"), convert it * to a CSS selector targeting the `data-cloak-uid` attribute so it can be * passed directly to Playwright locators. Otherwise pass through unchanged. */ export declare function resolveUid(sel: string): string; /** * Post-process a snapshot result: apply compact (strip bbox/selector), viewportOnly, * filter by role/tag/name, uid, and/or limit. * Filters are applied in order: compact → viewportOnly → filter → uid → limit * @returns The filtered items array. */ export declare function filterSnapshot(snapshot: { items: SnapshotItem[]; url: string; title: string; }, opts: SnapshotFilterOpts): SnapshotItem[]; /** * In-page script that tags interactive elements with `data-cloak-uid` and * returns a flat snapshot of visible elements: uid, role, tag, name, attrs, * bounding box, and selector. * * Used by both `page.snapshot` and `maybeSnapshot` (after-action snapshots) * to keep element tagging logic in a single definition. */ export declare const SNAPSHOT_TAGGER_SCRIPT = "(() => {\n const TAGS = ['a','button','input','textarea','select','label','summary','details','option','[role=button]','[role=link]','[role=textbox]','[role=combobox]','[role=checkbox]','[role=radio]','[role=tab]','[role=menuitem]','[role=switch]','[role=slider]'];\n const sel = TAGS.join(',');\n const els = Array.from(document.querySelectorAll(sel));\n let counter = 0;\n const items = [];\n for (const el of els) {\n counter += 1;\n const uid = 'u' + counter;\n el.setAttribute('data-cloak-uid', uid);\n const tag = el.tagName.toLowerCase();\n const role = el.getAttribute('role') || tag;\n let name = (el.getAttribute('aria-label') || el.getAttribute('title') || el.getAttribute('alt') || el.textContent || el.getAttribute('placeholder') || el.getAttribute('value') || '').trim();\n if (name.length > 120) name = name.slice(0, 120) + '\u2026';\n const rect = el.getBoundingClientRect();\n const visible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0;\n if (!visible) continue;\n items.push({\n uid, role, tag, name,\n attrs: {\n id: el.id || null,\n name: el.getAttribute('name') || null,\n type: el.getAttribute('type') || null,\n href: el.getAttribute('href') || null,\n placeholder: el.getAttribute('placeholder') || null,\n value: ('value' in el && el.value) ? String(el.value).slice(0, 200) : null,\n disabled: el.hasAttribute('disabled') || el.getAttribute('aria-disabled') === 'true',\n checked: 'checked' in el ? !!el.checked : (el.getAttribute('aria-checked') === 'true'),\n },\n bbox: { x: Math.round(rect.x), y: Math.round(rect.y), w: Math.round(rect.width), h: Math.round(rect.height) },\n selector: '[data-cloak-uid=\"' + uid + '\"]',\n });\n }\n return { items, url: location.href, title: document.title };\n})()"; /** * In-page polling script for DOM stability detection (used by wait --stable). * Playwright's waitForFunction evaluates this body repeatedly. * * - First call: sets up a MutationObserver on , records last mutation timestamp. * - Subsequent calls: checks if the quiet period (arg) has elapsed since the last mutation. * - Returns `{ stable: true, mutations: }` when stable, `false` to keep polling. */ export declare const WAIT_STABLE_SCRIPT = "\n if (!window.__cloakStable) {\n window.__cloakStable = { lastMutation: Date.now(), mutationCount: 0 };\n const obs = new MutationObserver(() => {\n window.__cloakStable.lastMutation = Date.now();\n window.__cloakStable.mutationCount++;\n });\n try {\n obs.observe(document.documentElement, {\n childList: true, subtree: true, attributes: true, characterData: true,\n });\n } catch (e) {\n return { stable: false, reason: String(e) };\n }\n }\n const quietMs = Math.min(Math.max(Number(arg) || 500, 100), 5000);\n const elapsed = Date.now() - window.__cloakStable.lastMutation;\n return elapsed >= quietMs\n ? { stable: true, mutations: window.__cloakStable.mutationCount }\n : false;\n"; /** * In-page script that tags interactive + content elements within the main document * AND all same-origin iframes with `data-cloak-uid`, then returns a flat snapshot * of visible elements. Each element includes an `origin` field set to `"main"` or * the iframe's index as a string for disambiguation. */ export declare const SNAPSHOT_IFRAME_SCRIPT = "(() => {\n const TAGS = ['a','button','input','textarea','select','label','summary','details','option','[role=button]','[role=link]','[role=textbox]','[role=combobox]','[role=checkbox]','[role=radio]','[role=tab]','[role=menuitem]','[role=switch]','[role=slider]'];\n const sel = TAGS.join(',');\n let counter = 0;\n const items = [];\n function scan(root, origin) {\n const els = Array.from(root.querySelectorAll(sel));\n for (const el of els) {\n counter += 1;\n const uid = 'u' + counter;\n el.setAttribute('data-cloak-uid', uid);\n const tag = el.tagName.toLowerCase();\n const role = el.getAttribute('role') || tag;\n let name = (el.getAttribute('aria-label') || el.getAttribute('title') || el.getAttribute('alt') || el.textContent || el.getAttribute('placeholder') || el.getAttribute('value') || '').trim();\n if (name.length > 120) name = name.slice(0, 120) + '\u2026';\n const rect = el.getBoundingClientRect();\n const visible = rect.width > 0 && rect.height > 0 && rect.bottom > 0 && rect.right > 0;\n if (!visible) continue;\n items.push({\n uid, role, tag, name, origin,\n attrs: {\n id: el.id || null,\n name: el.getAttribute('name') || null,\n type: el.getAttribute('type') || null,\n href: el.getAttribute('href') || null,\n placeholder: el.getAttribute('placeholder') || null,\n value: ('value' in el && el.value) ? String(el.value).slice(0, 200) : null,\n disabled: el.hasAttribute('disabled') || el.getAttribute('aria-disabled') === 'true',\n checked: 'checked' in el ? !!el.checked : (el.getAttribute('aria-checked') === 'true'),\n },\n bbox: { x: Math.round(rect.x), y: Math.round(rect.y), w: Math.round(rect.width), h: Math.round(rect.height) },\n selector: '[data-cloak-uid=\"' + uid + '\"]',\n });\n }\n }\n scan(document, 'main');\n const frames = Array.from(document.querySelectorAll('iframe'));\n for (let i = 0; i < frames.length; i++) {\n try {\n const doc = frames[i].contentDocument;\n if (doc) scan(doc, String(i));\n } catch { /* cross-origin iframe \u2014 skip silently */ }\n }\n return { items, url: location.href, title: document.title };\n})()"; //# sourceMappingURL=params.d.ts.map