@vostride/agent-qa-web 0.1.14 → 0.1.16
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.
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/dom-extractor.ts","../src/observer.ts","../src/element-resolver.ts","../src/action-validator.ts","../src/smart-wait.ts","../src/scroll-helper.ts","../src/browser-install-error.ts","../src/farm-adapter.ts","../src/accessibility.ts"],"sourcesContent":["export { WebPlatformAdapter } from './adapter.js'\nexport { FarmWebAdapter } from './farm-adapter.js'\nexport { observePage, parseAriaSnapshot } from './observer.js'\nexport { ElementResolver } from './element-resolver.js'\nexport { validateAction, ActionValidationError } from './action-validator.js'\nexport { waitForPageReady } from './smart-wait.js'\nexport type { ValidationResult } from './action-validator.js'\nexport type { SmartWaitOptions } from './smart-wait.js'\nexport type { RefMap, WebAdapterConfig, SnapshotResult } from './types.js'\nexport { runAccessibilityCheck, type AccessibilityOptions } from './accessibility.js'\nexport { extractDom } from './dom-extractor.js'\nexport type { ExtractDomOptions } from './dom-extractor.js'\n","import type { Browser, BrowserContext, Page } from 'playwright-core'\nimport type { PlatformAdapter, PlatformConfig, ScreenState, Action, ActionResult, ObserveOptions, ConsoleLogEntry, NetworkLogEntry } from '@vostride/agent-qa-core'\nimport { convertKeysForPlatform, isMacPlatform, warnIfOutOfBounds } from '@vostride/agent-qa-core'\nimport { observePage } from './observer.js'\nimport { ElementResolver } from './element-resolver.js'\nimport { validateAction } from './action-validator.js'\nimport { waitForPageReady } from './smart-wait.js'\nimport { scrollWithRef } from './scroll-helper.js'\nimport type { RefMap } from './types.js'\nimport { formatMissingBrowserError, isPlaywrightMissingBrowserError } from './browser-install-error.js'\n\ninterface PageLogBuffers {\n consoleLogs: ConsoleLogEntry[]\n networkLogs: NetworkLogEntry[]\n consoleDrainIndex: number\n networkDrainIndex: number\n pendingRequests: Map<string, { url: string; method: string; headers: Record<string, string>; startTime: number; postData?: string }>\n}\n\nfunction clickDelayOption(clickDelay?: number): { delay?: number } {\n return clickDelay !== undefined && clickDelay > 0 ? { delay: clickDelay } : {}\n}\n\nexport class WebPlatformAdapter implements PlatformAdapter {\n readonly platform = 'web' as const\n\n private browser: Browser | null = null\n private context: BrowserContext | null = null\n private page: Page | null = null\n private lastRefs: RefMap = {}\n private pageLogBuffers = new Map<Page, PageLogBuffers>()\n private logCaptureConfig: { console: boolean; network: boolean } = { console: true, network: true }\n private disconnected = false\n private intentionalClose = false\n\n async setup(config: PlatformConfig): Promise<void> {\n const { chromium, firefox, webkit } = await import('playwright-core')\n const launchers = { chromium, firefox, webkit } as const\n const browserName = config.browser?.name ?? 'chromium'\n const launcher = launchers[browserName]\n\n try {\n this.browser = await launcher.launch({\n headless: config.browser?.headless ?? true,\n ...(browserName === 'chromium' ? { args: ['--disable-blink-features=AutomationControlled'] } : {}),\n })\n } catch (error) {\n if (isPlaywrightMissingBrowserError(error)) {\n throw new Error(formatMissingBrowserError(browserName))\n }\n throw error\n }\n\n this.disconnected = false\n this.intentionalClose = false\n this.browser.on('disconnected', () => {\n if (!this.intentionalClose) {\n this.disconnected = true\n }\n })\n\n const contextOptions: Record<string, unknown> = {\n viewport: config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n if (config.recording?.enabled) {\n contextOptions.recordVideo = {\n dir: config.recording.videoDir,\n size: config.recording.videoSize ?? config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n }\n this.context = await this.browser.newContext(contextOptions)\n\n // Clipboard write permission — chromium only (firefox/webkit reject this permission per Pitfall 3)\n if (browserName === 'chromium') {\n await this.context.grantPermissions(['clipboard-write'])\n }\n\n this.logCaptureConfig = { console: config.logCapture?.console !== false, network: config.logCapture?.network !== false }\n\n // Hide automation signals so bot-protected sites don't redirect\n await this.context.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', { get: () => false })\n })\n\n this.page = await this.context.newPage()\n this.attachLogListeners(this.page)\n }\n\n async cleanup(): Promise<void> {\n this.intentionalClose = true\n if (this.browser) {\n await this.browser.close()\n }\n this.browser = null\n this.context = null\n this.page = null\n this.lastRefs = {}\n this.pageLogBuffers.clear()\n this.disconnected = false\n this.intentionalClose = false\n }\n\n get isBrowserDisconnected(): boolean {\n return this.disconnected\n }\n\n async observe(options?: ObserveOptions): Promise<ScreenState> {\n if (!this.page) {\n throw new Error('WebPlatformAdapter not initialized — call setup() first')\n }\n\n await waitForPageReady(this.page)\n const state = await observePage(this.page, {\n extractDom: options?.extractDom,\n })\n this.lastRefs = (state.metadata.refMap as RefMap) ?? {}\n return state\n }\n\n async execute(action: Action): Promise<ActionResult> {\n if (!this.page) {\n throw new Error('WebPlatformAdapter not initialized — call setup() first')\n }\n\n try {\n return await this.executeAction(action)\n } catch (err) {\n let screenshot: Buffer | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n try {\n screenshot = await this.page.screenshot({ scale: 'css' })\n } catch {\n // ignore screenshot failure\n }\n try {\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const resolver = new ElementResolver(this.page, this.lastRefs)\n const box = await resolver.getBoundingBox((action as any).ref)\n if (box) boundingBox = box\n }\n } catch {\n // ignore bounding box failure\n }\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n screenshot,\n boundingBox,\n }\n }\n }\n\n async screenshot(): Promise<Buffer | undefined> {\n try {\n if (this.page) {\n return await this.page.screenshot({ scale: 'css' })\n }\n return undefined\n } catch {\n return undefined\n }\n }\n\n getPage(): Page | null {\n return this.page\n }\n\n async getVideoPath(): Promise<string | null> {\n try {\n const video = this.page?.video()\n if (!video) return null\n return await video.path()\n } catch {\n return null\n }\n }\n\n drainConsoleLogs(level?: string): ConsoleLogEntry[] {\n const all: ConsoleLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.consoleLogs.slice(buffers.consoleDrainIndex)\n buffers.consoleDrainIndex = buffers.consoleLogs.length\n all.push(...newLogs)\n }\n if (!level) return all\n return all.filter(e => e.level === level)\n }\n\n drainNetworkLogs(urlPattern?: string): NetworkLogEntry[] {\n const all: NetworkLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.networkLogs.slice(buffers.networkDrainIndex)\n buffers.networkDrainIndex = buffers.networkLogs.length\n all.push(...newLogs)\n }\n if (!urlPattern) return all\n return all.filter(e => e.url.includes(urlPattern))\n }\n\n private attachLogListeners(page: Page): void {\n const buffers: PageLogBuffers = {\n consoleLogs: [],\n networkLogs: [],\n consoleDrainIndex: 0,\n networkDrainIndex: 0,\n pendingRequests: new Map(),\n }\n this.pageLogBuffers.set(page, buffers)\n\n if (this.logCaptureConfig.console) {\n page.on('console', (msg) => {\n buffers.consoleLogs.push({\n level: msg.type(),\n text: msg.text(),\n location: msg.location(),\n timestamp: Date.now(),\n })\n if (buffers.consoleLogs.length > 1000) {\n buffers.consoleLogs = buffers.consoleLogs.slice(-500)\n }\n })\n }\n\n if (this.logCaptureConfig.network) {\n page.on('request', (request) => {\n buffers.pendingRequests.set(request.url() + request.method(), {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n startTime: Date.now(),\n postData: request.postData() ?? undefined,\n })\n })\n\n page.on('response', async (response) => {\n const key = response.url() + response.request().method()\n const pending = buffers.pendingRequests.get(key)\n buffers.pendingRequests.delete(key)\n\n let body: string | undefined\n try {\n const buf = await response.body()\n const ct = response.headers()['content-type'] ?? ''\n if (ct.includes('image/') && !ct.includes('svg')) {\n body = buf.length > 32768 ? undefined : `data:${ct.split(';')[0]};base64,${buf.toString('base64')}`\n } else {\n const text = buf.toString('utf-8')\n body = text.length > 32768 ? text.slice(0, 32768) + '...[truncated]' : text\n }\n } catch {\n body = undefined\n }\n\n buffers.networkLogs.push({\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n requestHeaders: pending?.headers ?? response.request().headers(),\n responseHeaders: response.headers(),\n body,\n requestBody: pending?.postData,\n startTime: pending?.startTime ?? Date.now(),\n endTime: Date.now(),\n timing: response.request().timing(),\n })\n if (buffers.networkLogs.length > 500) {\n buffers.networkLogs = buffers.networkLogs.slice(-250)\n }\n })\n }\n }\n\n private async resolveTabTargetAsync(tab: { index?: number; title?: string; url?: string }): Promise<Page | undefined> {\n const pages = this.context!.pages()\n if (tab.index !== undefined) {\n return (tab.index >= 0 && tab.index < pages.length) ? pages[tab.index] : undefined\n }\n if (tab.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(tab.title)) return p\n }\n return undefined\n }\n if (tab.url) {\n return pages.find(p => p.url().includes(tab.url!))\n }\n return undefined\n }\n\n private async executeAction(action: Action): Promise<ActionResult> {\n const page = this.page!\n const resolver = new ElementResolver(page, this.lastRefs)\n\n // Validate action-element compatibility for ref-targeting actions\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const refData = this.lastRefs[(action as any).ref]\n const role = refData?.role\n const validation = validateAction(action, role)\n if (!validation.valid) {\n return { success: false, error: validation.error }\n }\n }\n\n switch (action.type) {\n case 'click': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : undefined\n await locator.click({\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'fill': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.fill(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'select': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.selectOption(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'navigate': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'scroll': {\n const deltaX = action.scrollType === 'horizontal' ? action.value : 0\n const deltaY = action.scrollType === 'vertical' ? action.value : 0\n let coordinates: { x: number; y: number } | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n let scrollData: { scrolled: boolean; scrolledContainer: string } | undefined\n\n if (action.ref) {\n const refData = this.lastRefs[action.ref]\n if (refData) {\n const scrollAxis = action.scrollType === 'horizontal' ? 'horizontal' : 'vertical'\n const result = await scrollWithRef(page, refData, deltaX, deltaY, scrollAxis)\n if (result.bounds) {\n coordinates = { x: result.bounds.x + result.bounds.width / 2, y: result.bounds.y + result.bounds.height / 2 }\n boundingBox = result.bounds\n }\n scrollData = { scrolled: result.scrolled, scrolledContainer: result.scrolledContainer }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n\n await page.evaluate(`new Promise(resolve => {\n const t = setTimeout(() => resolve('timeout'), 500);\n requestAnimationFrame(() => requestAnimationFrame(() => {\n clearTimeout(t);\n resolve('raf');\n }));\n })`)\n\n return { success: true, coordinates, boundingBox, data: scrollData }\n }\n\n case 'waitFor': {\n // Wait for condition: try as text content first, then fall back to selector.\n // The LLM generates natural language conditions (\"loading spinner disappears\")\n // which aren't CSS selectors — use page.waitForFunction for text matching.\n const timeout = action.timeout ?? 5000\n try {\n // Runs in browser context — checks if the condition text appears on page\n await page.waitForFunction(\n `document.body && document.body.innerText.includes(${JSON.stringify(action.condition)})`,\n { timeout },\n )\n } catch {\n // Fall back to waitForSelector for CSS-selector-shaped conditions\n try {\n await page.waitForSelector(action.condition, { timeout })\n } catch {\n // Best-effort — return success so the agent loop can re-observe\n }\n }\n return { success: true }\n }\n\n case 'delay': {\n await page.waitForTimeout(action.ms)\n return { success: true }\n }\n\n case 'waitForUrl': {\n try {\n // Explicit 30s timeout overrides Playwright's infinite default (Pitfall 2)\n await page.waitForURL(action.pattern, { timeout: 30_000 })\n return { success: true }\n } catch (err) {\n return {\n success: false,\n error: `URL pattern \"${action.pattern}\" did not match within 30s. Hint: use \"**\" wildcards for substring matching (e.g., \"**/dashboard**\"). ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n case 'keypress': {\n const effectiveKeys = convertKeysForPlatform(action.keys, {\n enabled: action.convertPlatformKeys !== false,\n isMac: isMacPlatform(),\n })\n for (const key of effectiveKeys) {\n await page.keyboard.press(key)\n }\n return { success: true }\n }\n\n case 'hover': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.hover()\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'paste': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.focus()\n await page.evaluate(`(() => {\n const el = document.activeElement;\n if (!el) return;\n const dt = new DataTransfer();\n dt.setData('text/plain', ${JSON.stringify(action.value)});\n el.dispatchEvent(new ClipboardEvent('paste', {\n clipboardData: dt,\n bubbles: true,\n cancelable: true,\n }));\n })()`)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'fileUpload': {\n // Paths are pre-resolved to absolute by runner loop.ts (see Plan 01 Task 2)\n const { existsSync } = await import('node:fs')\n for (const filePath of action.files) {\n if (!existsSync(filePath)) {\n return { success: false, error: `File not found: ${filePath}` }\n }\n }\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.setInputFiles(action.files)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'copy': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const text = (await locator.textContent()) ?? ''\n await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(text)})`)\n return { success: true, boundingBox: box ?? undefined, data: { copied: text } }\n }\n\n case 'keyDown': {\n await page.keyboard.down(action.key)\n return { success: true }\n }\n\n case 'keyUp': {\n await page.keyboard.up(action.key)\n return { success: true }\n }\n\n case 'refresh': {\n await page.reload({ waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'navigateHistory': {\n if (action.direction === 'back') {\n await page.goBack({ waitUntil: 'domcontentloaded' })\n } else {\n await page.goForward({ waitUntil: 'domcontentloaded' })\n }\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'readConsoleLogs': {\n let entries: ConsoleLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.consoleLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.consoleLogs)\n }\n }\n if (action.level) {\n entries = entries.filter(e => e.level === action.level)\n }\n return { success: true, data: entries }\n }\n\n case 'readNetworkLogs': {\n let entries: NetworkLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.networkLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.networkLogs)\n }\n }\n if (action.urlPattern) {\n entries = entries.filter(e => e.url.includes(action.urlPattern!))\n }\n return { success: true, data: entries }\n }\n\n case 'readCookies': {\n const cookies = await this.context!.cookies()\n if (action.name) {\n const cookie = cookies.find(c => c.name === action.name) ?? null\n return { success: true, data: cookie }\n }\n return { success: true, data: cookies }\n }\n\n case 'setCookies': {\n const cookiesWithDefaults = action.cookies.map(c => ({\n ...c,\n url: !c.domain ? page.url() : undefined,\n }))\n await this.context!.addCookies(cookiesWithDefaults)\n return { success: true }\n }\n\n case 'readLocalStorage': {\n const pageUrl = page.url()\n if (pageUrl === 'about:blank') {\n return { success: true, data: action.key ? null : {} }\n }\n if (action.key) {\n const value = await page.evaluate(\n (k: string) => localStorage.getItem(k), action.key\n )\n return { success: true, data: value }\n }\n const all = await page.evaluate(\n () => Object.fromEntries(\n Object.keys(localStorage).map(k => [k, localStorage.getItem(k)])\n )\n )\n return { success: true, data: all }\n }\n\n case 'setLocalStorage': {\n await page.evaluate((entries: Array<{ key: string; value: string }>) => {\n for (const { key, value } of entries) {\n localStorage.setItem(key, value)\n }\n }, action.entries)\n return { success: true }\n }\n\n case 'assert': {\n return { success: true }\n }\n\n case 'clearText': {\n const loc = resolver.resolve(action.ref)\n const clearBox = await resolver.getBoundingBox(action.ref)\n await loc.clear()\n return { success: true, boundingBox: clearBox ?? undefined }\n }\n\n case 'drag': {\n const fromLoc = resolver.resolve(action.fromRef)\n const toLoc = resolver.resolve(action.toRef)\n await fromLoc.dragTo(toLoc)\n return { success: true }\n }\n\n case 'doubleTap': {\n const dblLoc = resolver.resolve(action.ref)\n const dblBox = await resolver.getBoundingBox(action.ref)\n await dblLoc.dblclick()\n return { success: true, boundingBox: dblBox ?? undefined }\n }\n\n case 'doubleClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.dblclick({\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'rightClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.click({\n button: 'right',\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'openLink': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'newTab': {\n const newPage = await this.context!.newPage()\n this.attachLogListeners(newPage)\n await newPage.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(newPage)\n this.page = newPage\n return { success: true }\n }\n\n case 'switchTab': {\n const pages = this.context!.pages()\n\n let target: Page | undefined\n\n if (action.index !== undefined) {\n if (action.index < 0 || action.index >= pages.length) {\n return { success: false, error: `Tab index ${action.index} out of range (${pages.length} tabs open)` }\n }\n target = pages[action.index]\n } else if (action.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(action.title)) { target = p; break }\n }\n } else if (action.url) {\n target = pages.find(p => p.url().includes(action.url!))\n } else {\n return { success: false, error: 'switchTab requires at least one of: index, title, or url' }\n }\n\n if (!target) {\n return { success: false, error: `No tab found matching ${JSON.stringify({ index: action.index, title: action.title, url: action.url })}` }\n }\n\n this.page = target\n return { success: true }\n }\n\n // Mobile-only actions — graceful unsupported messages\n case 'tap':\n case 'swipe':\n case 'longpress':\n case 'pinch':\n case 'multiTap': {\n return { success: false, error: `${action.type} is a mobile-only gesture` }\n }\n\n case 'tapCoordinate': {\n const vp = page.viewportSize()\n if (vp) {\n warnIfOutOfBounds({ x: action.x, y: action.y }, { width: vp.width, height: vp.height }, 'tapCoordinate')\n }\n await page.mouse.click(action.x, action.y)\n return { success: true, coordinates: { x: action.x, y: action.y } }\n }\n\n case 'executeScript': {\n return { success: false, error: 'executeScript is a mobile-only action' }\n }\n\n case 'hideKeyboard':\n case 'launchApp':\n case 'stopApp':\n case 'setOrientation': {\n return { success: true }\n }\n\n default: {\n return { success: false, error: `Unknown action type: ${(action as any).type}` }\n }\n }\n }\n}\n","import type { Page } from 'playwright-core'\n\nconst SKIP_TAGS = new Set([\n 'SCRIPT', 'STYLE', 'SVG', 'NOSCRIPT', 'LINK', 'META',\n 'TEMPLATE', 'IFRAME',\n])\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nexport function extractDomTree(opts: { maxDepth: number; maxTextLen: number }): string {\n const { maxDepth, maxTextLen } = opts\n const doc = (globalThis as any).document\n const win = (globalThis as any).window\n const lines: string[] = []\n\n function isHidden(el: any): boolean {\n if (!el.offsetParent && el.tagName !== 'BODY' && el.tagName !== 'HTML') {\n const style = win.getComputedStyle(el)\n if (style.display === 'none' || style.visibility === 'hidden') return true\n }\n return false\n }\n\n function walk(node: any, depth: number, indent: string): void {\n if (depth > maxDepth) {\n lines.push(indent + '[... deeper content truncated]')\n return\n }\n\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === 3) {\n const text = child.textContent.trim()\n if (text) {\n const truncated = text.length > maxTextLen\n ? text.slice(0, maxTextLen) + '...'\n : text\n lines.push(indent + truncated)\n }\n continue\n }\n\n if (child.nodeType !== 1) continue\n\n const tag = child.tagName\n if (SKIP_TAGS.has(tag)) continue\n if (isHidden(child)) continue\n\n const isCustom = tag.toLowerCase().includes('-')\n const annotation = child.getAttribute('aria-label')\n || child.getAttribute('role')\n || ''\n\n let label = tag.toLowerCase()\n if (isCustom) {\n if (!child.shadowRoot && !child.firstChild) {\n label += ' (custom element, closed shadow root)'\n } else {\n label += ' (custom element)'\n }\n }\n if (annotation) label += ` [${annotation}]`\n\n lines.push(indent + label)\n\n if (child.shadowRoot) {\n lines.push(indent + ' #shadow-root')\n walk(child.shadowRoot, depth + 1, indent + ' ')\n }\n\n walk(child, depth + 1, indent + ' ')\n }\n }\n\n walk(doc.body, 0, '')\n return lines.join('\\n')\n}\n\nexport interface ExtractDomOptions {\n maxDepth?: number\n maxTextLen?: number\n}\n\nexport async function extractDom(\n page: Page,\n opts?: ExtractDomOptions,\n): Promise<string | undefined> {\n const maxDepth = opts?.maxDepth ?? 20\n const maxTextLen = opts?.maxTextLen ?? 200\n\n try {\n return await page.evaluate(extractDomTree, { maxDepth, maxTextLen })\n } catch {\n return undefined\n }\n}\n","import type { Page } from 'playwright-core'\nimport type { ScreenState, ElementInfo } from '@vostride/agent-qa-core'\nimport type { RefMap } from './types.js'\nimport { extractDom } from './dom-extractor.js'\n\nconst INTERACTIVE_ROLES = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox', 'listbox',\n 'menuitem', 'menuitemradio', 'menuitemcheckbox', 'option',\n 'searchbox', 'slider', 'spinbutton', 'switch', 'tab', 'treeitem',\n // WAI-ARIA 1.2 standalone widget roles\n 'gridcell', 'scrollbar', 'separator',\n // WAI-ARIA 1.2 composite widget roles (interactive containers)\n 'grid', 'menu', 'menubar', 'tree', 'treegrid',\n])\n\nconst CONTENT_ROLES = new Set([\n 'heading', 'cell', 'listitem', 'article', 'region', 'navigation',\n 'progressbar', 'tabpanel',\n])\n\nconst LINE_PATTERN = /^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/\n// Playwright wraps ARIA entries in single quotes when element names contain\n// colons or other characters that are ambiguous in its snapshot format.\n// e.g. - 'button \"Spoken Language: Any\"'\nconst QUOTED_LINE_PATTERN = /^(\\s*-\\s*)'(\\w+)(?:\\s+\"([^\"]*)\")?(.*)'\\s*$/\n\nexport function parseAriaSnapshot(ariaTree: string): { tree: string; elements: ElementInfo[]; refs: RefMap } {\n const lines = ariaTree.split('\\n')\n const elements: ElementInfo[] = []\n const refs: RefMap = {}\n const resultLines: string[] = []\n let refCounter = 0\n\n // Track role+name occurrences for disambiguation\n const roleNameCounts = new Map<string, number>()\n const refToKey = new Map<string, string>()\n\n for (const line of lines) {\n const match = line.match(LINE_PATTERN) || line.match(QUOTED_LINE_PATTERN)\n if (!match) {\n resultLines.push(line)\n continue\n }\n\n const [, prefix, role, name, suffix] = match\n const roleLower = role.toLowerCase()\n const shouldGetRef = INTERACTIVE_ROLES.has(roleLower) || CONTENT_ROLES.has(roleLower)\n\n if (!shouldGetRef) {\n resultLines.push(line)\n continue\n }\n\n refCounter++\n const ref = `e${refCounter}`\n const key = `${roleLower}:${name ?? ''}`\n\n const currentCount = roleNameCounts.get(key) ?? 0\n roleNameCounts.set(key, currentCount + 1)\n refToKey.set(ref, key)\n\n refs[ref] = { role: roleLower, name, nth: currentCount }\n\n // Parse attributes from suffix like [level=1], [checked], [disabled]\n const attributes: Record<string, string> = {}\n const attrMatches = suffix?.matchAll(/\\[(\\w+)(?:=([^\\]]*))?\\]/g)\n if (attrMatches) {\n for (const am of attrMatches) {\n attributes[am[1]] = am[2] ?? 'true'\n }\n }\n\n elements.push({ ref, role: roleLower, name: name ?? '', attributes })\n\n let enhanced = `${prefix}${role}`\n if (name) enhanced += ` \"${name}\"`\n enhanced += ` [ref=${ref}]`\n if (suffix?.trim()) enhanced += suffix\n resultLines.push(enhanced)\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n for (const [ref, data] of Object.entries(refs)) {\n const key = refToKey.get(ref)!\n if ((roleNameCounts.get(key) ?? 0) <= 1) {\n delete refs[ref].nth\n }\n }\n\n return { tree: resultLines.join('\\n'), elements, refs }\n}\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nfunction hideAgentQaElements() {\n const doc = (globalThis as any).document\n doc.querySelectorAll('[data-agent-qa-internal]').forEach((el: any) => {\n el.style.display = 'none'\n el.setAttribute('aria-hidden', 'true')\n })\n}\n\nfunction restoreAgentQaElements() {\n const doc = (globalThis as any).document\n doc.querySelectorAll('[data-agent-qa-internal]').forEach((el: any) => {\n el.style.display = ''\n el.removeAttribute('aria-hidden')\n })\n}\n\nexport async function observePage(\n page: Page,\n options?: { filterSelector?: string; extractDom?: boolean },\n): Promise<ScreenState> {\n const viewport = page.viewportSize()\n const locator = options?.filterSelector\n ? page.locator(options.filterSelector)\n : page.locator(':root')\n\n // Hide framework-injected elements from ARIA snapshot\n await page.evaluate(hideAgentQaElements)\n\n let ariaTree: string\n try {\n ariaTree = await locator.ariaSnapshot()\n } finally {\n // Restore framework-injected elements (always, even if snapshot fails)\n await page.evaluate(restoreAgentQaElements)\n }\n\n if (!ariaTree) {\n return {\n tree: '(empty)',\n elements: [],\n url: page.url(),\n timestamp: Date.now(),\n metadata: {\n coordSpace: 'viewport' as const,\n viewportWidth: viewport?.width ?? 0,\n viewportHeight: viewport?.height ?? 0,\n refMap: {},\n },\n }\n }\n\n const { tree, elements, refs } = parseAriaSnapshot(ariaTree)\n\n // Bulk bounding box enrichment — single page.evaluate collects all rects in one DOM call.\n // Previous approach used N sequential getByRole().boundingBox({timeout:500}) calls which\n // all timed out on complex external pages (100+ elements), reporting \"0 visible elements\".\n try {\n const refEntries = Object.entries(refs)\n if (refEntries.length > 0) {\n const refArgs: Array<[string, string, string | undefined, number | undefined]> = refEntries.map(\n ([ref, data]) => [ref, data.role, data.name, data.nth]\n )\n\n type BBoxResult = Array<[string, { x: number; y: number; width: number; height: number } | null]>\n const result = await Promise.race([\n page.evaluate((args: Array<[string, string, string | undefined, number | undefined]>) => {\n const doc = (globalThis as any).document\n const IMPLICIT_ROLES: Record<string, string> = {\n button: 'button', a: 'link', input: 'textbox', select: 'combobox',\n textarea: 'textbox', h1: 'heading', h2: 'heading', h3: 'heading',\n h4: 'heading', h5: 'heading', h6: 'heading', nav: 'navigation',\n main: 'main', aside: 'complementary', footer: 'contentinfo',\n header: 'banner', form: 'form', table: 'table', img: 'img',\n ul: 'list', ol: 'list', li: 'listitem', dialog: 'dialog',\n details: 'group', summary: 'button', progress: 'progressbar',\n meter: 'meter', output: 'status', article: 'article',\n section: 'region', fieldset: 'group', legend: 'legend',\n }\n const INPUT_TYPE_ROLES: Record<string, string> = {\n checkbox: 'checkbox', radio: 'radio', range: 'slider',\n number: 'spinbutton', search: 'searchbox', email: 'textbox',\n tel: 'textbox', url: 'textbox', password: 'textbox',\n }\n\n function getAccessibleName(el: any): string {\n const label = el.getAttribute('aria-label')\n if (label) return label.trim()\n const labelledBy = el.getAttribute('aria-labelledby')\n if (labelledBy) {\n const parts = labelledBy.split(/\\s+/).map((id: string) => {\n const ref = doc.getElementById(id)\n return ref ? (ref.textContent || '').trim() : ''\n }).filter(Boolean)\n if (parts.length) return parts.join(' ')\n }\n const title = el.getAttribute('title')\n if (title) return title.trim()\n const alt = el.getAttribute('alt')\n if (alt) return alt.trim()\n return (el.textContent || '').trim()\n }\n\n function matchesName(elName: string, targetName: string): boolean {\n return elName.toLowerCase().includes(targetName.toLowerCase())\n }\n\n function getImplicitRole(el: any): string | null {\n const tag = el.tagName.toLowerCase()\n if (tag === 'input') {\n const type = (el.getAttribute('type') || 'text').toLowerCase()\n return INPUT_TYPE_ROLES[type] || 'textbox'\n }\n if (tag === 'a' && el.hasAttribute('href')) return 'link'\n return IMPLICIT_ROLES[tag] || null\n }\n\n const results: Array<[string, { x: number; y: number; width: number; height: number } | null]> = []\n for (const [ref, role, name, nth] of args) {\n const candidates: any[] = []\n doc.querySelectorAll(`[role=\"${role}\"]`).forEach((el: any) => candidates.push(el))\n doc.querySelectorAll('*').forEach((el: any) => {\n if (el.getAttribute('role')) return\n if (getImplicitRole(el) === role) candidates.push(el)\n })\n let matched = candidates\n if (name) {\n matched = candidates.filter((el: any) => matchesName(getAccessibleName(el), name))\n }\n const target = matched[nth ?? 0]\n if (target) {\n const rect = target.getBoundingClientRect()\n results.push([ref, {\n x: Math.round(rect.x), y: Math.round(rect.y),\n width: Math.round(rect.width), height: Math.round(rect.height),\n }])\n } else {\n results.push([ref, null])\n }\n }\n return results\n }, refArgs),\n new Promise<null>(resolve => setTimeout(() => resolve(null), 3000)),\n ]) as BBoxResult | null\n\n if (result) {\n for (const [ref, box] of result) {\n if (box) refs[ref].bounds = box\n }\n }\n }\n } catch {\n // Bounding box enrichment is best-effort — never block observation\n }\n\n let domContext: string | undefined\n if (options?.extractDom) {\n try {\n domContext = await extractDom(page)\n } catch {\n // DOM extraction is best-effort\n }\n }\n\n return {\n tree,\n elements,\n url: page.url(),\n timestamp: Date.now(),\n metadata: {\n coordSpace: 'viewport' as const,\n viewportWidth: viewport?.width ?? 0,\n viewportHeight: viewport?.height ?? 0,\n refMap: refs,\n ...(domContext ? { domContext } : {}),\n },\n }\n}\n","import type { Page, Locator } from 'playwright-core'\nimport type { Action } from '@vostride/agent-qa-core'\nimport type { RefMap } from './types.js'\n\nconst ACTIONS_WITHOUT_REF = new Set(['navigate', 'waitFor', 'delay', 'waitForUrl', 'assert'])\n\nexport class ElementResolver {\n constructor(\n private page: Page,\n private refs: RefMap,\n ) {}\n\n resolve(ref: string): Locator {\n const data = this.refs[ref]\n if (!data) {\n throw new Error(`Unknown ref \"${ref}\". Available refs: ${Object.keys(this.refs).join(', ') || 'none'}`)\n }\n\n let locator: Locator\n if (data.name) {\n locator = this.page.getByRole(data.role as any, { name: data.name, exact: true })\n } else {\n locator = this.page.getByRole(data.role as any)\n }\n\n if (data.nth !== undefined) {\n locator = locator.nth(data.nth)\n }\n\n return locator\n }\n\n resolveAction(action: Action): Locator | null {\n if (ACTIONS_WITHOUT_REF.has(action.type)) {\n return null\n }\n\n if ('ref' in action && typeof action.ref === 'string') {\n return this.resolve(action.ref)\n }\n\n return null\n }\n\n async getBoundingBox(ref: string): Promise<{ x: number; y: number; width: number; height: number } | null> {\n try {\n const locator = this.resolve(ref)\n return await locator.boundingBox()\n } catch {\n return null\n }\n }\n}\n","import type { Action } from '@vostride/agent-qa-core'\n\nexport type ValidationResult =\n | { valid: true }\n | { valid: false; error: string; suggestion?: string }\n\nexport class ActionValidationError extends Error {\n readonly suggestion?: string\n\n constructor(message: string, suggestion?: string) {\n super(message)\n this.name = 'ActionValidationError'\n this.suggestion = suggestion\n }\n}\n\nconst FILL_ROLES = new Set(['textbox', 'searchbox', 'spinbutton', 'combobox'])\nconst SELECT_ROLES = new Set(['listbox', 'combobox'])\n\n// Actions that don't target elements — always valid\nconst NO_REF_ACTIONS = new Set(['scroll', 'navigate', 'waitFor', 'delay', 'waitForUrl', 'assert', 'pinch', 'multiTap', 'keyDown', 'keyUp', 'refresh', 'navigateHistory', 'readConsoleLogs', 'readNetworkLogs', 'readCookies', 'setCookies', 'readLocalStorage', 'setLocalStorage', 'executeScript'])\n\n// Actions valid for any role\nconst ANY_ROLE_ACTIONS = new Set(['click', 'hover', 'keypress', 'paste', 'doubleClick', 'rightClick'])\n\nexport function validateAction(action: Action, elementRole: string | undefined): ValidationResult {\n // Actions that don't require an element ref are always valid\n if (NO_REF_ACTIONS.has(action.type)) {\n return { valid: true }\n }\n\n // Actions valid for any role\n if (ANY_ROLE_ACTIONS.has(action.type)) {\n return { valid: true }\n }\n\n // Unknown or missing role — allow with permissive pass (LLM might know better)\n if (!elementRole) {\n return { valid: true }\n }\n\n const role = elementRole.toLowerCase()\n\n if (action.type === 'fill') {\n if (FILL_ROLES.has(role)) {\n return { valid: true }\n }\n if (SELECT_ROLES.has(role)) {\n return {\n valid: false,\n error: `Cannot fill() on a '${role}' element — fill is for text inputs. Try 'select' to choose an option.`,\n suggestion: 'select',\n }\n }\n return {\n valid: false,\n error: `Element ${(action as any).ref} is not fillable (role: ${role}). Use a textbox or input element instead.`,\n suggestion: 'click',\n }\n }\n\n if (action.type === 'clearText') {\n if (FILL_ROLES.has(role)) {\n return { valid: true }\n }\n return {\n valid: false,\n error: `Element ${(action as any).ref} is not fillable (role: ${role}). clearText only works on text inputs. Use a textbox or input element instead.`,\n suggestion: 'click',\n }\n }\n\n if (action.type === 'select') {\n if (SELECT_ROLES.has(role)) {\n return { valid: true }\n }\n if (FILL_ROLES.has(role)) {\n return {\n valid: false,\n error: `Cannot select() on a '${role}' element — select is for lists. Try 'fill' to type a value instead.`,\n suggestion: 'fill',\n }\n }\n return {\n valid: false,\n error: `Cannot select() on a '${role}' element — select is for list/combo elements.`,\n suggestion: 'click',\n }\n }\n\n // Unknown action type — allow (forward-compatible)\n return { valid: true }\n}\n","import type { Page } from 'playwright-core'\n\nexport interface SmartWaitOptions {\n timeout?: number\n}\n\nconst LOADING_SELECTORS = [\n '[aria-busy=\"true\"]',\n '[aria-label*=\"loading\" i]',\n '.loading', '.spinner', '.skeleton',\n '[data-loading]', '[data-testid=\"loading\"]',\n 'progress:not([value])',\n]\n\nexport async function waitForPageReady(page: Page, options?: SmartWaitOptions): Promise<void> {\n const timeout = options?.timeout ?? 10000\n\n await Promise.race([\n runReadinessChecks(page),\n new Promise<void>(resolve => setTimeout(resolve, timeout)),\n ])\n}\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nfunction checkLoadingIndicators(selectors: string[]): boolean {\n const doc = (globalThis as any).document\n return selectors.some((sel: string) => doc.querySelector(sel) !== null)\n}\n\nfunction checkLoadingGone(selectors: string[]): boolean {\n const doc = (globalThis as any).document\n return !selectors.some((sel: string) => doc.querySelector(sel))\n}\n\nfunction checkAnimationsRunning(): boolean {\n const doc = (globalThis as any).document\n return doc.getAnimations().filter((a: any) => a.playState === 'running').length > 0\n}\n\nfunction checkAnimationsSettled(): boolean {\n const doc = (globalThis as any).document\n return doc.getAnimations().filter((a: any) => a.playState === 'running').length === 0\n}\n\nasync function runReadinessChecks(page: Page): Promise<void> {\n // 1. Document ready\n try {\n await page.waitForLoadState('domcontentloaded', { timeout: 5000 })\n } catch {\n // Already loaded or timed out — continue\n }\n\n // 2. Network settle (best effort)\n try {\n await page.waitForLoadState('networkidle', { timeout: 5000 })\n } catch {\n // SPA with websockets or long-polling — proceed anyway\n }\n\n // 3. Loading indicators gone\n try {\n const hasIndicators = await page.evaluate(checkLoadingIndicators, LOADING_SELECTORS)\n\n if (hasIndicators) {\n try {\n await page.waitForFunction(checkLoadingGone, LOADING_SELECTORS, { timeout: 3000 })\n } catch {\n // Indicators didn't clear in 3s — proceed anyway\n }\n }\n } catch {\n // page.evaluate failed (navigation in progress, context destroyed) — continue\n }\n\n // 4. Animations settled\n try {\n const hasRunning = await page.evaluate(checkAnimationsRunning)\n\n if (hasRunning) {\n try {\n await page.waitForFunction(checkAnimationsSettled, undefined, { timeout: 2000 })\n } catch {\n // Animations didn't settle in 2s — proceed anyway\n }\n }\n } catch {\n // page.evaluate failed — continue\n }\n}\n","import type { Page } from 'playwright-core'\n\ninterface ScrollRefData {\n role: string\n name?: string\n nth?: number\n}\n\ninterface ScrollResult {\n bounds: { x: number; y: number; width: number; height: number } | null\n scrolledContainer: 'element' | 'ancestor' | 'documentElement' | 'notFound'\n scrolled: boolean\n}\n\nexport async function scrollWithRef(\n page: Page,\n refData: ScrollRefData,\n deltaX: number,\n deltaY: number,\n scrollAxis: 'horizontal' | 'vertical',\n): Promise<ScrollResult> {\n return page.evaluate(\n (args: [string, string | undefined, number, number, number, string]) => {\n const [role, name, nth, dx, dy, axis] = args\n const doc = (globalThis as any).document\n const win = (globalThis as any).window\n\n const IMPLICIT_ROLES: Record<string, string> = {\n button: 'button', a: 'link', input: 'textbox', select: 'combobox',\n textarea: 'textbox', h1: 'heading', h2: 'heading', h3: 'heading',\n h4: 'heading', h5: 'heading', h6: 'heading', nav: 'navigation',\n main: 'main', aside: 'complementary', footer: 'contentinfo',\n header: 'banner', form: 'form', table: 'table', img: 'img',\n ul: 'list', ol: 'list', li: 'listitem', dialog: 'dialog',\n details: 'group', summary: 'button', progress: 'progressbar',\n meter: 'meter', output: 'status', article: 'article',\n section: 'region', fieldset: 'group', legend: 'legend',\n }\n const INPUT_TYPE_ROLES: Record<string, string> = {\n checkbox: 'checkbox', radio: 'radio', range: 'slider',\n number: 'spinbutton', search: 'searchbox', email: 'textbox',\n tel: 'textbox', url: 'textbox', password: 'textbox',\n }\n\n function getAccessibleName(el: any): string {\n const label = el.getAttribute('aria-label')\n if (label) return label.trim()\n const labelledBy = el.getAttribute('aria-labelledby')\n if (labelledBy) {\n const parts = labelledBy.split(/\\s+/).map((id: string) => {\n const ref = doc.getElementById(id)\n return ref ? (ref.textContent || '').trim() : ''\n }).filter(Boolean)\n if (parts.length) return parts.join(' ')\n }\n const title = el.getAttribute('title')\n if (title) return title.trim()\n const alt = el.getAttribute('alt')\n if (alt) return alt.trim()\n return (el.textContent || '').trim()\n }\n\n function getImplicitRole(el: any): string | null {\n const tag = el.tagName.toLowerCase()\n if (tag === 'input') {\n const type = (el.getAttribute('type') || 'text').toLowerCase()\n return INPUT_TYPE_ROLES[type] || 'textbox'\n }\n if (tag === 'a' && el.hasAttribute('href')) return 'link'\n return IMPLICIT_ROLES[tag] || null\n }\n\n const candidates: any[] = []\n doc.querySelectorAll(`[role=\"${role}\"]`).forEach((el: any) => candidates.push(el))\n doc.querySelectorAll('*').forEach((el: any) => {\n if (el.getAttribute('role')) return\n if (getImplicitRole(el) === role) candidates.push(el)\n })\n\n let matched = candidates\n if (name) {\n matched = candidates.filter((el: any) =>\n getAccessibleName(el).toLowerCase().includes(name.toLowerCase())\n )\n }\n\n const target = matched[nth]\n if (!target) {\n win.scrollBy(dx, dy)\n return { bounds: null, scrolledContainer: 'notFound' as const, scrolled: true }\n }\n\n // Check target element itself for scrollability\n const targetStyle = win.getComputedStyle(target)\n const targetOverflow = axis === 'horizontal' ? targetStyle.overflowX : targetStyle.overflowY\n const targetScrollable = targetOverflow === 'auto' || targetOverflow === 'scroll' || targetOverflow === 'hidden'\n const targetHasContent = axis === 'horizontal'\n ? target.scrollWidth > target.clientWidth\n : target.scrollHeight > target.clientHeight\n if (targetScrollable && targetHasContent) {\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = target[prop]\n target.scrollBy(dx, dy)\n const after = target[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'element' as const,\n scrolled: before !== after,\n }\n }\n\n // Walk ancestors\n let parent = target.parentElement\n while (parent && parent !== doc.documentElement) {\n const style = win.getComputedStyle(parent)\n const overflow = axis === 'horizontal' ? style.overflowX : style.overflowY\n const isScrollable = overflow === 'auto' || overflow === 'scroll' || overflow === 'hidden'\n const hasContent = axis === 'horizontal'\n ? parent.scrollWidth > parent.clientWidth\n : parent.scrollHeight > parent.clientHeight\n if (isScrollable && hasContent) {\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = parent[prop]\n parent.scrollBy(dx, dy)\n const after = parent[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'ancestor' as const,\n scrolled: before !== after,\n }\n }\n parent = parent.parentElement\n }\n\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = doc.documentElement[prop]\n doc.documentElement.scrollBy(dx, dy)\n const after = doc.documentElement[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'documentElement' as const,\n scrolled: before !== after,\n }\n },\n [refData.role, refData.name, refData.nth ?? 0, deltaX, deltaY, scrollAxis] as [string, string | undefined, number, number, number, string],\n )\n}\n","type BrowserName = 'chromium' | 'firefox' | 'webkit'\n\nfunction displayBrowserName(browserName: BrowserName): string {\n if (browserName === 'chromium') return 'Chromium'\n if (browserName === 'firefox') return 'Firefox'\n return 'WebKit'\n}\n\nexport function isPlaywrightMissingBrowserError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error)\n const lower = message.toLowerCase()\n return lower.includes(\"executable doesn't exist\")\n && lower.includes('playwright')\n && lower.includes('install')\n}\n\nexport function formatMissingBrowserError(browserName: BrowserName): string {\n return [\n `agent-qa browser support is not installed for ${displayBrowserName(browserName)}.`,\n '',\n 'Install the browser managed by agent-qa, then rerun the test:',\n ` agent-qa install-browsers --${browserName}`,\n '',\n 'This can happen after upgrading agent-qa or Playwright because browser binaries live outside the package install.',\n ].join('\\n')\n}\n","import type { Browser, BrowserContext, Page } from 'playwright-core'\nimport type { PlatformAdapter, PlatformConfig, ScreenState, Action, ActionResult, ObserveOptions, ConsoleLogEntry, NetworkLogEntry } from '@vostride/agent-qa-core'\nimport { getProvider, registerAllProviders } from '@vostride/agent-qa-core'\nimport { convertKeysForPlatform, isMacPlatform } from '@vostride/agent-qa-core'\nimport type { FarmWebConfig } from '@vostride/agent-qa-core'\nimport { observePage } from './observer.js'\nimport { ElementResolver } from './element-resolver.js'\nimport { validateAction } from './action-validator.js'\nimport { waitForPageReady } from './smart-wait.js'\nimport { scrollWithRef } from './scroll-helper.js'\nimport type { RefMap } from './types.js'\n\ninterface PageLogBuffers {\n consoleLogs: ConsoleLogEntry[]\n networkLogs: NetworkLogEntry[]\n consoleDrainIndex: number\n networkDrainIndex: number\n pendingRequests: Map<string, { url: string; method: string; headers: Record<string, string>; startTime: number; postData?: string }>\n}\n\nfunction clickDelayOption(clickDelay?: number): { delay?: number } {\n return clickDelay !== undefined && clickDelay > 0 ? { delay: clickDelay } : {}\n}\n\nexport class FarmWebAdapter implements PlatformAdapter {\n readonly platform = 'web' as const\n\n private browser: Browser | null = null\n private context: BrowserContext | null = null\n private page: Page | null = null\n private lastRefs: RefMap = {}\n private sessionUrl: string | undefined\n private sessionId: string | undefined\n private testFailed = false\n private exitHandler: (() => void) | null = null\n private credentials: { username: string; accessKey: string } | null = null\n private pageLogBuffers = new Map<Page, PageLogBuffers>()\n private logCaptureConfig: { console: boolean; network: boolean } = { console: true, network: true }\n\n async setup(config: PlatformConfig): Promise<void> {\n if (!config.farmSession) {\n throw new Error('FarmWebAdapter requires config.farmSession to be set')\n }\n\n registerAllProviders()\n const provider = getProvider('browserstack')\n if (!provider) {\n throw new Error('Unknown farm provider: browserstack')\n }\n\n this.credentials = provider.resolveCredentials(config.farmSession.capabilities as any)\n if (!config.browser?.name) {\n throw new Error('FarmWebAdapter requires config.browser.name to be set')\n }\n const credentials = this.credentials\n\n const farmWebConfig: FarmWebConfig = {\n browser: config.browser,\n credentials,\n testName: (config.farmSession.capabilities as any)?.testName,\n }\n\n const { wsEndpoint } = await provider.resolveWebEndpoint(farmWebConfig)\n\n const { chromium } = await import('playwright-core')\n this.browser = await chromium.connect({ wsEndpoint })\n\n const contextOptions: Record<string, unknown> = {\n viewport: config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n if (config.recording?.enabled) {\n contextOptions.recordVideo = {\n dir: config.recording.videoDir,\n size: config.recording.videoSize ?? config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n }\n this.context = await this.browser.newContext(contextOptions)\n\n // Clipboard write permission — farm-adapter always uses chromium (see chromium.connect above)\n await this.context.grantPermissions(['clipboard-write'])\n\n this.page = await this.context.newPage()\n\n try {\n const cdpSession = await this.page.context().newCDPSession(this.page)\n const result = await cdpSession.send('Browser.getVersion') as Record<string, string>\n await cdpSession.detach()\n // BrowserStack includes session info in the debugger URL or we extract from the WSS endpoint\n // Use REST API to get session details\n const auth = Buffer.from(`${credentials.username}:${credentials.accessKey}`).toString('base64')\n const resp = await fetch('https://api.browserstack.com/automate/builds.json?limit=1&status=running', {\n headers: { Authorization: `Basic ${auth}` },\n })\n if (resp.ok) {\n const builds = await resp.json() as Array<{ automation_build: { hashed_id: string; name: string } }>\n if (builds.length > 0) {\n const buildId = builds[0].automation_build.hashed_id\n const sessResp = await fetch(`https://api.browserstack.com/automate/builds/${buildId}/sessions.json?limit=1`, {\n headers: { Authorization: `Basic ${auth}` },\n })\n if (sessResp.ok) {\n const sessions = await sessResp.json() as Array<{ automation_session: { hashed_id: string; browser_url: string } }>\n if (sessions.length > 0) {\n this.sessionId = sessions[0].automation_session.hashed_id\n this.sessionUrl = sessions[0].automation_session.browser_url\n }\n }\n }\n }\n } catch {\n // Session details extraction is best-effort\n }\n\n this.exitHandler = () => {\n try {\n this.browser?.close()\n } catch {\n // Best-effort cleanup on exit\n }\n }\n process.on('exit', this.exitHandler)\n\n this.logCaptureConfig = { console: config.logCapture?.console !== false, network: config.logCapture?.network !== false }\n this.attachLogListeners(this.page)\n }\n\n async cleanup(): Promise<void> {\n if (this.browser) {\n await this.browser.close()\n }\n\n // Set session status via REST API after browser is closed\n if (this.sessionId && this.credentials) {\n try {\n const status = this.testFailed ? 'failed' : 'passed'\n const reason = this.testFailed ? 'Test failed' : 'Test passed'\n const auth = Buffer.from(`${this.credentials.username}:${this.credentials.accessKey}`).toString('base64')\n await fetch(`https://api.browserstack.com/automate/sessions/${this.sessionId}.json`, {\n method: 'PUT',\n headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ status, reason }),\n })\n } catch {\n // Status reporting is best-effort\n }\n }\n\n if (this.exitHandler) {\n process.removeListener('exit', this.exitHandler)\n this.exitHandler = null\n }\n\n this.browser = null\n this.context = null\n this.page = null\n this.lastRefs = {}\n this.pageLogBuffers.clear()\n }\n\n async observe(options?: ObserveOptions): Promise<ScreenState> {\n if (!this.page) {\n throw new Error('FarmWebAdapter not initialized — call setup() first')\n }\n\n await waitForPageReady(this.page)\n const state = await observePage(this.page, {\n extractDom: options?.extractDom,\n })\n this.lastRefs = (state.metadata.refMap as RefMap) ?? {}\n return state\n }\n\n async execute(action: Action): Promise<ActionResult> {\n if (!this.page) {\n throw new Error('FarmWebAdapter not initialized — call setup() first')\n }\n\n try {\n return await this.executeAction(action)\n } catch (err) {\n let screenshot: Buffer | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n try {\n screenshot = await this.page.screenshot()\n } catch {\n // ignore screenshot failure\n }\n try {\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const resolver = new ElementResolver(this.page, this.lastRefs)\n const box = await resolver.getBoundingBox((action as any).ref)\n if (box) boundingBox = box\n }\n } catch {\n // ignore bounding box failure\n }\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n screenshot,\n boundingBox,\n }\n }\n }\n\n async screenshot(): Promise<Buffer | undefined> {\n try {\n if (this.page) {\n return await this.page.screenshot()\n }\n return undefined\n } catch {\n return undefined\n }\n }\n\n getPage(): Page | null {\n return this.page\n }\n\n async getVideoPath(): Promise<string | null> {\n try {\n const video = this.page?.video()\n if (!video) return null\n return await video.path()\n } catch {\n return null\n }\n }\n\n markFailed(): void {\n this.testFailed = true\n }\n\n getSessionUrl(): string | undefined {\n return this.sessionUrl\n }\n\n getSessionId(): string | undefined {\n return this.sessionId\n }\n\n drainConsoleLogs(level?: string): ConsoleLogEntry[] {\n const all: ConsoleLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.consoleLogs.slice(buffers.consoleDrainIndex)\n buffers.consoleDrainIndex = buffers.consoleLogs.length\n all.push(...newLogs)\n }\n if (!level) return all\n return all.filter(e => e.level === level)\n }\n\n drainNetworkLogs(urlPattern?: string): NetworkLogEntry[] {\n const all: NetworkLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.networkLogs.slice(buffers.networkDrainIndex)\n buffers.networkDrainIndex = buffers.networkLogs.length\n all.push(...newLogs)\n }\n if (!urlPattern) return all\n return all.filter(e => e.url.includes(urlPattern))\n }\n\n private attachLogListeners(page: Page): void {\n const buffers: PageLogBuffers = {\n consoleLogs: [],\n networkLogs: [],\n consoleDrainIndex: 0,\n networkDrainIndex: 0,\n pendingRequests: new Map(),\n }\n this.pageLogBuffers.set(page, buffers)\n\n if (this.logCaptureConfig.console) {\n page.on('console', (msg) => {\n buffers.consoleLogs.push({\n level: msg.type(),\n text: msg.text(),\n location: msg.location(),\n timestamp: Date.now(),\n })\n if (buffers.consoleLogs.length > 1000) {\n buffers.consoleLogs = buffers.consoleLogs.slice(-500)\n }\n })\n }\n\n if (this.logCaptureConfig.network) {\n page.on('request', (request) => {\n buffers.pendingRequests.set(request.url() + request.method(), {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n startTime: Date.now(),\n postData: request.postData() ?? undefined,\n })\n })\n\n page.on('response', async (response) => {\n const key = response.url() + response.request().method()\n const pending = buffers.pendingRequests.get(key)\n buffers.pendingRequests.delete(key)\n\n let body: string | undefined\n try {\n const buf = await response.body()\n const ct = response.headers()['content-type'] ?? ''\n if (ct.includes('image/') && !ct.includes('svg')) {\n body = buf.length > 32768 ? undefined : `data:${ct.split(';')[0]};base64,${buf.toString('base64')}`\n } else {\n const text = buf.toString('utf-8')\n body = text.length > 32768 ? text.slice(0, 32768) + '...[truncated]' : text\n }\n } catch {\n body = undefined\n }\n\n buffers.networkLogs.push({\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n requestHeaders: pending?.headers ?? response.request().headers(),\n responseHeaders: response.headers(),\n body,\n requestBody: pending?.postData,\n startTime: pending?.startTime ?? Date.now(),\n endTime: Date.now(),\n timing: response.request().timing(),\n })\n if (buffers.networkLogs.length > 500) {\n buffers.networkLogs = buffers.networkLogs.slice(-250)\n }\n })\n }\n }\n\n private async resolveTabTargetAsync(tab: { index?: number; title?: string; url?: string }): Promise<Page | undefined> {\n const pages = this.context!.pages()\n if (tab.index !== undefined) {\n return (tab.index >= 0 && tab.index < pages.length) ? pages[tab.index] : undefined\n }\n if (tab.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(tab.title)) return p\n }\n return undefined\n }\n if (tab.url) {\n return pages.find(p => p.url().includes(tab.url!))\n }\n return undefined\n }\n\n private async executeAction(action: Action): Promise<ActionResult> {\n const page = this.page!\n const resolver = new ElementResolver(page, this.lastRefs)\n\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const refData = this.lastRefs[(action as any).ref]\n const role = refData?.role\n const validation = validateAction(action, role)\n if (!validation.valid) {\n return { success: false, error: validation.error }\n }\n }\n\n switch (action.type) {\n case 'click': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : undefined\n await locator.click({\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'fill': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.fill(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'select': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.selectOption(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'navigate': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'scroll': {\n const deltaX = action.scrollType === 'horizontal' ? action.value : 0\n const deltaY = action.scrollType === 'vertical' ? action.value : 0\n let coordinates: { x: number; y: number } | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n let scrollData: { scrolled: boolean; scrolledContainer: string } | undefined\n\n if (action.ref) {\n const refData = this.lastRefs[action.ref]\n if (refData) {\n const scrollAxis = action.scrollType === 'horizontal' ? 'horizontal' : 'vertical'\n const result = await scrollWithRef(page, refData, deltaX, deltaY, scrollAxis)\n if (result.bounds) {\n coordinates = { x: result.bounds.x + result.bounds.width / 2, y: result.bounds.y + result.bounds.height / 2 }\n boundingBox = result.bounds\n }\n scrollData = { scrolled: result.scrolled, scrolledContainer: result.scrolledContainer }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n\n await page.evaluate(`new Promise(resolve => {\n const t = setTimeout(() => resolve('timeout'), 500);\n requestAnimationFrame(() => requestAnimationFrame(() => {\n clearTimeout(t);\n resolve('raf');\n }));\n })`)\n\n return { success: true, coordinates, boundingBox, data: scrollData }\n }\n\n case 'waitFor': {\n const timeout = action.timeout ?? 5000\n try {\n await page.waitForFunction(\n `document.body && document.body.innerText.includes(${JSON.stringify(action.condition)})`,\n { timeout },\n )\n } catch {\n try {\n await page.waitForSelector(action.condition, { timeout })\n } catch {\n // Best-effort\n }\n }\n return { success: true }\n }\n\n case 'delay': {\n await page.waitForTimeout(action.ms)\n return { success: true }\n }\n\n case 'waitForUrl': {\n try {\n // Explicit 30s timeout overrides Playwright's infinite default (Pitfall 2)\n await page.waitForURL(action.pattern, { timeout: 30_000 })\n return { success: true }\n } catch (err) {\n return {\n success: false,\n error: `URL pattern \"${action.pattern}\" did not match within 30s. Hint: use \"**\" wildcards for substring matching (e.g., \"**/dashboard**\"). ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n case 'keypress': {\n const effectiveKeys = convertKeysForPlatform(action.keys, {\n enabled: action.convertPlatformKeys !== false,\n isMac: isMacPlatform(),\n })\n for (const key of effectiveKeys) {\n await page.keyboard.press(key)\n }\n return { success: true }\n }\n\n case 'hover': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.hover()\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'paste': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.focus()\n await page.evaluate(`(() => {\n const el = document.activeElement;\n if (!el) return;\n const dt = new DataTransfer();\n dt.setData('text/plain', ${JSON.stringify(action.value)});\n el.dispatchEvent(new ClipboardEvent('paste', {\n clipboardData: dt,\n bubbles: true,\n cancelable: true,\n }));\n })()`)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'fileUpload': {\n // Paths are pre-resolved to absolute by runner loop.ts (see Plan 01 Task 2)\n const { existsSync } = await import('node:fs')\n for (const filePath of action.files) {\n if (!existsSync(filePath)) {\n return { success: false, error: `File not found: ${filePath}` }\n }\n }\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.setInputFiles(action.files)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'copy': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const text = (await locator.textContent()) ?? ''\n await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(text)})`)\n return { success: true, boundingBox: box ?? undefined, data: { copied: text } }\n }\n\n case 'keyDown': {\n await page.keyboard.down(action.key)\n return { success: true }\n }\n\n case 'keyUp': {\n await page.keyboard.up(action.key)\n return { success: true }\n }\n\n case 'refresh': {\n await page.reload({ waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'navigateHistory': {\n if (action.direction === 'back') {\n await page.goBack({ waitUntil: 'domcontentloaded' })\n } else {\n await page.goForward({ waitUntil: 'domcontentloaded' })\n }\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'readConsoleLogs': {\n let entries: ConsoleLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.consoleLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.consoleLogs)\n }\n }\n if (action.level) {\n entries = entries.filter(e => e.level === action.level)\n }\n return { success: true, data: entries }\n }\n\n case 'readNetworkLogs': {\n let entries: NetworkLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.networkLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.networkLogs)\n }\n }\n if (action.urlPattern) {\n entries = entries.filter(e => e.url.includes(action.urlPattern!))\n }\n return { success: true, data: entries }\n }\n\n case 'readCookies': {\n const cookies = await this.context!.cookies()\n if (action.name) {\n const cookie = cookies.find(c => c.name === action.name) ?? null\n return { success: true, data: cookie }\n }\n return { success: true, data: cookies }\n }\n\n case 'setCookies': {\n const cookiesWithDefaults = action.cookies.map(c => ({\n ...c,\n url: !c.domain ? page.url() : undefined,\n }))\n await this.context!.addCookies(cookiesWithDefaults)\n return { success: true }\n }\n\n case 'readLocalStorage': {\n const pageUrl = page.url()\n if (pageUrl === 'about:blank') {\n return { success: true, data: action.key ? null : {} }\n }\n if (action.key) {\n const value = await page.evaluate(\n (k: string) => localStorage.getItem(k), action.key\n )\n return { success: true, data: value }\n }\n const all = await page.evaluate(\n () => Object.fromEntries(\n Object.keys(localStorage).map(k => [k, localStorage.getItem(k)])\n )\n )\n return { success: true, data: all }\n }\n\n case 'setLocalStorage': {\n await page.evaluate((entries: Array<{ key: string; value: string }>) => {\n for (const { key, value } of entries) {\n localStorage.setItem(key, value)\n }\n }, action.entries)\n return { success: true }\n }\n\n case 'assert': {\n return { success: true }\n }\n\n case 'clearText': {\n const loc = resolver.resolve(action.ref)\n const clearBox = await resolver.getBoundingBox(action.ref)\n await loc.clear()\n return { success: true, boundingBox: clearBox ?? undefined }\n }\n\n case 'drag': {\n const fromLoc = resolver.resolve(action.fromRef)\n const toLoc = resolver.resolve(action.toRef)\n await fromLoc.dragTo(toLoc)\n return { success: true }\n }\n\n case 'doubleTap': {\n const dblLoc = resolver.resolve(action.ref)\n const dblBox = await resolver.getBoundingBox(action.ref)\n await dblLoc.dblclick()\n return { success: true, boundingBox: dblBox ?? undefined }\n }\n\n case 'doubleClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.dblclick({\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'rightClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.click({\n button: 'right',\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'openLink': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'newTab': {\n const newPage = await this.context!.newPage()\n this.attachLogListeners(newPage)\n await newPage.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(newPage)\n this.page = newPage\n return { success: true }\n }\n\n case 'switchTab': {\n const pages = this.context!.pages()\n\n let target: Page | undefined\n\n if (action.index !== undefined) {\n if (action.index < 0 || action.index >= pages.length) {\n return { success: false, error: `Tab index ${action.index} out of range (${pages.length} tabs open)` }\n }\n target = pages[action.index]\n } else if (action.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(action.title)) { target = p; break }\n }\n } else if (action.url) {\n target = pages.find(p => p.url().includes(action.url!))\n } else {\n return { success: false, error: 'switchTab requires at least one of: index, title, or url' }\n }\n\n if (!target) {\n return { success: false, error: `No tab found matching ${JSON.stringify({ index: action.index, title: action.title, url: action.url })}` }\n }\n\n this.page = target\n return { success: true }\n }\n\n case 'tap':\n case 'swipe':\n case 'longpress':\n case 'pinch':\n case 'multiTap': {\n return { success: false, error: `${action.type} is a mobile-only gesture` }\n }\n\n case 'tapCoordinate': {\n await page.mouse.click(action.x, action.y)\n return { success: true, coordinates: { x: action.x, y: action.y } }\n }\n\n case 'hideKeyboard':\n case 'launchApp':\n case 'stopApp':\n case 'setOrientation': {\n return { success: true }\n }\n\n default: {\n return { success: false, error: `Unknown action type: ${(action as any).type}` }\n }\n }\n }\n}\n","import { AxeBuilder } from '@axe-core/playwright'\nimport type { Page } from 'playwright-core'\nimport type { AccessibilityViolation } from '@vostride/agent-qa-core'\n\nexport interface AccessibilityOptions {\n standard?: 'wcag2a' | 'wcag2aa' | 'wcag2aaa'\n disableRules?: string[]\n exclude?: string[]\n}\n\nexport async function runAccessibilityCheck(\n page: Page,\n options?: AccessibilityOptions,\n): Promise<AccessibilityViolation[]> {\n let builder = new AxeBuilder({ page })\n\n if (options?.standard) {\n const tagMap: Record<string, string[]> = {\n 'wcag2a': ['wcag2a'],\n 'wcag2aa': ['wcag2a', 'wcag2aa'],\n 'wcag2aaa': ['wcag2a', 'wcag2aa', 'wcag2aaa'],\n }\n builder = builder.withTags(tagMap[options.standard] ?? ['wcag2a', 'wcag2aa'])\n }\n\n if (options?.disableRules?.length) {\n builder = builder.disableRules(options.disableRules)\n }\n\n if (options?.exclude?.length) {\n for (const selector of options.exclude) {\n builder = builder.exclude(selector)\n }\n }\n\n const results = await builder.analyze()\n\n return results.violations.map(v => ({\n ruleId: v.id,\n impact: v.impact as AccessibilityViolation['impact'],\n description: v.description,\n help: v.help,\n helpUrl: v.helpUrl,\n nodes: v.nodes.slice(0, 10).map(n => ({\n html: n.html,\n target: n.target as string[],\n })),\n }))\n}\n"],"mappings":"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","names":["prop","before","after","rect","import_agent_qa_core","clickDelayOption"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/adapter.ts","../src/dom-extractor.ts","../src/observer.ts","../src/element-resolver.ts","../src/action-validator.ts","../src/smart-wait.ts","../src/scroll-helper.ts","../src/browser-install-error.ts","../src/farm-adapter.ts","../src/accessibility.ts"],"sourcesContent":["export { WebPlatformAdapter } from './adapter.js'\nexport { FarmWebAdapter } from './farm-adapter.js'\nexport { observePage, parseAriaSnapshot } from './observer.js'\nexport { ElementResolver } from './element-resolver.js'\nexport { validateAction, ActionValidationError } from './action-validator.js'\nexport { waitForPageReady } from './smart-wait.js'\nexport type { ValidationResult } from './action-validator.js'\nexport type { SmartWaitOptions } from './smart-wait.js'\nexport type { RefMap, WebAdapterConfig, SnapshotResult } from './types.js'\nexport { runAccessibilityCheck, type AccessibilityOptions } from './accessibility.js'\nexport { extractDom } from './dom-extractor.js'\nexport type { ExtractDomOptions } from './dom-extractor.js'\n","import type { Browser, BrowserContext, Page } from 'playwright-core'\nimport type { PlatformAdapter, PlatformConfig, ScreenState, Action, ActionResult, ObserveOptions, ConsoleLogEntry, NetworkLogEntry } from '@vostride/agent-qa-core'\nimport { convertKeysForPlatform, isMacPlatform, warnIfOutOfBounds } from '@vostride/agent-qa-core'\nimport { observePage } from './observer.js'\nimport { ElementResolver } from './element-resolver.js'\nimport { validateAction } from './action-validator.js'\nimport { waitForPageReady } from './smart-wait.js'\nimport { scrollWithRef } from './scroll-helper.js'\nimport type { RefMap } from './types.js'\nimport { formatMissingBrowserError, isPlaywrightMissingBrowserError } from './browser-install-error.js'\n\ninterface PageLogBuffers {\n consoleLogs: ConsoleLogEntry[]\n networkLogs: NetworkLogEntry[]\n consoleDrainIndex: number\n networkDrainIndex: number\n pendingRequests: Map<string, { url: string; method: string; headers: Record<string, string>; startTime: number; postData?: string }>\n}\n\nfunction clickDelayOption(clickDelay?: number): { delay?: number } {\n return clickDelay !== undefined && clickDelay > 0 ? { delay: clickDelay } : {}\n}\n\nexport class WebPlatformAdapter implements PlatformAdapter {\n readonly platform = 'web' as const\n\n private browser: Browser | null = null\n private context: BrowserContext | null = null\n private page: Page | null = null\n private lastRefs: RefMap = {}\n private pageLogBuffers = new Map<Page, PageLogBuffers>()\n private logCaptureConfig: { console: boolean; network: boolean } = { console: true, network: true }\n private disconnected = false\n private intentionalClose = false\n\n async setup(config: PlatformConfig): Promise<void> {\n const { chromium, firefox, webkit } = await import('playwright-core')\n const launchers = { chromium, firefox, webkit } as const\n const browserName = config.browser?.name ?? 'chromium'\n const launcher = launchers[browserName]\n\n try {\n this.browser = await launcher.launch({\n headless: config.browser?.headless ?? true,\n ...(browserName === 'chromium' ? { args: ['--disable-blink-features=AutomationControlled'] } : {}),\n })\n } catch (error) {\n if (isPlaywrightMissingBrowserError(error)) {\n throw new Error(formatMissingBrowserError(browserName))\n }\n throw error\n }\n\n this.disconnected = false\n this.intentionalClose = false\n this.browser.on('disconnected', () => {\n if (!this.intentionalClose) {\n this.disconnected = true\n }\n })\n\n const contextOptions: Record<string, unknown> = {\n viewport: config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n if (config.recording?.enabled) {\n contextOptions.recordVideo = {\n dir: config.recording.videoDir,\n size: config.recording.videoSize ?? config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n }\n if (config.authState?.storageStatePath) {\n contextOptions.storageState = config.authState.storageStatePath\n }\n this.context = await this.browser.newContext(contextOptions)\n\n // Clipboard write permission — chromium only (firefox/webkit reject this permission per Pitfall 3)\n if (browserName === 'chromium') {\n await this.context.grantPermissions(['clipboard-write'])\n }\n\n this.logCaptureConfig = { console: config.logCapture?.console !== false, network: config.logCapture?.network !== false }\n\n // Hide automation signals so bot-protected sites don't redirect\n await this.context.addInitScript(() => {\n Object.defineProperty(navigator, 'webdriver', { get: () => false })\n })\n\n this.page = await this.context.newPage()\n this.attachLogListeners(this.page)\n }\n\n async cleanup(): Promise<void> {\n this.intentionalClose = true\n if (this.browser) {\n await this.browser.close()\n }\n this.browser = null\n this.context = null\n this.page = null\n this.lastRefs = {}\n this.pageLogBuffers.clear()\n this.disconnected = false\n this.intentionalClose = false\n }\n\n get isBrowserDisconnected(): boolean {\n return this.disconnected\n }\n\n async observe(options?: ObserveOptions): Promise<ScreenState> {\n if (!this.page) {\n throw new Error('WebPlatformAdapter not initialized — call setup() first')\n }\n\n await waitForPageReady(this.page)\n const state = await observePage(this.page, {\n extractDom: options?.extractDom,\n })\n this.lastRefs = (state.metadata.refMap as RefMap) ?? {}\n return state\n }\n\n async execute(action: Action): Promise<ActionResult> {\n if (!this.page) {\n throw new Error('WebPlatformAdapter not initialized — call setup() first')\n }\n\n try {\n return await this.executeAction(action)\n } catch (err) {\n let screenshot: Buffer | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n try {\n screenshot = await this.page.screenshot({ scale: 'css' })\n } catch {\n // ignore screenshot failure\n }\n try {\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const resolver = new ElementResolver(this.page, this.lastRefs)\n const box = await resolver.getBoundingBox((action as any).ref)\n if (box) boundingBox = box\n }\n } catch {\n // ignore bounding box failure\n }\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n screenshot,\n boundingBox,\n }\n }\n }\n\n async screenshot(): Promise<Buffer | undefined> {\n try {\n if (this.page) {\n return await this.page.screenshot({ scale: 'css' })\n }\n return undefined\n } catch {\n return undefined\n }\n }\n\n getPage(): Page | null {\n return this.page\n }\n\n async getVideoPath(): Promise<string | null> {\n try {\n const video = this.page?.video()\n if (!video) return null\n return await video.path()\n } catch {\n return null\n }\n }\n\n drainConsoleLogs(level?: string): ConsoleLogEntry[] {\n const all: ConsoleLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.consoleLogs.slice(buffers.consoleDrainIndex)\n buffers.consoleDrainIndex = buffers.consoleLogs.length\n all.push(...newLogs)\n }\n if (!level) return all\n return all.filter(e => e.level === level)\n }\n\n drainNetworkLogs(urlPattern?: string): NetworkLogEntry[] {\n const all: NetworkLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.networkLogs.slice(buffers.networkDrainIndex)\n buffers.networkDrainIndex = buffers.networkLogs.length\n all.push(...newLogs)\n }\n if (!urlPattern) return all\n return all.filter(e => e.url.includes(urlPattern))\n }\n\n private attachLogListeners(page: Page): void {\n const buffers: PageLogBuffers = {\n consoleLogs: [],\n networkLogs: [],\n consoleDrainIndex: 0,\n networkDrainIndex: 0,\n pendingRequests: new Map(),\n }\n this.pageLogBuffers.set(page, buffers)\n\n if (this.logCaptureConfig.console) {\n page.on('console', (msg) => {\n buffers.consoleLogs.push({\n level: msg.type(),\n text: msg.text(),\n location: msg.location(),\n timestamp: Date.now(),\n })\n if (buffers.consoleLogs.length > 1000) {\n buffers.consoleLogs = buffers.consoleLogs.slice(-500)\n }\n })\n }\n\n if (this.logCaptureConfig.network) {\n page.on('request', (request) => {\n buffers.pendingRequests.set(request.url() + request.method(), {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n startTime: Date.now(),\n postData: request.postData() ?? undefined,\n })\n })\n\n page.on('response', async (response) => {\n const key = response.url() + response.request().method()\n const pending = buffers.pendingRequests.get(key)\n buffers.pendingRequests.delete(key)\n\n let body: string | undefined\n try {\n const buf = await response.body()\n const ct = response.headers()['content-type'] ?? ''\n if (ct.includes('image/') && !ct.includes('svg')) {\n body = buf.length > 32768 ? undefined : `data:${ct.split(';')[0]};base64,${buf.toString('base64')}`\n } else {\n const text = buf.toString('utf-8')\n body = text.length > 32768 ? text.slice(0, 32768) + '...[truncated]' : text\n }\n } catch {\n body = undefined\n }\n\n buffers.networkLogs.push({\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n requestHeaders: pending?.headers ?? response.request().headers(),\n responseHeaders: response.headers(),\n body,\n requestBody: pending?.postData,\n startTime: pending?.startTime ?? Date.now(),\n endTime: Date.now(),\n timing: response.request().timing(),\n })\n if (buffers.networkLogs.length > 500) {\n buffers.networkLogs = buffers.networkLogs.slice(-250)\n }\n })\n }\n }\n\n private async resolveTabTargetAsync(tab: { index?: number; title?: string; url?: string }): Promise<Page | undefined> {\n const pages = this.context!.pages()\n if (tab.index !== undefined) {\n return (tab.index >= 0 && tab.index < pages.length) ? pages[tab.index] : undefined\n }\n if (tab.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(tab.title)) return p\n }\n return undefined\n }\n if (tab.url) {\n return pages.find(p => p.url().includes(tab.url!))\n }\n return undefined\n }\n\n private async executeAction(action: Action): Promise<ActionResult> {\n const page = this.page!\n const resolver = new ElementResolver(page, this.lastRefs)\n\n // Validate action-element compatibility for ref-targeting actions\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const refData = this.lastRefs[(action as any).ref]\n const role = refData?.role\n const validation = validateAction(action, role)\n if (!validation.valid) {\n return { success: false, error: validation.error }\n }\n }\n\n switch (action.type) {\n case 'click': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : undefined\n await locator.click({\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'fill': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.fill(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'select': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.selectOption(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'navigate': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'scroll': {\n const deltaX = action.scrollType === 'horizontal' ? action.value : 0\n const deltaY = action.scrollType === 'vertical' ? action.value : 0\n let coordinates: { x: number; y: number } | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n let scrollData: { scrolled: boolean; scrolledContainer: string } | undefined\n\n if (action.ref) {\n const refData = this.lastRefs[action.ref]\n if (refData) {\n const scrollAxis = action.scrollType === 'horizontal' ? 'horizontal' : 'vertical'\n const result = await scrollWithRef(page, refData, deltaX, deltaY, scrollAxis)\n if (result.bounds) {\n coordinates = { x: result.bounds.x + result.bounds.width / 2, y: result.bounds.y + result.bounds.height / 2 }\n boundingBox = result.bounds\n }\n scrollData = { scrolled: result.scrolled, scrolledContainer: result.scrolledContainer }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n\n await page.evaluate(`new Promise(resolve => {\n const t = setTimeout(() => resolve('timeout'), 500);\n requestAnimationFrame(() => requestAnimationFrame(() => {\n clearTimeout(t);\n resolve('raf');\n }));\n })`)\n\n return { success: true, coordinates, boundingBox, data: scrollData }\n }\n\n case 'waitFor': {\n // Wait for condition: try as text content first, then fall back to selector.\n // The LLM generates natural language conditions (\"loading spinner disappears\")\n // which aren't CSS selectors — use page.waitForFunction for text matching.\n const timeout = action.timeout ?? 5000\n try {\n // Runs in browser context — checks if the condition text appears on page\n await page.waitForFunction(\n `document.body && document.body.innerText.includes(${JSON.stringify(action.condition)})`,\n { timeout },\n )\n } catch {\n // Fall back to waitForSelector for CSS-selector-shaped conditions\n try {\n await page.waitForSelector(action.condition, { timeout })\n } catch {\n // Best-effort — return success so the agent loop can re-observe\n }\n }\n return { success: true }\n }\n\n case 'delay': {\n await page.waitForTimeout(action.ms)\n return { success: true }\n }\n\n case 'waitForUrl': {\n try {\n // Explicit 30s timeout overrides Playwright's infinite default (Pitfall 2)\n await page.waitForURL(action.pattern, { timeout: 30_000 })\n return { success: true }\n } catch (err) {\n return {\n success: false,\n error: `URL pattern \"${action.pattern}\" did not match within 30s. Hint: use \"**\" wildcards for substring matching (e.g., \"**/dashboard**\"). ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n case 'keypress': {\n const effectiveKeys = convertKeysForPlatform(action.keys, {\n enabled: action.convertPlatformKeys !== false,\n isMac: isMacPlatform(),\n })\n for (const key of effectiveKeys) {\n await page.keyboard.press(key)\n }\n return { success: true }\n }\n\n case 'hover': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.hover()\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'paste': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.focus()\n await page.evaluate(`(() => {\n const el = document.activeElement;\n if (!el) return;\n const dt = new DataTransfer();\n dt.setData('text/plain', ${JSON.stringify(action.value)});\n el.dispatchEvent(new ClipboardEvent('paste', {\n clipboardData: dt,\n bubbles: true,\n cancelable: true,\n }));\n })()`)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'fileUpload': {\n // Paths are pre-resolved to absolute by runner loop.ts (see Plan 01 Task 2)\n const { existsSync } = await import('node:fs')\n for (const filePath of action.files) {\n if (!existsSync(filePath)) {\n return { success: false, error: `File not found: ${filePath}` }\n }\n }\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.setInputFiles(action.files)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'copy': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const text = (await locator.textContent()) ?? ''\n await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(text)})`)\n return { success: true, boundingBox: box ?? undefined, data: { copied: text } }\n }\n\n case 'keyDown': {\n await page.keyboard.down(action.key)\n return { success: true }\n }\n\n case 'keyUp': {\n await page.keyboard.up(action.key)\n return { success: true }\n }\n\n case 'refresh': {\n await page.reload({ waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'navigateHistory': {\n if (action.direction === 'back') {\n await page.goBack({ waitUntil: 'domcontentloaded' })\n } else {\n await page.goForward({ waitUntil: 'domcontentloaded' })\n }\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'readConsoleLogs': {\n let entries: ConsoleLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.consoleLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.consoleLogs)\n }\n }\n if (action.level) {\n entries = entries.filter(e => e.level === action.level)\n }\n return { success: true, data: entries }\n }\n\n case 'readNetworkLogs': {\n let entries: NetworkLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.networkLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.networkLogs)\n }\n }\n if (action.urlPattern) {\n entries = entries.filter(e => e.url.includes(action.urlPattern!))\n }\n return { success: true, data: entries }\n }\n\n case 'readCookies': {\n const cookies = await this.context!.cookies()\n if (action.name) {\n const cookie = cookies.find(c => c.name === action.name) ?? null\n return { success: true, data: cookie }\n }\n return { success: true, data: cookies }\n }\n\n case 'setCookies': {\n const cookiesWithDefaults = action.cookies.map(c => ({\n ...c,\n url: !c.domain ? page.url() : undefined,\n }))\n await this.context!.addCookies(cookiesWithDefaults)\n return { success: true }\n }\n\n case 'readLocalStorage': {\n const pageUrl = page.url()\n if (pageUrl === 'about:blank') {\n return { success: true, data: action.key ? null : {} }\n }\n if (action.key) {\n const value = await page.evaluate(\n (k: string) => localStorage.getItem(k), action.key\n )\n return { success: true, data: value }\n }\n const all = await page.evaluate(\n () => Object.fromEntries(\n Object.keys(localStorage).map(k => [k, localStorage.getItem(k)])\n )\n )\n return { success: true, data: all }\n }\n\n case 'setLocalStorage': {\n await page.evaluate((entries: Array<{ key: string; value: string }>) => {\n for (const { key, value } of entries) {\n localStorage.setItem(key, value)\n }\n }, action.entries)\n return { success: true }\n }\n\n case 'assert': {\n return { success: true }\n }\n\n case 'clearText': {\n const loc = resolver.resolve(action.ref)\n const clearBox = await resolver.getBoundingBox(action.ref)\n await loc.clear()\n return { success: true, boundingBox: clearBox ?? undefined }\n }\n\n case 'drag': {\n const fromLoc = resolver.resolve(action.fromRef)\n const toLoc = resolver.resolve(action.toRef)\n await fromLoc.dragTo(toLoc)\n return { success: true }\n }\n\n case 'doubleTap': {\n const dblLoc = resolver.resolve(action.ref)\n const dblBox = await resolver.getBoundingBox(action.ref)\n await dblLoc.dblclick()\n return { success: true, boundingBox: dblBox ?? undefined }\n }\n\n case 'doubleClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.dblclick({\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'rightClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.click({\n button: 'right',\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'openLink': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'newTab': {\n const newPage = await this.context!.newPage()\n this.attachLogListeners(newPage)\n await newPage.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(newPage)\n this.page = newPage\n return { success: true }\n }\n\n case 'switchTab': {\n const pages = this.context!.pages()\n\n let target: Page | undefined\n\n if (action.index !== undefined) {\n if (action.index < 0 || action.index >= pages.length) {\n return { success: false, error: `Tab index ${action.index} out of range (${pages.length} tabs open)` }\n }\n target = pages[action.index]\n } else if (action.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(action.title)) { target = p; break }\n }\n } else if (action.url) {\n target = pages.find(p => p.url().includes(action.url!))\n } else {\n return { success: false, error: 'switchTab requires at least one of: index, title, or url' }\n }\n\n if (!target) {\n return { success: false, error: `No tab found matching ${JSON.stringify({ index: action.index, title: action.title, url: action.url })}` }\n }\n\n this.page = target\n return { success: true }\n }\n\n // Mobile-only actions — graceful unsupported messages\n case 'tap':\n case 'swipe':\n case 'longpress':\n case 'pinch':\n case 'multiTap': {\n return { success: false, error: `${action.type} is a mobile-only gesture` }\n }\n\n case 'tapCoordinate': {\n const vp = page.viewportSize()\n if (vp) {\n warnIfOutOfBounds({ x: action.x, y: action.y }, { width: vp.width, height: vp.height }, 'tapCoordinate')\n }\n await page.mouse.click(action.x, action.y)\n return { success: true, coordinates: { x: action.x, y: action.y } }\n }\n\n case 'executeScript': {\n return { success: false, error: 'executeScript is a mobile-only action' }\n }\n\n case 'hideKeyboard':\n case 'launchApp':\n case 'stopApp':\n case 'setOrientation': {\n return { success: true }\n }\n\n default: {\n return { success: false, error: `Unknown action type: ${(action as any).type}` }\n }\n }\n }\n}\n","import type { Page } from 'playwright-core'\n\nconst SKIP_TAGS = new Set([\n 'SCRIPT', 'STYLE', 'SVG', 'NOSCRIPT', 'LINK', 'META',\n 'TEMPLATE', 'IFRAME',\n])\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nexport function extractDomTree(opts: { maxDepth: number; maxTextLen: number }): string {\n const { maxDepth, maxTextLen } = opts\n const doc = (globalThis as any).document\n const win = (globalThis as any).window\n const lines: string[] = []\n\n function isHidden(el: any): boolean {\n if (!el.offsetParent && el.tagName !== 'BODY' && el.tagName !== 'HTML') {\n const style = win.getComputedStyle(el)\n if (style.display === 'none' || style.visibility === 'hidden') return true\n }\n return false\n }\n\n function walk(node: any, depth: number, indent: string): void {\n if (depth > maxDepth) {\n lines.push(indent + '[... deeper content truncated]')\n return\n }\n\n for (let child = node.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === 3) {\n const text = child.textContent.trim()\n if (text) {\n const truncated = text.length > maxTextLen\n ? text.slice(0, maxTextLen) + '...'\n : text\n lines.push(indent + truncated)\n }\n continue\n }\n\n if (child.nodeType !== 1) continue\n\n const tag = child.tagName\n if (SKIP_TAGS.has(tag)) continue\n if (isHidden(child)) continue\n\n const isCustom = tag.toLowerCase().includes('-')\n const annotation = child.getAttribute('aria-label')\n || child.getAttribute('role')\n || ''\n\n let label = tag.toLowerCase()\n if (isCustom) {\n if (!child.shadowRoot && !child.firstChild) {\n label += ' (custom element, closed shadow root)'\n } else {\n label += ' (custom element)'\n }\n }\n if (annotation) label += ` [${annotation}]`\n\n lines.push(indent + label)\n\n if (child.shadowRoot) {\n lines.push(indent + ' #shadow-root')\n walk(child.shadowRoot, depth + 1, indent + ' ')\n }\n\n walk(child, depth + 1, indent + ' ')\n }\n }\n\n walk(doc.body, 0, '')\n return lines.join('\\n')\n}\n\nexport interface ExtractDomOptions {\n maxDepth?: number\n maxTextLen?: number\n}\n\nexport async function extractDom(\n page: Page,\n opts?: ExtractDomOptions,\n): Promise<string | undefined> {\n const maxDepth = opts?.maxDepth ?? 20\n const maxTextLen = opts?.maxTextLen ?? 200\n\n try {\n return await page.evaluate(extractDomTree, { maxDepth, maxTextLen })\n } catch {\n return undefined\n }\n}\n","import type { Page } from 'playwright-core'\nimport type { ScreenState, ElementInfo } from '@vostride/agent-qa-core'\nimport type { RefMap } from './types.js'\nimport { extractDom } from './dom-extractor.js'\n\nconst INTERACTIVE_ROLES = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox', 'listbox',\n 'menuitem', 'menuitemradio', 'menuitemcheckbox', 'option',\n 'searchbox', 'slider', 'spinbutton', 'switch', 'tab', 'treeitem',\n // WAI-ARIA 1.2 standalone widget roles\n 'gridcell', 'scrollbar', 'separator',\n // WAI-ARIA 1.2 composite widget roles (interactive containers)\n 'grid', 'menu', 'menubar', 'tree', 'treegrid',\n])\n\nconst CONTENT_ROLES = new Set([\n 'heading', 'cell', 'listitem', 'article', 'region', 'navigation',\n 'progressbar', 'tabpanel',\n])\n\nconst LINE_PATTERN = /^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/\n// Playwright wraps ARIA entries in single quotes when element names contain\n// colons or other characters that are ambiguous in its snapshot format.\n// e.g. - 'button \"Spoken Language: Any\"'\nconst QUOTED_LINE_PATTERN = /^(\\s*-\\s*)'(\\w+)(?:\\s+\"([^\"]*)\")?(.*)'\\s*$/\n\nexport function parseAriaSnapshot(ariaTree: string): { tree: string; elements: ElementInfo[]; refs: RefMap } {\n const lines = ariaTree.split('\\n')\n const elements: ElementInfo[] = []\n const refs: RefMap = {}\n const resultLines: string[] = []\n let refCounter = 0\n\n // Track role+name occurrences for disambiguation\n const roleNameCounts = new Map<string, number>()\n const refToKey = new Map<string, string>()\n\n for (const line of lines) {\n const match = line.match(LINE_PATTERN) || line.match(QUOTED_LINE_PATTERN)\n if (!match) {\n resultLines.push(line)\n continue\n }\n\n const [, prefix, role, name, suffix] = match\n const roleLower = role.toLowerCase()\n const shouldGetRef = INTERACTIVE_ROLES.has(roleLower) || CONTENT_ROLES.has(roleLower)\n\n if (!shouldGetRef) {\n resultLines.push(line)\n continue\n }\n\n refCounter++\n const ref = `e${refCounter}`\n const key = `${roleLower}:${name ?? ''}`\n\n const currentCount = roleNameCounts.get(key) ?? 0\n roleNameCounts.set(key, currentCount + 1)\n refToKey.set(ref, key)\n\n refs[ref] = { role: roleLower, name, nth: currentCount }\n\n // Parse attributes from suffix like [level=1], [checked], [disabled]\n const attributes: Record<string, string> = {}\n const attrMatches = suffix?.matchAll(/\\[(\\w+)(?:=([^\\]]*))?\\]/g)\n if (attrMatches) {\n for (const am of attrMatches) {\n attributes[am[1]] = am[2] ?? 'true'\n }\n }\n\n elements.push({ ref, role: roleLower, name: name ?? '', attributes })\n\n let enhanced = `${prefix}${role}`\n if (name) enhanced += ` \"${name}\"`\n enhanced += ` [ref=${ref}]`\n if (suffix?.trim()) enhanced += suffix\n resultLines.push(enhanced)\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n for (const [ref, data] of Object.entries(refs)) {\n const key = refToKey.get(ref)!\n if ((roleNameCounts.get(key) ?? 0) <= 1) {\n delete refs[ref].nth\n }\n }\n\n return { tree: resultLines.join('\\n'), elements, refs }\n}\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nfunction hideAgentQaElements() {\n const doc = (globalThis as any).document\n doc.querySelectorAll('[data-agent-qa-internal]').forEach((el: any) => {\n el.style.display = 'none'\n el.setAttribute('aria-hidden', 'true')\n })\n}\n\nfunction restoreAgentQaElements() {\n const doc = (globalThis as any).document\n doc.querySelectorAll('[data-agent-qa-internal]').forEach((el: any) => {\n el.style.display = ''\n el.removeAttribute('aria-hidden')\n })\n}\n\nexport async function observePage(\n page: Page,\n options?: { filterSelector?: string; extractDom?: boolean },\n): Promise<ScreenState> {\n const viewport = page.viewportSize()\n const locator = options?.filterSelector\n ? page.locator(options.filterSelector)\n : page.locator(':root')\n\n // Hide framework-injected elements from ARIA snapshot\n await page.evaluate(hideAgentQaElements)\n\n let ariaTree: string\n try {\n ariaTree = await locator.ariaSnapshot()\n } finally {\n // Restore framework-injected elements (always, even if snapshot fails)\n await page.evaluate(restoreAgentQaElements)\n }\n\n if (!ariaTree) {\n return {\n tree: '(empty)',\n elements: [],\n url: page.url(),\n timestamp: Date.now(),\n metadata: {\n coordSpace: 'viewport' as const,\n viewportWidth: viewport?.width ?? 0,\n viewportHeight: viewport?.height ?? 0,\n refMap: {},\n },\n }\n }\n\n const { tree, elements, refs } = parseAriaSnapshot(ariaTree)\n\n // Bulk bounding box enrichment — single page.evaluate collects all rects in one DOM call.\n // Previous approach used N sequential getByRole().boundingBox({timeout:500}) calls which\n // all timed out on complex external pages (100+ elements), reporting \"0 visible elements\".\n try {\n const refEntries = Object.entries(refs)\n if (refEntries.length > 0) {\n const refArgs: Array<[string, string, string | undefined, number | undefined]> = refEntries.map(\n ([ref, data]) => [ref, data.role, data.name, data.nth]\n )\n\n type BBoxResult = Array<[string, { x: number; y: number; width: number; height: number } | null]>\n const result = await Promise.race([\n page.evaluate((args: Array<[string, string, string | undefined, number | undefined]>) => {\n const doc = (globalThis as any).document\n const IMPLICIT_ROLES: Record<string, string> = {\n button: 'button', a: 'link', input: 'textbox', select: 'combobox',\n textarea: 'textbox', h1: 'heading', h2: 'heading', h3: 'heading',\n h4: 'heading', h5: 'heading', h6: 'heading', nav: 'navigation',\n main: 'main', aside: 'complementary', footer: 'contentinfo',\n header: 'banner', form: 'form', table: 'table', img: 'img',\n ul: 'list', ol: 'list', li: 'listitem', dialog: 'dialog',\n details: 'group', summary: 'button', progress: 'progressbar',\n meter: 'meter', output: 'status', article: 'article',\n section: 'region', fieldset: 'group', legend: 'legend',\n }\n const INPUT_TYPE_ROLES: Record<string, string> = {\n checkbox: 'checkbox', radio: 'radio', range: 'slider',\n number: 'spinbutton', search: 'searchbox', email: 'textbox',\n tel: 'textbox', url: 'textbox', password: 'textbox',\n }\n\n function getAccessibleName(el: any): string {\n const label = el.getAttribute('aria-label')\n if (label) return label.trim()\n const labelledBy = el.getAttribute('aria-labelledby')\n if (labelledBy) {\n const parts = labelledBy.split(/\\s+/).map((id: string) => {\n const ref = doc.getElementById(id)\n return ref ? (ref.textContent || '').trim() : ''\n }).filter(Boolean)\n if (parts.length) return parts.join(' ')\n }\n const title = el.getAttribute('title')\n if (title) return title.trim()\n const alt = el.getAttribute('alt')\n if (alt) return alt.trim()\n return (el.textContent || '').trim()\n }\n\n function matchesName(elName: string, targetName: string): boolean {\n return elName.toLowerCase().includes(targetName.toLowerCase())\n }\n\n function getImplicitRole(el: any): string | null {\n const tag = el.tagName.toLowerCase()\n if (tag === 'input') {\n const type = (el.getAttribute('type') || 'text').toLowerCase()\n return INPUT_TYPE_ROLES[type] || 'textbox'\n }\n if (tag === 'a' && el.hasAttribute('href')) return 'link'\n return IMPLICIT_ROLES[tag] || null\n }\n\n const results: Array<[string, { x: number; y: number; width: number; height: number } | null]> = []\n for (const [ref, role, name, nth] of args) {\n const candidates: any[] = []\n doc.querySelectorAll(`[role=\"${role}\"]`).forEach((el: any) => candidates.push(el))\n doc.querySelectorAll('*').forEach((el: any) => {\n if (el.getAttribute('role')) return\n if (getImplicitRole(el) === role) candidates.push(el)\n })\n let matched = candidates\n if (name) {\n matched = candidates.filter((el: any) => matchesName(getAccessibleName(el), name))\n }\n const target = matched[nth ?? 0]\n if (target) {\n const rect = target.getBoundingClientRect()\n results.push([ref, {\n x: Math.round(rect.x), y: Math.round(rect.y),\n width: Math.round(rect.width), height: Math.round(rect.height),\n }])\n } else {\n results.push([ref, null])\n }\n }\n return results\n }, refArgs),\n new Promise<null>(resolve => setTimeout(() => resolve(null), 3000)),\n ]) as BBoxResult | null\n\n if (result) {\n for (const [ref, box] of result) {\n if (box) refs[ref].bounds = box\n }\n }\n }\n } catch {\n // Bounding box enrichment is best-effort — never block observation\n }\n\n let domContext: string | undefined\n if (options?.extractDom) {\n try {\n domContext = await extractDom(page)\n } catch {\n // DOM extraction is best-effort\n }\n }\n\n return {\n tree,\n elements,\n url: page.url(),\n timestamp: Date.now(),\n metadata: {\n coordSpace: 'viewport' as const,\n viewportWidth: viewport?.width ?? 0,\n viewportHeight: viewport?.height ?? 0,\n refMap: refs,\n ...(domContext ? { domContext } : {}),\n },\n }\n}\n","import type { Page, Locator } from 'playwright-core'\nimport type { Action } from '@vostride/agent-qa-core'\nimport type { RefMap } from './types.js'\n\nconst ACTIONS_WITHOUT_REF = new Set(['navigate', 'waitFor', 'delay', 'waitForUrl', 'assert'])\n\nexport class ElementResolver {\n constructor(\n private page: Page,\n private refs: RefMap,\n ) {}\n\n resolve(ref: string): Locator {\n const data = this.refs[ref]\n if (!data) {\n throw new Error(`Unknown ref \"${ref}\". Available refs: ${Object.keys(this.refs).join(', ') || 'none'}`)\n }\n\n let locator: Locator\n if (data.name) {\n locator = this.page.getByRole(data.role as any, { name: data.name, exact: true })\n } else {\n locator = this.page.getByRole(data.role as any)\n }\n\n if (data.nth !== undefined) {\n locator = locator.nth(data.nth)\n }\n\n return locator\n }\n\n resolveAction(action: Action): Locator | null {\n if (ACTIONS_WITHOUT_REF.has(action.type)) {\n return null\n }\n\n if ('ref' in action && typeof action.ref === 'string') {\n return this.resolve(action.ref)\n }\n\n return null\n }\n\n async getBoundingBox(ref: string): Promise<{ x: number; y: number; width: number; height: number } | null> {\n try {\n const locator = this.resolve(ref)\n return await locator.boundingBox()\n } catch {\n return null\n }\n }\n}\n","import type { Action } from '@vostride/agent-qa-core'\n\nexport type ValidationResult =\n | { valid: true }\n | { valid: false; error: string; suggestion?: string }\n\nexport class ActionValidationError extends Error {\n readonly suggestion?: string\n\n constructor(message: string, suggestion?: string) {\n super(message)\n this.name = 'ActionValidationError'\n this.suggestion = suggestion\n }\n}\n\nconst FILL_ROLES = new Set(['textbox', 'searchbox', 'spinbutton', 'combobox'])\nconst SELECT_ROLES = new Set(['listbox', 'combobox'])\n\n// Actions that don't target elements — always valid\nconst NO_REF_ACTIONS = new Set(['scroll', 'navigate', 'waitFor', 'delay', 'waitForUrl', 'assert', 'pinch', 'multiTap', 'keyDown', 'keyUp', 'refresh', 'navigateHistory', 'readConsoleLogs', 'readNetworkLogs', 'readCookies', 'setCookies', 'readLocalStorage', 'setLocalStorage', 'executeScript'])\n\n// Actions valid for any role\nconst ANY_ROLE_ACTIONS = new Set(['click', 'hover', 'keypress', 'paste', 'doubleClick', 'rightClick'])\n\nexport function validateAction(action: Action, elementRole: string | undefined): ValidationResult {\n // Actions that don't require an element ref are always valid\n if (NO_REF_ACTIONS.has(action.type)) {\n return { valid: true }\n }\n\n // Actions valid for any role\n if (ANY_ROLE_ACTIONS.has(action.type)) {\n return { valid: true }\n }\n\n // Unknown or missing role — allow with permissive pass (LLM might know better)\n if (!elementRole) {\n return { valid: true }\n }\n\n const role = elementRole.toLowerCase()\n\n if (action.type === 'fill') {\n if (FILL_ROLES.has(role)) {\n return { valid: true }\n }\n if (SELECT_ROLES.has(role)) {\n return {\n valid: false,\n error: `Cannot fill() on a '${role}' element — fill is for text inputs. Try 'select' to choose an option.`,\n suggestion: 'select',\n }\n }\n return {\n valid: false,\n error: `Element ${(action as any).ref} is not fillable (role: ${role}). Use a textbox or input element instead.`,\n suggestion: 'click',\n }\n }\n\n if (action.type === 'clearText') {\n if (FILL_ROLES.has(role)) {\n return { valid: true }\n }\n return {\n valid: false,\n error: `Element ${(action as any).ref} is not fillable (role: ${role}). clearText only works on text inputs. Use a textbox or input element instead.`,\n suggestion: 'click',\n }\n }\n\n if (action.type === 'select') {\n if (SELECT_ROLES.has(role)) {\n return { valid: true }\n }\n if (FILL_ROLES.has(role)) {\n return {\n valid: false,\n error: `Cannot select() on a '${role}' element — select is for lists. Try 'fill' to type a value instead.`,\n suggestion: 'fill',\n }\n }\n return {\n valid: false,\n error: `Cannot select() on a '${role}' element — select is for list/combo elements.`,\n suggestion: 'click',\n }\n }\n\n // Unknown action type — allow (forward-compatible)\n return { valid: true }\n}\n","import type { Page } from 'playwright-core'\n\nexport interface SmartWaitOptions {\n timeout?: number\n}\n\nconst LOADING_SELECTORS = [\n '[aria-busy=\"true\"]',\n '[aria-label*=\"loading\" i]',\n '.loading', '.spinner', '.skeleton',\n '[data-loading]', '[data-testid=\"loading\"]',\n 'progress:not([value])',\n]\n\nexport async function waitForPageReady(page: Page, options?: SmartWaitOptions): Promise<void> {\n const timeout = options?.timeout ?? 10000\n\n await Promise.race([\n runReadinessChecks(page),\n new Promise<void>(resolve => setTimeout(resolve, timeout)),\n ])\n}\n\n// Browser-context functions use (globalThis as any) to access document\n// because the Node tsconfig has no DOM lib — these functions serialize and run in browser\nfunction checkLoadingIndicators(selectors: string[]): boolean {\n const doc = (globalThis as any).document\n return selectors.some((sel: string) => doc.querySelector(sel) !== null)\n}\n\nfunction checkLoadingGone(selectors: string[]): boolean {\n const doc = (globalThis as any).document\n return !selectors.some((sel: string) => doc.querySelector(sel))\n}\n\nfunction checkAnimationsRunning(): boolean {\n const doc = (globalThis as any).document\n return doc.getAnimations().filter((a: any) => a.playState === 'running').length > 0\n}\n\nfunction checkAnimationsSettled(): boolean {\n const doc = (globalThis as any).document\n return doc.getAnimations().filter((a: any) => a.playState === 'running').length === 0\n}\n\nasync function runReadinessChecks(page: Page): Promise<void> {\n // 1. Document ready\n try {\n await page.waitForLoadState('domcontentloaded', { timeout: 5000 })\n } catch {\n // Already loaded or timed out — continue\n }\n\n // 2. Network settle (best effort)\n try {\n await page.waitForLoadState('networkidle', { timeout: 5000 })\n } catch {\n // SPA with websockets or long-polling — proceed anyway\n }\n\n // 3. Loading indicators gone\n try {\n const hasIndicators = await page.evaluate(checkLoadingIndicators, LOADING_SELECTORS)\n\n if (hasIndicators) {\n try {\n await page.waitForFunction(checkLoadingGone, LOADING_SELECTORS, { timeout: 3000 })\n } catch {\n // Indicators didn't clear in 3s — proceed anyway\n }\n }\n } catch {\n // page.evaluate failed (navigation in progress, context destroyed) — continue\n }\n\n // 4. Animations settled\n try {\n const hasRunning = await page.evaluate(checkAnimationsRunning)\n\n if (hasRunning) {\n try {\n await page.waitForFunction(checkAnimationsSettled, undefined, { timeout: 2000 })\n } catch {\n // Animations didn't settle in 2s — proceed anyway\n }\n }\n } catch {\n // page.evaluate failed — continue\n }\n}\n","import type { Page } from 'playwright-core'\n\ninterface ScrollRefData {\n role: string\n name?: string\n nth?: number\n}\n\ninterface ScrollResult {\n bounds: { x: number; y: number; width: number; height: number } | null\n scrolledContainer: 'element' | 'ancestor' | 'documentElement' | 'notFound'\n scrolled: boolean\n}\n\nexport async function scrollWithRef(\n page: Page,\n refData: ScrollRefData,\n deltaX: number,\n deltaY: number,\n scrollAxis: 'horizontal' | 'vertical',\n): Promise<ScrollResult> {\n return page.evaluate(\n (args: [string, string | undefined, number, number, number, string]) => {\n const [role, name, nth, dx, dy, axis] = args\n const doc = (globalThis as any).document\n const win = (globalThis as any).window\n\n const IMPLICIT_ROLES: Record<string, string> = {\n button: 'button', a: 'link', input: 'textbox', select: 'combobox',\n textarea: 'textbox', h1: 'heading', h2: 'heading', h3: 'heading',\n h4: 'heading', h5: 'heading', h6: 'heading', nav: 'navigation',\n main: 'main', aside: 'complementary', footer: 'contentinfo',\n header: 'banner', form: 'form', table: 'table', img: 'img',\n ul: 'list', ol: 'list', li: 'listitem', dialog: 'dialog',\n details: 'group', summary: 'button', progress: 'progressbar',\n meter: 'meter', output: 'status', article: 'article',\n section: 'region', fieldset: 'group', legend: 'legend',\n }\n const INPUT_TYPE_ROLES: Record<string, string> = {\n checkbox: 'checkbox', radio: 'radio', range: 'slider',\n number: 'spinbutton', search: 'searchbox', email: 'textbox',\n tel: 'textbox', url: 'textbox', password: 'textbox',\n }\n\n function getAccessibleName(el: any): string {\n const label = el.getAttribute('aria-label')\n if (label) return label.trim()\n const labelledBy = el.getAttribute('aria-labelledby')\n if (labelledBy) {\n const parts = labelledBy.split(/\\s+/).map((id: string) => {\n const ref = doc.getElementById(id)\n return ref ? (ref.textContent || '').trim() : ''\n }).filter(Boolean)\n if (parts.length) return parts.join(' ')\n }\n const title = el.getAttribute('title')\n if (title) return title.trim()\n const alt = el.getAttribute('alt')\n if (alt) return alt.trim()\n return (el.textContent || '').trim()\n }\n\n function getImplicitRole(el: any): string | null {\n const tag = el.tagName.toLowerCase()\n if (tag === 'input') {\n const type = (el.getAttribute('type') || 'text').toLowerCase()\n return INPUT_TYPE_ROLES[type] || 'textbox'\n }\n if (tag === 'a' && el.hasAttribute('href')) return 'link'\n return IMPLICIT_ROLES[tag] || null\n }\n\n const candidates: any[] = []\n doc.querySelectorAll(`[role=\"${role}\"]`).forEach((el: any) => candidates.push(el))\n doc.querySelectorAll('*').forEach((el: any) => {\n if (el.getAttribute('role')) return\n if (getImplicitRole(el) === role) candidates.push(el)\n })\n\n let matched = candidates\n if (name) {\n matched = candidates.filter((el: any) =>\n getAccessibleName(el).toLowerCase().includes(name.toLowerCase())\n )\n }\n\n const target = matched[nth]\n if (!target) {\n win.scrollBy(dx, dy)\n return { bounds: null, scrolledContainer: 'notFound' as const, scrolled: true }\n }\n\n // Check target element itself for scrollability\n const targetStyle = win.getComputedStyle(target)\n const targetOverflow = axis === 'horizontal' ? targetStyle.overflowX : targetStyle.overflowY\n const targetScrollable = targetOverflow === 'auto' || targetOverflow === 'scroll' || targetOverflow === 'hidden'\n const targetHasContent = axis === 'horizontal'\n ? target.scrollWidth > target.clientWidth\n : target.scrollHeight > target.clientHeight\n if (targetScrollable && targetHasContent) {\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = target[prop]\n target.scrollBy(dx, dy)\n const after = target[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'element' as const,\n scrolled: before !== after,\n }\n }\n\n // Walk ancestors\n let parent = target.parentElement\n while (parent && parent !== doc.documentElement) {\n const style = win.getComputedStyle(parent)\n const overflow = axis === 'horizontal' ? style.overflowX : style.overflowY\n const isScrollable = overflow === 'auto' || overflow === 'scroll' || overflow === 'hidden'\n const hasContent = axis === 'horizontal'\n ? parent.scrollWidth > parent.clientWidth\n : parent.scrollHeight > parent.clientHeight\n if (isScrollable && hasContent) {\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = parent[prop]\n parent.scrollBy(dx, dy)\n const after = parent[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'ancestor' as const,\n scrolled: before !== after,\n }\n }\n parent = parent.parentElement\n }\n\n const prop = axis === 'horizontal' ? 'scrollLeft' : 'scrollTop'\n const before = doc.documentElement[prop]\n doc.documentElement.scrollBy(dx, dy)\n const after = doc.documentElement[prop]\n const rect = target.getBoundingClientRect()\n return {\n bounds: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },\n scrolledContainer: 'documentElement' as const,\n scrolled: before !== after,\n }\n },\n [refData.role, refData.name, refData.nth ?? 0, deltaX, deltaY, scrollAxis] as [string, string | undefined, number, number, number, string],\n )\n}\n","type BrowserName = 'chromium' | 'firefox' | 'webkit'\n\nfunction displayBrowserName(browserName: BrowserName): string {\n if (browserName === 'chromium') return 'Chromium'\n if (browserName === 'firefox') return 'Firefox'\n return 'WebKit'\n}\n\nexport function isPlaywrightMissingBrowserError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error)\n const lower = message.toLowerCase()\n return lower.includes(\"executable doesn't exist\")\n && lower.includes('playwright')\n && lower.includes('install')\n}\n\nexport function formatMissingBrowserError(browserName: BrowserName): string {\n return [\n `agent-qa browser support is not installed for ${displayBrowserName(browserName)}.`,\n '',\n 'Install the browser managed by agent-qa, then rerun the test:',\n ` agent-qa install-browsers --${browserName}`,\n '',\n 'This can happen after upgrading agent-qa or Playwright because browser binaries live outside the package install.',\n ].join('\\n')\n}\n","import type { Browser, BrowserContext, Page } from 'playwright-core'\nimport type { PlatformAdapter, PlatformConfig, ScreenState, Action, ActionResult, ObserveOptions, ConsoleLogEntry, NetworkLogEntry } from '@vostride/agent-qa-core'\nimport { getProvider, registerAllProviders } from '@vostride/agent-qa-core'\nimport { convertKeysForPlatform, isMacPlatform } from '@vostride/agent-qa-core'\nimport type { FarmWebConfig } from '@vostride/agent-qa-core'\nimport { observePage } from './observer.js'\nimport { ElementResolver } from './element-resolver.js'\nimport { validateAction } from './action-validator.js'\nimport { waitForPageReady } from './smart-wait.js'\nimport { scrollWithRef } from './scroll-helper.js'\nimport type { RefMap } from './types.js'\n\ninterface PageLogBuffers {\n consoleLogs: ConsoleLogEntry[]\n networkLogs: NetworkLogEntry[]\n consoleDrainIndex: number\n networkDrainIndex: number\n pendingRequests: Map<string, { url: string; method: string; headers: Record<string, string>; startTime: number; postData?: string }>\n}\n\nfunction clickDelayOption(clickDelay?: number): { delay?: number } {\n return clickDelay !== undefined && clickDelay > 0 ? { delay: clickDelay } : {}\n}\n\nexport class FarmWebAdapter implements PlatformAdapter {\n readonly platform = 'web' as const\n\n private browser: Browser | null = null\n private context: BrowserContext | null = null\n private page: Page | null = null\n private lastRefs: RefMap = {}\n private sessionUrl: string | undefined\n private sessionId: string | undefined\n private testFailed = false\n private exitHandler: (() => void) | null = null\n private credentials: { username: string; accessKey: string } | null = null\n private pageLogBuffers = new Map<Page, PageLogBuffers>()\n private logCaptureConfig: { console: boolean; network: boolean } = { console: true, network: true }\n\n async setup(config: PlatformConfig): Promise<void> {\n if (!config.farmSession) {\n throw new Error('FarmWebAdapter requires config.farmSession to be set')\n }\n\n registerAllProviders()\n const provider = getProvider('browserstack')\n if (!provider) {\n throw new Error('Unknown farm provider: browserstack')\n }\n\n this.credentials = provider.resolveCredentials(config.farmSession.capabilities as any)\n if (!config.browser?.name) {\n throw new Error('FarmWebAdapter requires config.browser.name to be set')\n }\n const credentials = this.credentials\n\n const farmWebConfig: FarmWebConfig = {\n browser: config.browser,\n credentials,\n testName: (config.farmSession.capabilities as any)?.testName,\n }\n\n const { wsEndpoint } = await provider.resolveWebEndpoint(farmWebConfig)\n\n const { chromium } = await import('playwright-core')\n this.browser = await chromium.connect({ wsEndpoint })\n\n const contextOptions: Record<string, unknown> = {\n viewport: config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n if (config.recording?.enabled) {\n contextOptions.recordVideo = {\n dir: config.recording.videoDir,\n size: config.recording.videoSize ?? config.browser?.viewport ?? { width: 1280, height: 720 },\n }\n }\n if (config.authState?.storageStatePath) {\n contextOptions.storageState = config.authState.storageStatePath\n }\n this.context = await this.browser.newContext(contextOptions)\n\n // Clipboard write permission — farm-adapter always uses chromium (see chromium.connect above)\n await this.context.grantPermissions(['clipboard-write'])\n\n this.page = await this.context.newPage()\n\n try {\n const cdpSession = await this.page.context().newCDPSession(this.page)\n const result = await cdpSession.send('Browser.getVersion') as Record<string, string>\n await cdpSession.detach()\n // BrowserStack includes session info in the debugger URL or we extract from the WSS endpoint\n // Use REST API to get session details\n const auth = Buffer.from(`${credentials.username}:${credentials.accessKey}`).toString('base64')\n const resp = await fetch('https://api.browserstack.com/automate/builds.json?limit=1&status=running', {\n headers: { Authorization: `Basic ${auth}` },\n })\n if (resp.ok) {\n const builds = await resp.json() as Array<{ automation_build: { hashed_id: string; name: string } }>\n if (builds.length > 0) {\n const buildId = builds[0].automation_build.hashed_id\n const sessResp = await fetch(`https://api.browserstack.com/automate/builds/${buildId}/sessions.json?limit=1`, {\n headers: { Authorization: `Basic ${auth}` },\n })\n if (sessResp.ok) {\n const sessions = await sessResp.json() as Array<{ automation_session: { hashed_id: string; browser_url: string } }>\n if (sessions.length > 0) {\n this.sessionId = sessions[0].automation_session.hashed_id\n this.sessionUrl = sessions[0].automation_session.browser_url\n }\n }\n }\n }\n } catch {\n // Session details extraction is best-effort\n }\n\n this.exitHandler = () => {\n try {\n this.browser?.close()\n } catch {\n // Best-effort cleanup on exit\n }\n }\n process.on('exit', this.exitHandler)\n\n this.logCaptureConfig = { console: config.logCapture?.console !== false, network: config.logCapture?.network !== false }\n this.attachLogListeners(this.page)\n }\n\n async cleanup(): Promise<void> {\n if (this.browser) {\n await this.browser.close()\n }\n\n // Set session status via REST API after browser is closed\n if (this.sessionId && this.credentials) {\n try {\n const status = this.testFailed ? 'failed' : 'passed'\n const reason = this.testFailed ? 'Test failed' : 'Test passed'\n const auth = Buffer.from(`${this.credentials.username}:${this.credentials.accessKey}`).toString('base64')\n await fetch(`https://api.browserstack.com/automate/sessions/${this.sessionId}.json`, {\n method: 'PUT',\n headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },\n body: JSON.stringify({ status, reason }),\n })\n } catch {\n // Status reporting is best-effort\n }\n }\n\n if (this.exitHandler) {\n process.removeListener('exit', this.exitHandler)\n this.exitHandler = null\n }\n\n this.browser = null\n this.context = null\n this.page = null\n this.lastRefs = {}\n this.pageLogBuffers.clear()\n }\n\n async observe(options?: ObserveOptions): Promise<ScreenState> {\n if (!this.page) {\n throw new Error('FarmWebAdapter not initialized — call setup() first')\n }\n\n await waitForPageReady(this.page)\n const state = await observePage(this.page, {\n extractDom: options?.extractDom,\n })\n this.lastRefs = (state.metadata.refMap as RefMap) ?? {}\n return state\n }\n\n async execute(action: Action): Promise<ActionResult> {\n if (!this.page) {\n throw new Error('FarmWebAdapter not initialized — call setup() first')\n }\n\n try {\n return await this.executeAction(action)\n } catch (err) {\n let screenshot: Buffer | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n try {\n screenshot = await this.page.screenshot()\n } catch {\n // ignore screenshot failure\n }\n try {\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const resolver = new ElementResolver(this.page, this.lastRefs)\n const box = await resolver.getBoundingBox((action as any).ref)\n if (box) boundingBox = box\n }\n } catch {\n // ignore bounding box failure\n }\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n screenshot,\n boundingBox,\n }\n }\n }\n\n async screenshot(): Promise<Buffer | undefined> {\n try {\n if (this.page) {\n return await this.page.screenshot()\n }\n return undefined\n } catch {\n return undefined\n }\n }\n\n getPage(): Page | null {\n return this.page\n }\n\n async getVideoPath(): Promise<string | null> {\n try {\n const video = this.page?.video()\n if (!video) return null\n return await video.path()\n } catch {\n return null\n }\n }\n\n markFailed(): void {\n this.testFailed = true\n }\n\n getSessionUrl(): string | undefined {\n return this.sessionUrl\n }\n\n getSessionId(): string | undefined {\n return this.sessionId\n }\n\n drainConsoleLogs(level?: string): ConsoleLogEntry[] {\n const all: ConsoleLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.consoleLogs.slice(buffers.consoleDrainIndex)\n buffers.consoleDrainIndex = buffers.consoleLogs.length\n all.push(...newLogs)\n }\n if (!level) return all\n return all.filter(e => e.level === level)\n }\n\n drainNetworkLogs(urlPattern?: string): NetworkLogEntry[] {\n const all: NetworkLogEntry[] = []\n for (const buffers of this.pageLogBuffers.values()) {\n const newLogs = buffers.networkLogs.slice(buffers.networkDrainIndex)\n buffers.networkDrainIndex = buffers.networkLogs.length\n all.push(...newLogs)\n }\n if (!urlPattern) return all\n return all.filter(e => e.url.includes(urlPattern))\n }\n\n private attachLogListeners(page: Page): void {\n const buffers: PageLogBuffers = {\n consoleLogs: [],\n networkLogs: [],\n consoleDrainIndex: 0,\n networkDrainIndex: 0,\n pendingRequests: new Map(),\n }\n this.pageLogBuffers.set(page, buffers)\n\n if (this.logCaptureConfig.console) {\n page.on('console', (msg) => {\n buffers.consoleLogs.push({\n level: msg.type(),\n text: msg.text(),\n location: msg.location(),\n timestamp: Date.now(),\n })\n if (buffers.consoleLogs.length > 1000) {\n buffers.consoleLogs = buffers.consoleLogs.slice(-500)\n }\n })\n }\n\n if (this.logCaptureConfig.network) {\n page.on('request', (request) => {\n buffers.pendingRequests.set(request.url() + request.method(), {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n startTime: Date.now(),\n postData: request.postData() ?? undefined,\n })\n })\n\n page.on('response', async (response) => {\n const key = response.url() + response.request().method()\n const pending = buffers.pendingRequests.get(key)\n buffers.pendingRequests.delete(key)\n\n let body: string | undefined\n try {\n const buf = await response.body()\n const ct = response.headers()['content-type'] ?? ''\n if (ct.includes('image/') && !ct.includes('svg')) {\n body = buf.length > 32768 ? undefined : `data:${ct.split(';')[0]};base64,${buf.toString('base64')}`\n } else {\n const text = buf.toString('utf-8')\n body = text.length > 32768 ? text.slice(0, 32768) + '...[truncated]' : text\n }\n } catch {\n body = undefined\n }\n\n buffers.networkLogs.push({\n url: response.url(),\n method: response.request().method(),\n status: response.status(),\n requestHeaders: pending?.headers ?? response.request().headers(),\n responseHeaders: response.headers(),\n body,\n requestBody: pending?.postData,\n startTime: pending?.startTime ?? Date.now(),\n endTime: Date.now(),\n timing: response.request().timing(),\n })\n if (buffers.networkLogs.length > 500) {\n buffers.networkLogs = buffers.networkLogs.slice(-250)\n }\n })\n }\n }\n\n private async resolveTabTargetAsync(tab: { index?: number; title?: string; url?: string }): Promise<Page | undefined> {\n const pages = this.context!.pages()\n if (tab.index !== undefined) {\n return (tab.index >= 0 && tab.index < pages.length) ? pages[tab.index] : undefined\n }\n if (tab.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(tab.title)) return p\n }\n return undefined\n }\n if (tab.url) {\n return pages.find(p => p.url().includes(tab.url!))\n }\n return undefined\n }\n\n private async executeAction(action: Action): Promise<ActionResult> {\n const page = this.page!\n const resolver = new ElementResolver(page, this.lastRefs)\n\n if ('ref' in action && typeof (action as any).ref === 'string') {\n const refData = this.lastRefs[(action as any).ref]\n const role = refData?.role\n const validation = validateAction(action, role)\n if (!validation.valid) {\n return { success: false, error: validation.error }\n }\n }\n\n switch (action.type) {\n case 'click': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box ? { x: box.x + box.width / 2, y: box.y + box.height / 2 } : undefined\n await locator.click({\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'fill': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.fill(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'select': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.selectOption(action.value)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'navigate': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'scroll': {\n const deltaX = action.scrollType === 'horizontal' ? action.value : 0\n const deltaY = action.scrollType === 'vertical' ? action.value : 0\n let coordinates: { x: number; y: number } | undefined\n let boundingBox: { x: number; y: number; width: number; height: number } | undefined\n let scrollData: { scrolled: boolean; scrolledContainer: string } | undefined\n\n if (action.ref) {\n const refData = this.lastRefs[action.ref]\n if (refData) {\n const scrollAxis = action.scrollType === 'horizontal' ? 'horizontal' : 'vertical'\n const result = await scrollWithRef(page, refData, deltaX, deltaY, scrollAxis)\n if (result.bounds) {\n coordinates = { x: result.bounds.x + result.bounds.width / 2, y: result.bounds.y + result.bounds.height / 2 }\n boundingBox = result.bounds\n }\n scrollData = { scrolled: result.scrolled, scrolledContainer: result.scrolledContainer }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n } else {\n await page.mouse.wheel(deltaX, deltaY)\n }\n\n await page.evaluate(`new Promise(resolve => {\n const t = setTimeout(() => resolve('timeout'), 500);\n requestAnimationFrame(() => requestAnimationFrame(() => {\n clearTimeout(t);\n resolve('raf');\n }));\n })`)\n\n return { success: true, coordinates, boundingBox, data: scrollData }\n }\n\n case 'waitFor': {\n const timeout = action.timeout ?? 5000\n try {\n await page.waitForFunction(\n `document.body && document.body.innerText.includes(${JSON.stringify(action.condition)})`,\n { timeout },\n )\n } catch {\n try {\n await page.waitForSelector(action.condition, { timeout })\n } catch {\n // Best-effort\n }\n }\n return { success: true }\n }\n\n case 'delay': {\n await page.waitForTimeout(action.ms)\n return { success: true }\n }\n\n case 'waitForUrl': {\n try {\n // Explicit 30s timeout overrides Playwright's infinite default (Pitfall 2)\n await page.waitForURL(action.pattern, { timeout: 30_000 })\n return { success: true }\n } catch (err) {\n return {\n success: false,\n error: `URL pattern \"${action.pattern}\" did not match within 30s. Hint: use \"**\" wildcards for substring matching (e.g., \"**/dashboard**\"). ${err instanceof Error ? err.message : String(err)}`,\n }\n }\n }\n\n case 'keypress': {\n const effectiveKeys = convertKeysForPlatform(action.keys, {\n enabled: action.convertPlatformKeys !== false,\n isMac: isMacPlatform(),\n })\n for (const key of effectiveKeys) {\n await page.keyboard.press(key)\n }\n return { success: true }\n }\n\n case 'hover': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.hover()\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'paste': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.focus()\n await page.evaluate(`(() => {\n const el = document.activeElement;\n if (!el) return;\n const dt = new DataTransfer();\n dt.setData('text/plain', ${JSON.stringify(action.value)});\n el.dispatchEvent(new ClipboardEvent('paste', {\n clipboardData: dt,\n bubbles: true,\n cancelable: true,\n }));\n })()`)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'fileUpload': {\n // Paths are pre-resolved to absolute by runner loop.ts (see Plan 01 Task 2)\n const { existsSync } = await import('node:fs')\n for (const filePath of action.files) {\n if (!existsSync(filePath)) {\n return { success: false, error: `File not found: ${filePath}` }\n }\n }\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n await locator.setInputFiles(action.files)\n return { success: true, boundingBox: box ?? undefined }\n }\n\n case 'copy': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const text = (await locator.textContent()) ?? ''\n await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(text)})`)\n return { success: true, boundingBox: box ?? undefined, data: { copied: text } }\n }\n\n case 'keyDown': {\n await page.keyboard.down(action.key)\n return { success: true }\n }\n\n case 'keyUp': {\n await page.keyboard.up(action.key)\n return { success: true }\n }\n\n case 'refresh': {\n await page.reload({ waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'navigateHistory': {\n if (action.direction === 'back') {\n await page.goBack({ waitUntil: 'domcontentloaded' })\n } else {\n await page.goForward({ waitUntil: 'domcontentloaded' })\n }\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'readConsoleLogs': {\n let entries: ConsoleLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.consoleLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.consoleLogs)\n }\n }\n if (action.level) {\n entries = entries.filter(e => e.level === action.level)\n }\n return { success: true, data: entries }\n }\n\n case 'readNetworkLogs': {\n let entries: NetworkLogEntry[]\n if (action.tab) {\n const targetPage = await this.resolveTabTargetAsync(action.tab)\n if (!targetPage) {\n return { success: false, error: `No tab found matching ${JSON.stringify(action.tab)}` }\n }\n const buffers = this.pageLogBuffers.get(targetPage)\n entries = buffers ? [...buffers.networkLogs] : []\n } else {\n entries = []\n for (const buffers of this.pageLogBuffers.values()) {\n entries.push(...buffers.networkLogs)\n }\n }\n if (action.urlPattern) {\n entries = entries.filter(e => e.url.includes(action.urlPattern!))\n }\n return { success: true, data: entries }\n }\n\n case 'readCookies': {\n const cookies = await this.context!.cookies()\n if (action.name) {\n const cookie = cookies.find(c => c.name === action.name) ?? null\n return { success: true, data: cookie }\n }\n return { success: true, data: cookies }\n }\n\n case 'setCookies': {\n const cookiesWithDefaults = action.cookies.map(c => ({\n ...c,\n url: !c.domain ? page.url() : undefined,\n }))\n await this.context!.addCookies(cookiesWithDefaults)\n return { success: true }\n }\n\n case 'readLocalStorage': {\n const pageUrl = page.url()\n if (pageUrl === 'about:blank') {\n return { success: true, data: action.key ? null : {} }\n }\n if (action.key) {\n const value = await page.evaluate(\n (k: string) => localStorage.getItem(k), action.key\n )\n return { success: true, data: value }\n }\n const all = await page.evaluate(\n () => Object.fromEntries(\n Object.keys(localStorage).map(k => [k, localStorage.getItem(k)])\n )\n )\n return { success: true, data: all }\n }\n\n case 'setLocalStorage': {\n await page.evaluate((entries: Array<{ key: string; value: string }>) => {\n for (const { key, value } of entries) {\n localStorage.setItem(key, value)\n }\n }, action.entries)\n return { success: true }\n }\n\n case 'assert': {\n return { success: true }\n }\n\n case 'clearText': {\n const loc = resolver.resolve(action.ref)\n const clearBox = await resolver.getBoundingBox(action.ref)\n await loc.clear()\n return { success: true, boundingBox: clearBox ?? undefined }\n }\n\n case 'drag': {\n const fromLoc = resolver.resolve(action.fromRef)\n const toLoc = resolver.resolve(action.toRef)\n await fromLoc.dragTo(toLoc)\n return { success: true }\n }\n\n case 'doubleTap': {\n const dblLoc = resolver.resolve(action.ref)\n const dblBox = await resolver.getBoundingBox(action.ref)\n await dblLoc.dblclick()\n return { success: true, boundingBox: dblBox ?? undefined }\n }\n\n case 'doubleClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.dblclick({\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'rightClick': {\n const locator = resolver.resolve(action.ref)\n const box = await resolver.getBoundingBox(action.ref)\n const coordinates = box\n ? action.relativePosition\n ? { x: box.x + action.relativePosition.x, y: box.y + action.relativePosition.y }\n : { x: box.x + box.width / 2, y: box.y + box.height / 2 }\n : undefined\n await locator.click({\n button: 'right',\n ...(action.relativePosition && { position: action.relativePosition }),\n ...clickDelayOption(action.clickDelay),\n })\n return { success: true, coordinates, boundingBox: box ?? undefined }\n }\n\n case 'openLink': {\n await page.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(page)\n return { success: true }\n }\n\n case 'newTab': {\n const newPage = await this.context!.newPage()\n this.attachLogListeners(newPage)\n await newPage.goto(action.url, { waitUntil: 'domcontentloaded' })\n await waitForPageReady(newPage)\n this.page = newPage\n return { success: true }\n }\n\n case 'switchTab': {\n const pages = this.context!.pages()\n\n let target: Page | undefined\n\n if (action.index !== undefined) {\n if (action.index < 0 || action.index >= pages.length) {\n return { success: false, error: `Tab index ${action.index} out of range (${pages.length} tabs open)` }\n }\n target = pages[action.index]\n } else if (action.title) {\n for (const p of pages) {\n const t = await p.title()\n if (t.includes(action.title)) { target = p; break }\n }\n } else if (action.url) {\n target = pages.find(p => p.url().includes(action.url!))\n } else {\n return { success: false, error: 'switchTab requires at least one of: index, title, or url' }\n }\n\n if (!target) {\n return { success: false, error: `No tab found matching ${JSON.stringify({ index: action.index, title: action.title, url: action.url })}` }\n }\n\n this.page = target\n return { success: true }\n }\n\n case 'tap':\n case 'swipe':\n case 'longpress':\n case 'pinch':\n case 'multiTap': {\n return { success: false, error: `${action.type} is a mobile-only gesture` }\n }\n\n case 'tapCoordinate': {\n await page.mouse.click(action.x, action.y)\n return { success: true, coordinates: { x: action.x, y: action.y } }\n }\n\n case 'hideKeyboard':\n case 'launchApp':\n case 'stopApp':\n case 'setOrientation': {\n return { success: true }\n }\n\n default: {\n return { success: false, error: `Unknown action type: ${(action as any).type}` }\n }\n }\n }\n}\n","import { AxeBuilder } from '@axe-core/playwright'\nimport type { Page } from 'playwright-core'\nimport type { AccessibilityViolation } from '@vostride/agent-qa-core'\n\nexport interface AccessibilityOptions {\n standard?: 'wcag2a' | 'wcag2aa' | 'wcag2aaa'\n disableRules?: string[]\n exclude?: string[]\n}\n\nexport async function runAccessibilityCheck(\n page: Page,\n options?: AccessibilityOptions,\n): Promise<AccessibilityViolation[]> {\n let builder = new AxeBuilder({ page })\n\n if (options?.standard) {\n const tagMap: Record<string, string[]> = {\n 'wcag2a': ['wcag2a'],\n 'wcag2aa': ['wcag2a', 'wcag2aa'],\n 'wcag2aaa': ['wcag2a', 'wcag2aa', 'wcag2aaa'],\n }\n builder = builder.withTags(tagMap[options.standard] ?? ['wcag2a', 'wcag2aa'])\n }\n\n if (options?.disableRules?.length) {\n builder = builder.disableRules(options.disableRules)\n }\n\n if (options?.exclude?.length) {\n for (const selector of options.exclude) {\n builder = builder.exclude(selector)\n }\n }\n\n const results = await builder.analyze()\n\n return results.violations.map(v => ({\n ruleId: v.id,\n impact: v.impact as AccessibilityViolation['impact'],\n description: v.description,\n help: v.help,\n helpUrl: v.helpUrl,\n nodes: v.nodes.slice(0, 10).map(n => ({\n html: n.html,\n target: n.target as string[],\n })),\n }))\n}\n"],"mappings":"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","names":["prop","before","after","rect","import_agent_qa_core","clickDelayOption"]}
|