@ricsam/isolate-playwright 0.1.13 → 0.1.15
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/README.md +47 -2
- package/dist/cjs/client.cjs +5 -1095
- package/dist/cjs/client.cjs.map +3 -3
- package/dist/cjs/handler.cjs +1406 -0
- package/dist/cjs/handler.cjs.map +10 -0
- package/dist/cjs/index.cjs +378 -1082
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/types.cjs.map +1 -1
- package/dist/mjs/client.mjs +5 -1093
- package/dist/mjs/client.mjs.map +3 -3
- package/dist/mjs/handler.mjs +1378 -0
- package/dist/mjs/handler.mjs.map +10 -0
- package/dist/mjs/index.mjs +382 -1079
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/types.mjs.map +1 -1
- package/dist/types/client.d.ts +2 -19
- package/dist/types/handler.d.ts +44 -0
- package/dist/types/index.d.ts +4 -86
- package/dist/types/types.d.ts +3 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import ivm from \"isolated-vm\";\nimport type { Page, Locator as PlaywrightLocator, BrowserContext, BrowserContextOptions } from \"playwright\";\nimport type {\n PlaywrightOperation,\n PlaywrightResult,\n PlaywrightEvent,\n PlaywrightFileData,\n} from \"@ricsam/isolate-protocol\";\nimport {\n DEFAULT_PLAYWRIGHT_HANDLER_META,\n type DefaultPlaywrightHandler,\n type DefaultPlaywrightHandlerMetadata,\n type DefaultPlaywrightHandlerOptions,\n} from \"./types.cjs\";\n\n// Re-export protocol types\nexport type { PlaywrightOperation, PlaywrightResult, PlaywrightEvent, PlaywrightFileData } from \"@ricsam/isolate-protocol\";\nexport { DEFAULT_PLAYWRIGHT_HANDLER_META };\n\n// ============================================================================\n// File I/O Callback Types (for secure file access)\n// ============================================================================\n\nexport type ReadFileCallback = (filePath: string) => Promise<PlaywrightFileData> | PlaywrightFileData;\nexport type WriteFileCallback = (filePath: string, data: Buffer) => Promise<void> | void;\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\nexport interface NetworkRequestInfo {\n url: string;\n method: string;\n headers: Record<string, string>;\n postData?: string;\n resourceType: string;\n timestamp: number;\n}\n\nexport interface NetworkResponseInfo {\n url: string;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n timestamp: number;\n}\n\n/**\n * Browser console log entry - logs from the page context (not sandbox).\n */\nexport interface BrowserConsoleLogEntry {\n level: string;\n stdout: string;\n timestamp: number;\n}\n\n/**\n * Callback type for handling playwright operations.\n * Used for remote execution where the page lives on the client.\n */\nexport type PlaywrightCallback = (\n op: PlaywrightOperation\n) => Promise<PlaywrightResult>;\n\n/**\n * Options for setting up playwright in an isolate.\n */\nexport interface PlaywrightSetupOptions {\n /** Direct page object (for local use) */\n page?: Page;\n /** Handler callback (for remote use - daemon invokes this) */\n handler?: PlaywrightCallback;\n /** Default timeout for operations */\n timeout?: number;\n /** If true, browser console logs are printed to stdout */\n console?: boolean;\n /** Unified event callback for all playwright events */\n onEvent?: (event: PlaywrightEvent) => void;\n /**\n * Callback invoked when context.newPage() is called from within the isolate.\n * Host creates/configures the new page. If not provided, newPage() will throw an error.\n * Receives the BrowserContext so you can call context.newPage().\n * @param context - The BrowserContext that requested the new page\n * @returns The new Page object\n */\n createPage?: (context: BrowserContext) => Promise<Page> | Page;\n /**\n * Callback invoked when browser.newContext() is called from within the isolate.\n * Host creates/configures the new context. If not provided, newContext() will throw an error.\n * @param options - Browser context options passed from the isolate\n * @returns The new BrowserContext object\n */\n createContext?: (options?: BrowserContextOptions) => Promise<BrowserContext> | BrowserContext;\n}\n\nexport interface PlaywrightHandle {\n dispose(): void;\n /** Get browser console logs (from the page, not sandbox) */\n getBrowserConsoleLogs(): BrowserConsoleLogEntry[];\n getNetworkRequests(): NetworkRequestInfo[];\n getNetworkResponses(): NetworkResponseInfo[];\n clearCollected(): void;\n}\n\n// ============================================================================\n// Helper: Get locator from selector info\n// ============================================================================\n\nfunction getLocator(\n page: Page,\n selectorType: string,\n selectorValue: string,\n optionsJson: string | null\n): PlaywrightLocator {\n // Parse options and extract nth if present\n const options = optionsJson ? JSON.parse(optionsJson) : undefined;\n const nthIndex = options?.nth;\n\n // For role selectors, pass options (excluding nth) to getByRole\n const roleOptions = options ? { ...options } : undefined;\n if (roleOptions) {\n delete roleOptions.nth;\n delete roleOptions.filter;\n // Deserialize regex name\n if (roleOptions.name && typeof roleOptions.name === 'object' && roleOptions.name.$regex) {\n roleOptions.name = new RegExp(roleOptions.name.$regex, roleOptions.name.$flags);\n }\n }\n\n let locator: PlaywrightLocator;\n switch (selectorType) {\n case \"css\":\n locator = page.locator(selectorValue);\n break;\n case \"role\":\n locator = page.getByRole(\n selectorValue as Parameters<Page[\"getByRole\"]>[0],\n roleOptions && Object.keys(roleOptions).length > 0 ? roleOptions : undefined\n );\n break;\n case \"text\":\n locator = page.getByText(selectorValue);\n break;\n case \"label\":\n locator = page.getByLabel(selectorValue);\n break;\n case \"placeholder\":\n locator = page.getByPlaceholder(selectorValue);\n break;\n case \"testId\":\n locator = page.getByTestId(selectorValue);\n break;\n case \"or\": {\n // Composite locator: selectorValue is JSON array of [firstInfo, secondInfo]\n const [firstInfo, secondInfo] = JSON.parse(selectorValue) as [[string, string, string | null], [string, string, string | null]];\n const first = getLocator(page, firstInfo[0], firstInfo[1], firstInfo[2]);\n const second = getLocator(page, secondInfo[0], secondInfo[1], secondInfo[2]);\n locator = first.or(second);\n break;\n }\n case \"and\": {\n // Composite locator: selectorValue is JSON array of [firstInfo, secondInfo]\n const [firstInfo, secondInfo] = JSON.parse(selectorValue) as [[string, string, string | null], [string, string, string | null]];\n const first = getLocator(page, firstInfo[0], firstInfo[1], firstInfo[2]);\n const second = getLocator(page, secondInfo[0], secondInfo[1], secondInfo[2]);\n locator = first.and(second);\n break;\n }\n case \"chained\": {\n // Chained locator: selectorValue is JSON array of [parentInfo, childInfo]\n const [parentInfo, childInfo] = JSON.parse(selectorValue) as [[string, string, string | null], [string, string, string | null]];\n const parent = getLocator(page, parentInfo[0], parentInfo[1], parentInfo[2]);\n // Resolve child relative to parent\n const childType = childInfo[0];\n const childValue = childInfo[1];\n const childOptionsJson = childInfo[2];\n const childOptions = childOptionsJson ? JSON.parse(childOptionsJson) : undefined;\n\n // For chained locators, we need to get a locator within the parent\n switch (childType) {\n case \"css\":\n locator = parent.locator(childValue);\n break;\n case \"role\": {\n const roleOpts = childOptions ? { ...childOptions } : undefined;\n if (roleOpts) {\n delete roleOpts.nth;\n delete roleOpts.filter;\n if (roleOpts.name && typeof roleOpts.name === 'object' && roleOpts.name.$regex) {\n roleOpts.name = new RegExp(roleOpts.name.$regex, roleOpts.name.$flags);\n }\n }\n locator = parent.getByRole(\n childValue as Parameters<PlaywrightLocator[\"getByRole\"]>[0],\n roleOpts && Object.keys(roleOpts).length > 0 ? roleOpts : undefined\n );\n break;\n }\n case \"text\":\n locator = parent.getByText(childValue);\n break;\n case \"label\":\n locator = parent.getByLabel(childValue);\n break;\n case \"placeholder\":\n locator = parent.getByPlaceholder(childValue);\n break;\n case \"testId\":\n locator = parent.getByTestId(childValue);\n break;\n case \"altText\":\n locator = parent.getByAltText(childValue);\n break;\n case \"title\":\n locator = parent.getByTitle(childValue);\n break;\n default:\n locator = parent.locator(childValue);\n }\n\n // Apply nth to the child if specified\n if (childOptions?.nth !== undefined) {\n locator = locator.nth(childOptions.nth);\n }\n // Apply filter to the child if specified\n if (childOptions?.filter) {\n const filterOpts = { ...childOptions.filter };\n if (filterOpts.hasText && typeof filterOpts.hasText === 'object' && filterOpts.hasText.$regex) {\n filterOpts.hasText = new RegExp(filterOpts.hasText.$regex, filterOpts.hasText.$flags);\n }\n if (filterOpts.hasNotText && typeof filterOpts.hasNotText === 'object' && filterOpts.hasNotText.$regex) {\n filterOpts.hasNotText = new RegExp(filterOpts.hasNotText.$regex, filterOpts.hasNotText.$flags);\n }\n locator = locator.filter(filterOpts);\n }\n break;\n }\n case \"altText\":\n locator = page.getByAltText(selectorValue);\n break;\n case \"title\":\n locator = page.getByTitle(selectorValue);\n break;\n case \"frame\": {\n // Frame locator: selectorValue is JSON [frameSelectorInfo, innerLocatorInfo]\n const [frameSelectorInfo, innerLocatorInfo] = JSON.parse(selectorValue) as [[string, string, string | null], [string, string, string | null]];\n const frameSelector = frameSelectorInfo[1]; // CSS selector for the iframe\n const frame = page.frameLocator(frameSelector);\n // Get the inner locator\n const innerType = innerLocatorInfo[0];\n const innerValue = innerLocatorInfo[1];\n const innerOptionsJson = innerLocatorInfo[2];\n const innerOptions = innerOptionsJson ? JSON.parse(innerOptionsJson) : undefined;\n\n switch (innerType) {\n case \"css\":\n locator = frame.locator(innerValue);\n break;\n case \"role\": {\n const roleOpts = innerOptions ? { ...innerOptions } : undefined;\n if (roleOpts) {\n delete roleOpts.nth;\n delete roleOpts.filter;\n if (roleOpts.name && typeof roleOpts.name === 'object' && roleOpts.name.$regex) {\n roleOpts.name = new RegExp(roleOpts.name.$regex, roleOpts.name.$flags);\n }\n }\n locator = frame.getByRole(\n innerValue as Parameters<PlaywrightLocator[\"getByRole\"]>[0],\n roleOpts && Object.keys(roleOpts).length > 0 ? roleOpts : undefined\n );\n break;\n }\n case \"text\":\n locator = frame.getByText(innerValue);\n break;\n case \"label\":\n locator = frame.getByLabel(innerValue);\n break;\n case \"placeholder\":\n locator = frame.getByPlaceholder(innerValue);\n break;\n case \"testId\":\n locator = frame.getByTestId(innerValue);\n break;\n case \"altText\":\n locator = frame.getByAltText(innerValue);\n break;\n case \"title\":\n locator = frame.getByTitle(innerValue);\n break;\n default:\n locator = frame.locator(innerValue);\n }\n\n // Apply nth to the inner locator if specified\n if (innerOptions?.nth !== undefined) {\n locator = locator.nth(innerOptions.nth);\n }\n // Apply filter to the inner locator if specified\n if (innerOptions?.filter) {\n const filterOpts = { ...innerOptions.filter };\n if (filterOpts.hasText && typeof filterOpts.hasText === 'object' && filterOpts.hasText.$regex) {\n filterOpts.hasText = new RegExp(filterOpts.hasText.$regex, filterOpts.hasText.$flags);\n }\n if (filterOpts.hasNotText && typeof filterOpts.hasNotText === 'object' && filterOpts.hasNotText.$regex) {\n filterOpts.hasNotText = new RegExp(filterOpts.hasNotText.$regex, filterOpts.hasNotText.$flags);\n }\n locator = locator.filter(filterOpts);\n }\n break;\n }\n default:\n locator = page.locator(selectorValue);\n }\n\n // Apply nth if specified\n if (nthIndex !== undefined) {\n locator = locator.nth(nthIndex);\n }\n\n // Apply filter if specified\n if (options?.filter) {\n const filterOpts = { ...options.filter };\n if (filterOpts.hasText && typeof filterOpts.hasText === 'object' && filterOpts.hasText.$regex) {\n filterOpts.hasText = new RegExp(filterOpts.hasText.$regex, filterOpts.hasText.$flags);\n }\n if (filterOpts.hasNotText && typeof filterOpts.hasNotText === 'object' && filterOpts.hasNotText.$regex) {\n filterOpts.hasNotText = new RegExp(filterOpts.hasNotText.$regex, filterOpts.hasNotText.$flags);\n }\n locator = locator.filter(filterOpts);\n }\n\n return locator;\n}\n\n// ============================================================================\n// Helper: Execute locator action\n// ============================================================================\n\ninterface FileIOCallbacks {\n readFile?: ReadFileCallback;\n writeFile?: WriteFileCallback;\n}\n\nasync function executeLocatorAction(\n locator: PlaywrightLocator,\n action: string,\n actionArg: unknown,\n timeout: number,\n fileIO?: FileIOCallbacks\n): Promise<unknown> {\n switch (action) {\n case \"click\":\n await locator.click({ timeout });\n return null;\n case \"dblclick\":\n await locator.dblclick({ timeout });\n return null;\n case \"fill\":\n await locator.fill(String(actionArg ?? \"\"), { timeout });\n return null;\n case \"type\":\n await locator.pressSequentially(String(actionArg ?? \"\"), { timeout });\n return null;\n case \"check\":\n await locator.check({ timeout });\n return null;\n case \"uncheck\":\n await locator.uncheck({ timeout });\n return null;\n case \"selectOption\":\n await locator.selectOption(String(actionArg ?? \"\"), { timeout });\n return null;\n case \"clear\":\n await locator.clear({ timeout });\n return null;\n case \"press\":\n await locator.press(String(actionArg ?? \"\"), { timeout });\n return null;\n case \"hover\":\n await locator.hover({ timeout });\n return null;\n case \"focus\":\n await locator.focus({ timeout });\n return null;\n case \"getText\":\n return await locator.textContent({ timeout });\n case \"getValue\":\n return await locator.inputValue({ timeout });\n case \"isVisible\":\n return await locator.isVisible();\n case \"isEnabled\":\n return await locator.isEnabled();\n case \"isChecked\":\n return await locator.isChecked();\n case \"count\":\n return await locator.count();\n case \"getAttribute\":\n return await locator.getAttribute(String(actionArg ?? \"\"), { timeout });\n case \"isDisabled\":\n return await locator.isDisabled();\n case \"isHidden\":\n return await locator.isHidden();\n case \"innerHTML\":\n return await locator.innerHTML({ timeout });\n case \"innerText\":\n return await locator.innerText({ timeout });\n case \"allTextContents\":\n return await locator.allTextContents();\n case \"allInnerTexts\":\n return await locator.allInnerTexts();\n case \"waitFor\": {\n const opts = actionArg && typeof actionArg === 'object' ? actionArg as Record<string, unknown> : {};\n await locator.waitFor({ state: opts.state as any, timeout: (opts.timeout as number) ?? timeout });\n return null;\n }\n case \"boundingBox\":\n return await locator.boundingBox({ timeout });\n case \"setInputFiles\": {\n const files = actionArg as string | string[] | { name: string; mimeType: string; buffer: string }[];\n\n // Case 1: Already have buffer data (base64 encoded from isolate)\n if (Array.isArray(files) && files.length > 0 && typeof files[0] === 'object' && 'buffer' in files[0]) {\n const fileBuffers = (files as { name: string; mimeType: string; buffer: string }[]).map(f => ({\n name: f.name,\n mimeType: f.mimeType,\n buffer: Buffer.from(f.buffer, 'base64'),\n }));\n await locator.setInputFiles(fileBuffers, { timeout });\n return null;\n }\n\n // Case 2: File paths - need to use readFile callback for security\n const filePaths = Array.isArray(files) ? files as string[] : [files as string];\n\n if (!fileIO?.readFile) {\n throw new Error(\n \"setInputFiles() with file paths requires a readFile callback in defaultPlaywrightHandler options. \" +\n 'Either provide file data directly using { name, mimeType, buffer } format, or ' +\n 'configure a readFile callback to control file access from the isolate.'\n );\n }\n\n // Read files through the callback\n const fileBuffers = await Promise.all(\n filePaths.map(async (filePath) => {\n const fileData = await fileIO.readFile!(filePath);\n return {\n name: fileData.name,\n mimeType: fileData.mimeType,\n buffer: fileData.buffer,\n };\n })\n );\n\n await locator.setInputFiles(fileBuffers, { timeout });\n return null;\n }\n case \"screenshot\": {\n const opts = actionArg as { type?: 'png' | 'jpeg'; quality?: number; path?: string } | undefined;\n\n // Take screenshot (without path - we handle file writing separately)\n const buffer = await locator.screenshot({\n timeout,\n type: opts?.type,\n quality: opts?.quality,\n });\n\n // If path is specified, use writeFile callback\n if (opts?.path) {\n if (!fileIO?.writeFile) {\n throw new Error(\n \"screenshot() with path option requires a writeFile callback in defaultPlaywrightHandler options. \" +\n 'Either omit the path option (screenshot returns base64 data), or ' +\n 'configure a writeFile callback to control file writing from the isolate.'\n );\n }\n await fileIO.writeFile(opts.path, buffer);\n }\n\n return buffer.toString('base64');\n }\n case \"dragTo\": {\n const targetInfo = actionArg as [string, string, string | null];\n // We need to resolve the target locator on the page\n // This is a workaround since we can't pass locator objects directly\n // The target info is passed as selector info tuple\n const targetLocator = getLocator(locator.page(), targetInfo[0], targetInfo[1], targetInfo[2]);\n await locator.dragTo(targetLocator, { timeout });\n return null;\n }\n case \"scrollIntoViewIfNeeded\":\n await locator.scrollIntoViewIfNeeded({ timeout });\n return null;\n case \"highlight\":\n await locator.highlight();\n return null;\n case \"evaluate\": {\n const [fnString, arg] = actionArg as [string, unknown];\n const fn = new Function('return (' + fnString + ')')();\n return await locator.evaluate(fn, arg);\n }\n case \"evaluateAll\": {\n const [fnString, arg] = actionArg as [string, unknown];\n const fn = new Function('return (' + fnString + ')')();\n return await locator.evaluateAll(fn, arg);\n }\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n}\n\n// ============================================================================\n// Helper: Execute expect assertion\n// ============================================================================\n\nasync function executeExpectAssertion(\n locator: PlaywrightLocator,\n matcher: string,\n expected: unknown,\n negated: boolean,\n timeout: number\n): Promise<void> {\n switch (matcher) {\n case \"toBeVisible\": {\n const isVisible = await locator.isVisible();\n if (negated) {\n if (isVisible) throw new Error(\"Expected element to not be visible, but it was visible\");\n } else {\n if (!isVisible) throw new Error(\"Expected element to be visible, but it was not\");\n }\n break;\n }\n case \"toContainText\": {\n const text = await locator.textContent({ timeout });\n let matches: boolean;\n let expectedDisplay: string;\n if (expected && typeof expected === 'object' && (expected as any).$regex) {\n const regex = new RegExp((expected as any).$regex, (expected as any).$flags);\n matches = regex.test(text ?? '');\n expectedDisplay = String(regex);\n } else {\n matches = text?.includes(String(expected)) ?? false;\n expectedDisplay = String(expected);\n }\n if (negated) {\n if (matches) throw new Error(`Expected text to not contain ${expectedDisplay}, but got \"${text}\"`);\n } else {\n if (!matches) throw new Error(`Expected text to contain ${expectedDisplay}, but got \"${text}\"`);\n }\n break;\n }\n case \"toHaveValue\": {\n const value = await locator.inputValue({ timeout });\n const matches = value === String(expected);\n if (negated) {\n if (matches) throw new Error(`Expected value to not be \"${expected}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected value to be \"${expected}\", but got \"${value}\"`);\n }\n break;\n }\n case \"toBeEnabled\": {\n const isEnabled = await locator.isEnabled();\n if (negated) {\n if (isEnabled) throw new Error(\"Expected element to be disabled, but it was enabled\");\n } else {\n if (!isEnabled) throw new Error(\"Expected element to be enabled, but it was disabled\");\n }\n break;\n }\n case \"toBeChecked\": {\n const isChecked = await locator.isChecked();\n if (negated) {\n if (isChecked) throw new Error(\"Expected element to not be checked, but it was checked\");\n } else {\n if (!isChecked) throw new Error(\"Expected element to be checked, but it was not\");\n }\n break;\n }\n case \"toHaveAttribute\": {\n const { name, value } = expected as { name: string; value: unknown };\n const actual = await locator.getAttribute(name, { timeout });\n if (value instanceof RegExp || (value && typeof value === 'object' && (value as any).$regex)) {\n const regex = (value as any).$regex ? new RegExp((value as any).$regex, (value as any).$flags) : value as RegExp;\n const matches = regex.test(actual ?? '');\n if (negated) {\n if (matches) throw new Error(`Expected attribute \"${name}\" to not match ${regex}, but got \"${actual}\"`);\n } else {\n if (!matches) throw new Error(`Expected attribute \"${name}\" to match ${regex}, but got \"${actual}\"`);\n }\n } else {\n const matches = actual === String(value);\n if (negated) {\n if (matches) throw new Error(`Expected attribute \"${name}\" to not be \"${value}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected attribute \"${name}\" to be \"${value}\", but got \"${actual}\"`);\n }\n }\n break;\n }\n case \"toHaveText\": {\n const text = (await locator.textContent({ timeout })) ?? '';\n let matches: boolean;\n let expectedDisplay: string;\n if (expected && typeof expected === 'object' && (expected as any).$regex) {\n const regex = new RegExp((expected as any).$regex, (expected as any).$flags);\n matches = regex.test(text);\n expectedDisplay = String(regex);\n } else {\n matches = text === String(expected);\n expectedDisplay = JSON.stringify(expected);\n }\n if (negated) {\n if (matches) throw new Error(`Expected text to not be ${expectedDisplay}, but got \"${text}\"`);\n } else {\n if (!matches) throw new Error(`Expected text to be ${expectedDisplay}, but got \"${text}\"`);\n }\n break;\n }\n case \"toHaveCount\": {\n const count = await locator.count();\n const expectedCount = Number(expected);\n if (negated) {\n if (count === expectedCount) throw new Error(`Expected count to not be ${expectedCount}, but it was`);\n } else {\n if (count !== expectedCount) throw new Error(`Expected count to be ${expectedCount}, but got ${count}`);\n }\n break;\n }\n case \"toBeHidden\": {\n const isHidden = await locator.isHidden();\n if (negated) {\n if (isHidden) throw new Error(\"Expected element to not be hidden, but it was hidden\");\n } else {\n if (!isHidden) throw new Error(\"Expected element to be hidden, but it was not\");\n }\n break;\n }\n case \"toBeDisabled\": {\n const isDisabled = await locator.isDisabled();\n if (negated) {\n if (isDisabled) throw new Error(\"Expected element to not be disabled, but it was disabled\");\n } else {\n if (!isDisabled) throw new Error(\"Expected element to be disabled, but it was not\");\n }\n break;\n }\n case \"toBeFocused\": {\n const isFocused = await locator.evaluate((el) => document.activeElement === el).catch(() => false);\n if (negated) {\n if (isFocused) throw new Error(\"Expected element to not be focused, but it was focused\");\n } else {\n if (!isFocused) throw new Error(\"Expected element to be focused, but it was not\");\n }\n break;\n }\n case \"toBeEmpty\": {\n const text = await locator.textContent({ timeout });\n const value = await locator.inputValue({ timeout }).catch(() => null);\n const isEmpty = (value !== null ? value === '' : (text ?? '') === '');\n if (negated) {\n if (isEmpty) throw new Error(\"Expected element to not be empty, but it was\");\n } else {\n if (!isEmpty) throw new Error(\"Expected element to be empty, but it was not\");\n }\n break;\n }\n case \"toBeAttached\": {\n const count = await locator.count();\n const isAttached = count > 0;\n if (negated) {\n if (isAttached) throw new Error(\"Expected element to not be attached to DOM, but it was\");\n } else {\n if (!isAttached) throw new Error(\"Expected element to be attached to DOM, but it was not\");\n }\n break;\n }\n case \"toBeEditable\": {\n const isEditable = await locator.isEditable({ timeout });\n if (negated) {\n if (isEditable) throw new Error(\"Expected element to not be editable, but it was\");\n } else {\n if (!isEditable) throw new Error(\"Expected element to be editable, but it was not\");\n }\n break;\n }\n case \"toHaveClass\": {\n const classAttr = await locator.getAttribute('class', { timeout }) ?? '';\n const classes = classAttr.split(/\\s+/).filter(Boolean);\n let matches: boolean;\n let expectedDisplay: string;\n if (expected && typeof expected === 'object' && (expected as any).$regex) {\n const regex = new RegExp((expected as any).$regex, (expected as any).$flags);\n matches = regex.test(classAttr);\n expectedDisplay = String(regex);\n } else if (Array.isArray(expected)) {\n matches = expected.every(c => classes.includes(c));\n expectedDisplay = JSON.stringify(expected);\n } else {\n // Exact match for string\n matches = classAttr === String(expected) || classes.includes(String(expected));\n expectedDisplay = String(expected);\n }\n if (negated) {\n if (matches) throw new Error(`Expected class to not match ${expectedDisplay}, but got \"${classAttr}\"`);\n } else {\n if (!matches) throw new Error(`Expected class to match ${expectedDisplay}, but got \"${classAttr}\"`);\n }\n break;\n }\n case \"toContainClass\": {\n const classAttr = await locator.getAttribute('class', { timeout }) ?? '';\n const classes = classAttr.split(/\\s+/).filter(Boolean);\n const expectedClass = String(expected);\n const hasClass = classes.includes(expectedClass);\n if (negated) {\n if (hasClass) throw new Error(`Expected element to not contain class \"${expectedClass}\", but it does`);\n } else {\n if (!hasClass) throw new Error(`Expected element to contain class \"${expectedClass}\", but classes are \"${classAttr}\"`);\n }\n break;\n }\n case \"toHaveId\": {\n const id = await locator.getAttribute('id', { timeout });\n const matches = id === String(expected);\n if (negated) {\n if (matches) throw new Error(`Expected id to not be \"${expected}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected id to be \"${expected}\", but got \"${id}\"`);\n }\n break;\n }\n case \"toBeInViewport\": {\n // Use Intersection Observer API via evaluate to check if element is in viewport\n const isInViewport = await locator.evaluate((el) => {\n const rect = el.getBoundingClientRect();\n return (\n rect.top < window.innerHeight &&\n rect.bottom > 0 &&\n rect.left < window.innerWidth &&\n rect.right > 0\n );\n });\n if (negated) {\n if (isInViewport) throw new Error(\"Expected element to not be in viewport, but it was\");\n } else {\n if (!isInViewport) throw new Error(\"Expected element to be in viewport, but it was not\");\n }\n break;\n }\n case \"toHaveCSS\": {\n const { name, value } = expected as { name: string; value: unknown };\n const actual = await locator.evaluate((el, propName) => {\n return getComputedStyle(el).getPropertyValue(propName);\n }, name);\n let matches: boolean;\n if (value && typeof value === 'object' && (value as any).$regex) {\n const regex = new RegExp((value as any).$regex, (value as any).$flags);\n matches = regex.test(actual);\n } else {\n matches = actual === String(value);\n }\n if (negated) {\n if (matches) throw new Error(`Expected CSS \"${name}\" to not be \"${value}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected CSS \"${name}\" to be \"${value}\", but got \"${actual}\"`);\n }\n break;\n }\n case \"toHaveJSProperty\": {\n const { name, value } = expected as { name: string; value: unknown };\n const actual = await locator.evaluate((el, propName) => {\n return (el as any)[propName];\n }, name);\n const matches = JSON.stringify(actual) === JSON.stringify(value);\n if (negated) {\n if (matches) throw new Error(`Expected JS property \"${name}\" to not be ${JSON.stringify(value)}, but it was`);\n } else {\n if (!matches) throw new Error(`Expected JS property \"${name}\" to be ${JSON.stringify(value)}, but got ${JSON.stringify(actual)}`);\n }\n break;\n }\n case \"toHaveAccessibleName\": {\n const accessibleName = await locator.evaluate((el) => {\n return el.getAttribute('aria-label') || el.getAttribute('aria-labelledby') || (el as HTMLElement).innerText || '';\n });\n let matches: boolean;\n if (expected && typeof expected === 'object' && (expected as any).$regex) {\n const regex = new RegExp((expected as any).$regex, (expected as any).$flags);\n matches = regex.test(accessibleName);\n } else {\n matches = accessibleName === String(expected);\n }\n if (negated) {\n if (matches) throw new Error(`Expected accessible name to not be \"${expected}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected accessible name to be \"${expected}\", but got \"${accessibleName}\"`);\n }\n break;\n }\n case \"toHaveAccessibleDescription\": {\n const accessibleDesc = await locator.evaluate((el) => {\n const describedby = el.getAttribute('aria-describedby');\n if (describedby) {\n const descEl = document.getElementById(describedby);\n return descEl?.textContent || '';\n }\n return el.getAttribute('aria-description') || '';\n });\n let matches: boolean;\n if (expected && typeof expected === 'object' && (expected as any).$regex) {\n const regex = new RegExp((expected as any).$regex, (expected as any).$flags);\n matches = regex.test(accessibleDesc);\n } else {\n matches = accessibleDesc === String(expected);\n }\n if (negated) {\n if (matches) throw new Error(`Expected accessible description to not be \"${expected}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected accessible description to be \"${expected}\", but got \"${accessibleDesc}\"`);\n }\n break;\n }\n case \"toHaveRole\": {\n const role = await locator.evaluate((el) => {\n return el.getAttribute('role') || el.tagName.toLowerCase();\n });\n const matches = role === String(expected);\n if (negated) {\n if (matches) throw new Error(`Expected role to not be \"${expected}\", but it was`);\n } else {\n if (!matches) throw new Error(`Expected role to be \"${expected}\", but got \"${role}\"`);\n }\n break;\n }\n default:\n throw new Error(`Unknown matcher: ${matcher}`);\n }\n}\n\n// ============================================================================\n// Helper: Execute page expect assertion\n// ============================================================================\n\nasync function executePageExpectAssertion(\n page: Page,\n matcher: string,\n expected: unknown,\n negated: boolean,\n timeout: number\n): Promise<void> {\n // Deserialize regex if needed\n let expectedValue = expected;\n if (expected && typeof expected === 'object' && (expected as { $regex?: string }).$regex) {\n expectedValue = new RegExp(\n (expected as { $regex: string }).$regex,\n (expected as { $flags?: string }).$flags\n );\n }\n\n switch (matcher) {\n case \"toHaveURL\": {\n const expectedUrl = expectedValue as string | RegExp;\n const startTime = Date.now();\n let lastUrl = \"\";\n while (Date.now() - startTime < timeout) {\n lastUrl = page.url();\n const matches = expectedUrl instanceof RegExp\n ? expectedUrl.test(lastUrl)\n : lastUrl === expectedUrl;\n if (negated ? !matches : matches) return;\n await new Promise(r => setTimeout(r, 100));\n }\n if (negated) {\n throw new Error(`Expected URL to not match \"${expectedUrl}\", but got \"${lastUrl}\"`);\n } else {\n throw new Error(`Expected URL to be \"${expectedUrl}\", but got \"${lastUrl}\"`);\n }\n }\n case \"toHaveTitle\": {\n const expectedTitle = expectedValue as string | RegExp;\n const startTime = Date.now();\n let lastTitle = \"\";\n while (Date.now() - startTime < timeout) {\n lastTitle = await page.title();\n const matches = expectedTitle instanceof RegExp\n ? expectedTitle.test(lastTitle)\n : lastTitle === expectedTitle;\n if (negated ? !matches : matches) return;\n await new Promise(r => setTimeout(r, 100));\n }\n if (negated) {\n throw new Error(`Expected title to not match \"${expectedTitle}\", but got \"${lastTitle}\"`);\n } else {\n throw new Error(`Expected title to be \"${expectedTitle}\", but got \"${lastTitle}\"`);\n }\n }\n default:\n throw new Error(`Unknown page matcher: ${matcher}`);\n }\n}\n\n// ============================================================================\n// Create Playwright Handler (for remote use)\n// ============================================================================\n\n/**\n * Registry for tracking multiple pages and contexts.\n */\ninterface PlaywrightRegistry {\n pages: Map<string, Page>;\n contexts: Map<string, BrowserContext>;\n nextPageId: number;\n nextContextId: number;\n}\n\n/**\n * Create a playwright handler from a Page object.\n * This handler is called by the daemon (via callback) when sandbox needs page operations.\n * Used for remote runtime where the browser runs on the client.\n */\nexport function createPlaywrightHandler(\n page: Page,\n options?: DefaultPlaywrightHandlerOptions\n): PlaywrightCallback {\n const timeout = options?.timeout ?? 30000;\n const fileIO: FileIOCallbacks = {\n readFile: options?.readFile,\n writeFile: options?.writeFile,\n };\n\n // Registry for tracking multiple pages and contexts\n const registry: PlaywrightRegistry = {\n pages: new Map<string, Page>([[\"page_0\", page]]),\n contexts: new Map<string, BrowserContext>([[\"ctx_0\", page.context()]]),\n nextPageId: 1,\n nextContextId: 1,\n };\n\n return async (op: PlaywrightOperation): Promise<PlaywrightResult> => {\n try {\n // Handle lifecycle operations first (they don't require existing page)\n switch (op.type) {\n case \"newContext\": {\n if (!options?.createContext) {\n return { ok: false, error: { name: \"Error\", message: \"createContext callback not provided. Configure createContext in playwright options to enable browser.newContext().\" } };\n }\n const [contextOptions] = op.args as [BrowserContextOptions?];\n const newContext = await options.createContext(contextOptions);\n const contextId = `ctx_${registry.nextContextId++}`;\n registry.contexts.set(contextId, newContext);\n return { ok: true, value: { contextId } };\n }\n\n case \"newPage\": {\n if (!options?.createPage) {\n return { ok: false, error: { name: \"Error\", message: \"createPage callback not provided. Configure createPage in playwright options to enable context.newPage().\" } };\n }\n const contextId = op.contextId ?? \"ctx_0\";\n const targetContext = registry.contexts.get(contextId);\n if (!targetContext) {\n return { ok: false, error: { name: \"Error\", message: `Context ${contextId} not found` } };\n }\n const newPage = await options.createPage(targetContext);\n const pageId = `page_${registry.nextPageId++}`;\n registry.pages.set(pageId, newPage);\n return { ok: true, value: { pageId } };\n }\n\n case \"closeContext\": {\n const contextId = op.contextId ?? \"ctx_0\";\n const context = registry.contexts.get(contextId);\n if (!context) {\n return { ok: false, error: { name: \"Error\", message: `Context ${contextId} not found` } };\n }\n await context.close();\n registry.contexts.delete(contextId);\n // Remove pages belonging to this context\n for (const [pid, p] of registry.pages) {\n if (p.context() === context) {\n registry.pages.delete(pid);\n }\n }\n return { ok: true };\n }\n }\n\n // Resolve page from pageId for page-specific operations\n const pageId = op.pageId ?? \"page_0\";\n const targetPage = registry.pages.get(pageId);\n if (!targetPage) {\n return { ok: false, error: { name: \"Error\", message: `Page ${pageId} not found` } };\n }\n\n // Resolve context from contextId for context-specific operations\n const contextId = op.contextId ?? \"ctx_0\";\n const targetContext = registry.contexts.get(contextId);\n\n switch (op.type) {\n case \"goto\": {\n const [url, waitUntil] = op.args as [string, string?];\n await targetPage.goto(url, {\n timeout,\n waitUntil: (waitUntil as \"load\" | \"domcontentloaded\" | \"networkidle\") ?? \"load\",\n });\n return { ok: true };\n }\n case \"reload\":\n await targetPage.reload({ timeout });\n return { ok: true };\n case \"url\":\n return { ok: true, value: targetPage.url() };\n case \"title\":\n return { ok: true, value: await targetPage.title() };\n case \"content\":\n return { ok: true, value: await targetPage.content() };\n case \"waitForSelector\": {\n const [selector, optionsJson] = op.args as [string, string?];\n const opts = optionsJson ? JSON.parse(optionsJson) : {};\n await targetPage.waitForSelector(selector, { timeout, ...opts });\n return { ok: true };\n }\n case \"waitForTimeout\": {\n const [ms] = op.args as [number];\n await targetPage.waitForTimeout(ms);\n return { ok: true };\n }\n case \"waitForLoadState\": {\n const [state] = op.args as [string?];\n await targetPage.waitForLoadState(\n (state as \"load\" | \"domcontentloaded\" | \"networkidle\") ?? \"load\",\n { timeout }\n );\n return { ok: true };\n }\n case \"evaluate\": {\n const [script, arg] = op.args as [string, unknown];\n if (op.args.length > 1) {\n const fn = new Function('return (' + script + ')')();\n const result = await targetPage.evaluate(fn, arg);\n return { ok: true, value: result };\n }\n const result = await targetPage.evaluate(script);\n return { ok: true, value: result };\n }\n case \"locatorAction\": {\n const [selectorType, selectorValue, roleOptions, action, actionArg] = op.args as [\n string,\n string,\n string | null,\n string,\n unknown\n ];\n const locator = getLocator(targetPage, selectorType, selectorValue, roleOptions);\n const result = await executeLocatorAction(locator, action, actionArg, timeout, fileIO);\n return { ok: true, value: result };\n }\n case \"expectLocator\": {\n const [selectorType, selectorValue, roleOptions, matcher, expected, negated, customTimeout] = op.args as [\n string,\n string,\n string | null,\n string,\n unknown,\n boolean,\n number?\n ];\n const locator = getLocator(targetPage, selectorType, selectorValue, roleOptions);\n const effectiveTimeout = customTimeout ?? timeout;\n await executeExpectAssertion(locator, matcher, expected, negated ?? false, effectiveTimeout);\n return { ok: true };\n }\n case \"expectPage\": {\n const [matcher, expected, negated, customTimeout] = op.args as [\n string,\n unknown,\n boolean,\n number?\n ];\n const effectiveTimeout = customTimeout ?? timeout;\n await executePageExpectAssertion(targetPage, matcher, expected, negated ?? false, effectiveTimeout);\n return { ok: true };\n }\n case \"request\": {\n const [url, method, data, headers] = op.args as [\n string,\n string,\n unknown,\n Record<string, string>?\n ];\n const requestOptions: {\n method?: string;\n data?: unknown;\n headers?: Record<string, string>;\n timeout?: number;\n } = {\n timeout,\n };\n if (headers) {\n requestOptions.headers = headers;\n }\n if (data !== undefined && data !== null) {\n requestOptions.data = data;\n }\n\n const response = await targetPage.request.fetch(url, {\n method: method as \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\" | \"HEAD\" | \"OPTIONS\",\n ...requestOptions,\n });\n\n // Get response data - try to parse as JSON, fall back to text\n const text = await response.text();\n let json: unknown = null;\n try {\n json = JSON.parse(text);\n } catch {\n // Not valid JSON, that's ok\n }\n\n return {\n ok: true,\n value: {\n status: response.status(),\n ok: response.ok(),\n headers: response.headers(),\n text,\n json,\n body: null, // ArrayBuffer not easily serializable, use text/json instead\n },\n };\n }\n case \"goBack\": {\n const [waitUntil] = op.args as [string?];\n await targetPage.goBack({\n timeout,\n waitUntil: (waitUntil as \"load\" | \"domcontentloaded\" | \"networkidle\") ?? \"load\",\n });\n return { ok: true };\n }\n case \"goForward\": {\n const [waitUntil] = op.args as [string?];\n await targetPage.goForward({\n timeout,\n waitUntil: (waitUntil as \"load\" | \"domcontentloaded\" | \"networkidle\") ?? \"load\",\n });\n return { ok: true };\n }\n case \"waitForURL\": {\n const [urlArg, customTimeout, waitUntil] = op.args as [\n string | { $regex: string; $flags: string },\n number?,\n string?\n ];\n // Deserialize regex URL pattern\n const url = urlArg && typeof urlArg === 'object' && '$regex' in urlArg\n ? new RegExp(urlArg.$regex, urlArg.$flags)\n : urlArg;\n await targetPage.waitForURL(url, {\n timeout: customTimeout ?? timeout,\n waitUntil: (waitUntil as \"load\" | \"domcontentloaded\" | \"networkidle\") ?? undefined,\n });\n return { ok: true };\n }\n case \"clearCookies\": {\n // Use contextId for cookie operations\n const ctx = targetContext ?? targetPage.context();\n await ctx.clearCookies();\n return { ok: true };\n }\n case \"screenshot\": {\n const [screenshotOptions] = op.args as [{\n path?: string;\n type?: 'png' | 'jpeg';\n quality?: number;\n fullPage?: boolean;\n clip?: { x: number; y: number; width: number; height: number };\n }?];\n // Don't pass path to Playwright - we handle file writing through callback\n const buffer = await targetPage.screenshot({\n type: screenshotOptions?.type,\n quality: screenshotOptions?.quality,\n fullPage: screenshotOptions?.fullPage,\n clip: screenshotOptions?.clip,\n });\n // If path is specified, use writeFile callback\n if (screenshotOptions?.path) {\n if (!fileIO.writeFile) {\n throw new Error(\n \"screenshot() with path option requires a writeFile callback to be provided. \" +\n \"Either provide a writeFile callback in defaultPlaywrightHandler options, or omit the path option \" +\n \"and handle the returned base64 data yourself.\"\n );\n }\n await fileIO.writeFile(screenshotOptions.path, buffer);\n }\n return { ok: true, value: buffer.toString('base64') };\n }\n case \"setViewportSize\": {\n const [size] = op.args as [{ width: number; height: number }];\n await targetPage.setViewportSize(size);\n return { ok: true };\n }\n case \"viewportSize\": {\n return { ok: true, value: targetPage.viewportSize() };\n }\n case \"keyboardType\": {\n const [text, typeOptions] = op.args as [string, { delay?: number }?];\n await targetPage.keyboard.type(text, typeOptions);\n return { ok: true };\n }\n case \"keyboardPress\": {\n const [key, pressOptions] = op.args as [string, { delay?: number }?];\n await targetPage.keyboard.press(key, pressOptions);\n return { ok: true };\n }\n case \"keyboardDown\": {\n const [key] = op.args as [string];\n await targetPage.keyboard.down(key);\n return { ok: true };\n }\n case \"keyboardUp\": {\n const [key] = op.args as [string];\n await targetPage.keyboard.up(key);\n return { ok: true };\n }\n case \"keyboardInsertText\": {\n const [text] = op.args as [string];\n await targetPage.keyboard.insertText(text);\n return { ok: true };\n }\n case \"mouseMove\": {\n const [x, y, moveOptions] = op.args as [number, number, { steps?: number }?];\n await targetPage.mouse.move(x, y, moveOptions);\n return { ok: true };\n }\n case \"mouseClick\": {\n const [x, y, clickOptions] = op.args as [number, number, { button?: 'left' | 'right' | 'middle'; clickCount?: number; delay?: number }?];\n await targetPage.mouse.click(x, y, clickOptions);\n return { ok: true };\n }\n case \"mouseDown\": {\n const [downOptions] = op.args as [{ button?: 'left' | 'right' | 'middle'; clickCount?: number }?];\n await targetPage.mouse.down(downOptions);\n return { ok: true };\n }\n case \"mouseUp\": {\n const [upOptions] = op.args as [{ button?: 'left' | 'right' | 'middle'; clickCount?: number }?];\n await targetPage.mouse.up(upOptions);\n return { ok: true };\n }\n case \"mouseWheel\": {\n const [deltaX, deltaY] = op.args as [number, number];\n await targetPage.mouse.wheel(deltaX, deltaY);\n return { ok: true };\n }\n case \"frames\": {\n const frames = targetPage.frames();\n return { ok: true, value: frames.map(f => ({ name: f.name(), url: f.url() })) };\n }\n case \"mainFrame\": {\n const mainFrame = targetPage.mainFrame();\n return { ok: true, value: { name: mainFrame.name(), url: mainFrame.url() } };\n }\n case \"bringToFront\": {\n await targetPage.bringToFront();\n return { ok: true };\n }\n case \"close\": {\n await targetPage.close();\n // Remove from registry\n registry.pages.delete(pageId);\n return { ok: true };\n }\n case \"isClosed\": {\n return { ok: true, value: targetPage.isClosed() };\n }\n case \"pdf\": {\n const [pdfOptions] = op.args as [{\n path?: string;\n scale?: number;\n displayHeaderFooter?: boolean;\n headerTemplate?: string;\n footerTemplate?: string;\n printBackground?: boolean;\n landscape?: boolean;\n pageRanges?: string;\n format?: string;\n width?: string | number;\n height?: string | number;\n margin?: { top?: string | number; right?: string | number; bottom?: string | number; left?: string | number };\n }?];\n // Don't pass path to Playwright - we handle file writing through callback\n const { path: pdfPath, ...restPdfOptions } = pdfOptions ?? {};\n const buffer = await targetPage.pdf(restPdfOptions);\n // If path is specified, use writeFile callback\n if (pdfPath) {\n if (!fileIO.writeFile) {\n throw new Error(\n \"pdf() with path option requires a writeFile callback to be provided. \" +\n \"Either provide a writeFile callback in defaultPlaywrightHandler options, or omit the path option \" +\n \"and handle the returned base64 data yourself.\"\n );\n }\n await fileIO.writeFile(pdfPath, buffer);\n }\n return { ok: true, value: buffer.toString('base64') };\n }\n case \"emulateMedia\": {\n const [mediaOptions] = op.args as [{ media?: 'screen' | 'print' | null; colorScheme?: 'light' | 'dark' | 'no-preference' | null; reducedMotion?: 'reduce' | 'no-preference' | null; forcedColors?: 'active' | 'none' | null }?];\n await targetPage.emulateMedia(mediaOptions);\n return { ok: true };\n }\n case \"addCookies\": {\n const [cookies] = op.args as [Array<{\n name: string;\n value: string;\n domain?: string;\n path?: string;\n expires?: number;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: 'Strict' | 'Lax' | 'None';\n }>];\n // Use contextId for cookie operations\n const ctx = targetContext ?? targetPage.context();\n await ctx.addCookies(cookies);\n return { ok: true };\n }\n case \"cookies\": {\n const [urls] = op.args as [string[]?];\n // Use contextId for cookie operations\n const ctx = targetContext ?? targetPage.context();\n const cookies = await ctx.cookies(urls);\n return { ok: true, value: cookies };\n }\n case \"setExtraHTTPHeaders\": {\n const [headers] = op.args as [Record<string, string>];\n await targetPage.setExtraHTTPHeaders(headers);\n return { ok: true };\n }\n case \"pause\": {\n await targetPage.pause();\n return { ok: true };\n }\n default:\n return { ok: false, error: { name: \"Error\", message: `Unknown operation: ${(op as PlaywrightOperation).type}` } };\n }\n } catch (err) {\n const error = err as Error;\n return { ok: false, error: { name: error.name, message: error.message } };\n }\n };\n}\n\n/**\n * Public helper for handler-first runtime options.\n * Adds metadata used by adapter layers for local event capture.\n */\nexport function defaultPlaywrightHandler(\n page: Page,\n options?: DefaultPlaywrightHandlerOptions\n): PlaywrightCallback {\n const handler = createPlaywrightHandler(page, options) as DefaultPlaywrightHandler;\n handler[DEFAULT_PLAYWRIGHT_HANDLER_META] = { page, options };\n return handler;\n}\n\n/**\n * Extract metadata from handlers created by defaultPlaywrightHandler().\n */\nexport function getDefaultPlaywrightHandlerMetadata(\n handler: PlaywrightCallback\n): DefaultPlaywrightHandlerMetadata | undefined {\n return (handler as DefaultPlaywrightHandler)[DEFAULT_PLAYWRIGHT_HANDLER_META];\n}\n\n// ============================================================================\n// Setup Playwright\n// ============================================================================\n\n/**\n * Set up playwright in an isolate context.\n *\n * For local use: provide `page` option (direct page access)\n * For remote use: provide `handler` option (callback pattern)\n */\nexport async function setupPlaywright(\n context: ivm.Context,\n options: PlaywrightSetupOptions\n): Promise<PlaywrightHandle> {\n const timeout = options.timeout ?? 30000;\n\n // Determine if we have a page or handler.\n // Handlers created via defaultPlaywrightHandler() carry page metadata so\n // event capture/collected data keeps working in handler-first mode.\n const explicitPage = \"page\" in options ? options.page : undefined;\n const handler = \"handler\" in options ? options.handler : undefined;\n const handlerMetadata = handler\n ? getDefaultPlaywrightHandlerMetadata(handler)\n : undefined;\n const page = explicitPage ?? handlerMetadata?.page;\n\n // Get lifecycle callbacks\n const createPage = \"createPage\" in options ? options.createPage : undefined;\n const createContext = \"createContext\" in options ? options.createContext : undefined;\n\n // Create handler from page if needed\n const effectiveHandler = handler ?? (page ? createPlaywrightHandler(page, {\n timeout,\n createPage,\n createContext,\n }) : undefined);\n\n if (!effectiveHandler) {\n throw new Error(\"Either page or handler must be provided to setupPlaywright\");\n }\n\n // State for collected data (only used when page is provided directly)\n const browserConsoleLogs: BrowserConsoleLogEntry[] = [];\n const networkRequests: NetworkRequestInfo[] = [];\n const networkResponses: NetworkResponseInfo[] = [];\n\n const global = context.global;\n\n // ========================================================================\n // Event Capture (only when page is provided directly)\n // ========================================================================\n\n let requestHandler: ((request: import(\"playwright\").Request) => void) | undefined;\n let responseHandler: ((response: import(\"playwright\").Response) => void) | undefined;\n let consoleHandler: ((msg: import(\"playwright\").ConsoleMessage) => void) | undefined;\n\n if (page) {\n // Get onEvent callback if provided\n const onEvent = \"onEvent\" in options ? options.onEvent : undefined;\n\n requestHandler = (request: import(\"playwright\").Request) => {\n const info: NetworkRequestInfo = {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n postData: request.postData() ?? undefined,\n resourceType: request.resourceType(),\n timestamp: Date.now(),\n };\n networkRequests.push(info);\n\n if (onEvent) {\n onEvent({\n type: \"networkRequest\",\n url: info.url,\n method: info.method,\n headers: info.headers,\n postData: info.postData,\n resourceType: info.resourceType,\n timestamp: info.timestamp,\n });\n }\n };\n\n responseHandler = (response: import(\"playwright\").Response) => {\n const info: NetworkResponseInfo = {\n url: response.url(),\n status: response.status(),\n statusText: response.statusText(),\n headers: response.headers(),\n timestamp: Date.now(),\n };\n networkResponses.push(info);\n\n if (onEvent) {\n onEvent({\n type: \"networkResponse\",\n url: info.url,\n status: info.status,\n statusText: info.statusText,\n headers: info.headers,\n timestamp: info.timestamp,\n });\n }\n };\n\n consoleHandler = (msg: import(\"playwright\").ConsoleMessage) => {\n const args = msg.args().map((arg) => String(arg));\n const entry: BrowserConsoleLogEntry = {\n level: msg.type(),\n stdout: args.join(\" \"),\n timestamp: Date.now(),\n };\n browserConsoleLogs.push(entry);\n\n if (onEvent) {\n onEvent({\n type: \"browserConsoleLog\",\n level: entry.level,\n stdout: entry.stdout,\n timestamp: entry.timestamp,\n });\n }\n\n // Print to stdout if console option is true\n if (\"console\" in options && options.console) {\n const prefix = `[browser:${entry.level}]`;\n console.log(prefix, entry.stdout);\n }\n };\n\n page.on(\"request\", requestHandler);\n page.on(\"response\", responseHandler);\n page.on(\"console\", consoleHandler);\n }\n\n // ========================================================================\n // Unified Handler Reference\n // ========================================================================\n\n // Single handler reference that receives operation objects\n global.setSync(\n \"__Playwright_handler_ref\",\n new ivm.Reference(async (opJson: string): Promise<string> => {\n const op = JSON.parse(opJson) as PlaywrightOperation;\n const result = await effectiveHandler(op);\n return JSON.stringify(result);\n })\n );\n\n // ========================================================================\n // Injected JavaScript\n // ========================================================================\n\n // Helper function to invoke handler and handle errors\n context.evalSync(`\n(function() {\n globalThis.__pw_invoke = async function(type, args, options) {\n const op = JSON.stringify({ type, args, pageId: options?.pageId, contextId: options?.contextId });\n const resultJson = __Playwright_handler_ref.applySyncPromise(undefined, [op]);\n const result = JSON.parse(resultJson);\n if (result.ok) {\n return result.value;\n } else {\n const error = new Error(result.error.message);\n error.name = result.error.name;\n throw error;\n }\n };\n})();\n`);\n\n // IsolatePage class and page/context/browser globals\n context.evalSync(`\n(function() {\n // IsolatePage class - represents a page with a specific pageId\n class IsolatePage {\n #pageId; #contextId; #currentUrl = '';\n constructor(pageId, contextId) {\n this.#pageId = pageId;\n this.#contextId = contextId;\n }\n get __isPage() { return true; }\n get __pageId() { return this.#pageId; }\n get __contextId() { return this.#contextId; }\n\n async goto(url, options) {\n await __pw_invoke(\"goto\", [url, options?.waitUntil || null], { pageId: this.#pageId });\n const resolvedUrl = await __pw_invoke(\"url\", [], { pageId: this.#pageId });\n this.#currentUrl = resolvedUrl || url;\n }\n async reload() {\n await __pw_invoke(\"reload\", [], { pageId: this.#pageId });\n const resolvedUrl = await __pw_invoke(\"url\", [], { pageId: this.#pageId });\n if (resolvedUrl) this.#currentUrl = resolvedUrl;\n }\n url() { return this.#currentUrl; }\n async title() { return __pw_invoke(\"title\", [], { pageId: this.#pageId }); }\n async content() { return __pw_invoke(\"content\", [], { pageId: this.#pageId }); }\n async waitForSelector(selector, options) {\n return __pw_invoke(\"waitForSelector\", [selector, options ? JSON.stringify(options) : null], { pageId: this.#pageId });\n }\n async waitForTimeout(ms) { return __pw_invoke(\"waitForTimeout\", [ms], { pageId: this.#pageId }); }\n async waitForLoadState(state) { return __pw_invoke(\"waitForLoadState\", [state || null], { pageId: this.#pageId }); }\n async evaluate(script, arg) {\n const hasArg = arguments.length > 1;\n if (hasArg) {\n const serialized = typeof script === \"function\" ? script.toString() : script;\n return __pw_invoke(\"evaluate\", [serialized, arg], { pageId: this.#pageId });\n }\n const serialized = typeof script === \"function\" ? \"(\" + script.toString() + \")()\" : script;\n return __pw_invoke(\"evaluate\", [serialized], { pageId: this.#pageId });\n }\n locator(selector) { return new Locator(\"css\", selector, null, this.#pageId); }\n getByRole(role, options) {\n if (options) {\n const serialized = { ...options };\n const name = options.name;\n if (name && typeof name === 'object' && typeof name.source === 'string' && typeof name.flags === 'string') {\n serialized.name = { $regex: name.source, $flags: name.flags };\n }\n return new Locator(\"role\", role, JSON.stringify(serialized), this.#pageId);\n }\n return new Locator(\"role\", role, null, this.#pageId);\n }\n getByText(text) { return new Locator(\"text\", text, null, this.#pageId); }\n getByLabel(label) { return new Locator(\"label\", label, null, this.#pageId); }\n getByPlaceholder(p) { return new Locator(\"placeholder\", p, null, this.#pageId); }\n getByTestId(id) { return new Locator(\"testId\", id, null, this.#pageId); }\n getByAltText(alt) { return new Locator(\"altText\", alt, null, this.#pageId); }\n getByTitle(title) { return new Locator(\"title\", title, null, this.#pageId); }\n frameLocator(selector) {\n const pageId = this.#pageId;\n return {\n locator(innerSelector) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"css\", innerSelector, null]]), null, pageId); },\n getByRole(role, options) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"role\", role, options ? JSON.stringify(options) : null]]), null, pageId); },\n getByText(text) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"text\", text, null]]), null, pageId); },\n getByLabel(label) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"label\", label, null]]), null, pageId); },\n getByPlaceholder(placeholder) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"placeholder\", placeholder, null]]), null, pageId); },\n getByTestId(testId) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"testId\", testId, null]]), null, pageId); },\n getByAltText(alt) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"altText\", alt, null]]), null, pageId); },\n getByTitle(title) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"title\", title, null]]), null, pageId); },\n };\n }\n async goBack(options) {\n await __pw_invoke(\"goBack\", [options?.waitUntil || null], { pageId: this.#pageId });\n const resolvedUrl = await __pw_invoke(\"url\", [], { pageId: this.#pageId });\n if (resolvedUrl) this.#currentUrl = resolvedUrl;\n }\n async goForward(options) {\n await __pw_invoke(\"goForward\", [options?.waitUntil || null], { pageId: this.#pageId });\n const resolvedUrl = await __pw_invoke(\"url\", [], { pageId: this.#pageId });\n if (resolvedUrl) this.#currentUrl = resolvedUrl;\n }\n async waitForURL(url, options) {\n let serializedUrl = url;\n if (url && typeof url === 'object' && typeof url.source === 'string' && typeof url.flags === 'string') {\n serializedUrl = { $regex: url.source, $flags: url.flags };\n }\n return __pw_invoke(\"waitForURL\", [serializedUrl, options?.timeout || null, options?.waitUntil || null], { pageId: this.#pageId });\n }\n context() {\n const contextId = this.#contextId;\n return new IsolateContext(contextId);\n }\n async click(selector) { return this.locator(selector).click(); }\n async fill(selector, value) { return this.locator(selector).fill(value); }\n async textContent(selector) { return this.locator(selector).textContent(); }\n async innerText(selector) { return this.locator(selector).innerText(); }\n async innerHTML(selector) { return this.locator(selector).innerHTML(); }\n async getAttribute(selector, name) { return this.locator(selector).getAttribute(name); }\n async inputValue(selector) { return this.locator(selector).inputValue(); }\n async isVisible(selector) { return this.locator(selector).isVisible(); }\n async isEnabled(selector) { return this.locator(selector).isEnabled(); }\n async isChecked(selector) { return this.locator(selector).isChecked(); }\n async isHidden(selector) { return this.locator(selector).isHidden(); }\n async isDisabled(selector) { return this.locator(selector).isDisabled(); }\n async screenshot(options) { return __pw_invoke(\"screenshot\", [options || {}], { pageId: this.#pageId }); }\n async setViewportSize(size) { return __pw_invoke(\"setViewportSize\", [size], { pageId: this.#pageId }); }\n async viewportSize() { return __pw_invoke(\"viewportSize\", [], { pageId: this.#pageId }); }\n async emulateMedia(options) { return __pw_invoke(\"emulateMedia\", [options], { pageId: this.#pageId }); }\n async setExtraHTTPHeaders(headers) { return __pw_invoke(\"setExtraHTTPHeaders\", [headers], { pageId: this.#pageId }); }\n async bringToFront() { return __pw_invoke(\"bringToFront\", [], { pageId: this.#pageId }); }\n async close() { return __pw_invoke(\"close\", [], { pageId: this.#pageId }); }\n async isClosed() { return __pw_invoke(\"isClosed\", [], { pageId: this.#pageId }); }\n async pdf(options) { return __pw_invoke(\"pdf\", [options || {}], { pageId: this.#pageId }); }\n async pause() { return __pw_invoke(\"pause\", [], { pageId: this.#pageId }); }\n async frames() { return __pw_invoke(\"frames\", [], { pageId: this.#pageId }); }\n async mainFrame() { return __pw_invoke(\"mainFrame\", [], { pageId: this.#pageId }); }\n get keyboard() {\n const pageId = this.#pageId;\n return {\n async type(text, options) { return __pw_invoke(\"keyboardType\", [text, options], { pageId }); },\n async press(key, options) { return __pw_invoke(\"keyboardPress\", [key, options], { pageId }); },\n async down(key) { return __pw_invoke(\"keyboardDown\", [key], { pageId }); },\n async up(key) { return __pw_invoke(\"keyboardUp\", [key], { pageId }); },\n async insertText(text) { return __pw_invoke(\"keyboardInsertText\", [text], { pageId }); }\n };\n }\n get mouse() {\n const pageId = this.#pageId;\n return {\n async move(x, y, options) { return __pw_invoke(\"mouseMove\", [x, y, options], { pageId }); },\n async click(x, y, options) { return __pw_invoke(\"mouseClick\", [x, y, options], { pageId }); },\n async down(options) { return __pw_invoke(\"mouseDown\", [options], { pageId }); },\n async up(options) { return __pw_invoke(\"mouseUp\", [options], { pageId }); },\n async wheel(deltaX, deltaY) { return __pw_invoke(\"mouseWheel\", [deltaX, deltaY], { pageId }); }\n };\n }\n get request() {\n const pageId = this.#pageId;\n return {\n async fetch(url, options) {\n const result = await __pw_invoke(\"request\", [url, options?.method || \"GET\", options?.data, options?.headers], { pageId });\n return {\n status: () => result.status,\n ok: () => result.ok,\n headers: () => result.headers,\n json: async () => result.json,\n text: async () => result.text,\n body: async () => result.body,\n };\n },\n async get(url, options) { return this.fetch(url, { ...options, method: \"GET\" }); },\n async post(url, options) { return this.fetch(url, { ...options, method: \"POST\" }); },\n async put(url, options) { return this.fetch(url, { ...options, method: \"PUT\" }); },\n async delete(url, options) { return this.fetch(url, { ...options, method: \"DELETE\" }); },\n };\n }\n }\n globalThis.IsolatePage = IsolatePage;\n\n // IsolateContext class - represents a browser context with a specific contextId\n class IsolateContext {\n #contextId;\n constructor(contextId) { this.#contextId = contextId; }\n get __contextId() { return this.#contextId; }\n\n async newPage() {\n const result = await __pw_invoke(\"newPage\", [], { contextId: this.#contextId });\n return new IsolatePage(result.pageId, this.#contextId);\n }\n async close() { return __pw_invoke(\"closeContext\", [], { contextId: this.#contextId }); }\n async clearCookies() { return __pw_invoke(\"clearCookies\", [], { contextId: this.#contextId }); }\n async addCookies(cookies) { return __pw_invoke(\"addCookies\", [cookies], { contextId: this.#contextId }); }\n async cookies(urls) { return __pw_invoke(\"cookies\", [urls], { contextId: this.#contextId }); }\n }\n globalThis.IsolateContext = IsolateContext;\n\n // browser global - for creating new contexts\n globalThis.browser = {\n async newContext(options) {\n const result = await __pw_invoke(\"newContext\", [options || null]);\n return new IsolateContext(result.contextId);\n }\n };\n\n // context global - represents the default context\n globalThis.context = new IsolateContext(\"ctx_0\");\n\n // page global - represents the default page\n globalThis.page = new IsolatePage(\"page_0\", \"ctx_0\");\n})();\n`);\n\n // Locator class with pageId support\n context.evalSync(`\n(function() {\n // Helper to serialize options including RegExp\n function serializeOptions(options) {\n if (!options) return null;\n const serialized = { ...options };\n if (options.name && typeof options.name === 'object' && typeof options.name.source === 'string' && typeof options.name.flags === 'string') {\n serialized.name = { $regex: options.name.source, $flags: options.name.flags };\n }\n return JSON.stringify(serialized);\n }\n\n class Locator {\n #type; #value; #options; #pageId;\n constructor(type, value, options, pageId) {\n this.#type = type;\n this.#value = value;\n this.#options = options;\n this.#pageId = pageId || \"page_0\";\n }\n\n _getInfo() { return [this.#type, this.#value, this.#options]; }\n _getPageId() { return this.#pageId; }\n\n // Helper to create a chained locator\n _chain(childType, childValue, childOptions) {\n const parentInfo = this._getInfo();\n const childInfo = [childType, childValue, childOptions];\n return new Locator(\"chained\", JSON.stringify([parentInfo, childInfo]), null, this.#pageId);\n }\n\n async click() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"click\", null], { pageId: this.#pageId });\n }\n async dblclick() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"dblclick\", null], { pageId: this.#pageId });\n }\n async fill(text) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"fill\", text], { pageId: this.#pageId });\n }\n async type(text) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"type\", text], { pageId: this.#pageId });\n }\n async check() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"check\", null], { pageId: this.#pageId });\n }\n async uncheck() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"uncheck\", null], { pageId: this.#pageId });\n }\n async selectOption(value) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"selectOption\", value], { pageId: this.#pageId });\n }\n async clear() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"clear\", null], { pageId: this.#pageId });\n }\n async press(key) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"press\", key], { pageId: this.#pageId });\n }\n async hover() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"hover\", null], { pageId: this.#pageId });\n }\n async focus() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"focus\", null], { pageId: this.#pageId });\n }\n async textContent() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getText\", null], { pageId: this.#pageId });\n }\n async inputValue() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getValue\", null], { pageId: this.#pageId });\n }\n async isVisible() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isVisible\", null], { pageId: this.#pageId });\n }\n async isEnabled() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isEnabled\", null], { pageId: this.#pageId });\n }\n async isChecked() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isChecked\", null], { pageId: this.#pageId });\n }\n async count() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"count\", null], { pageId: this.#pageId });\n }\n async getAttribute(name) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getAttribute\", name], { pageId: this.#pageId });\n }\n async isDisabled() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isDisabled\", null], { pageId: this.#pageId });\n }\n async isHidden() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isHidden\", null], { pageId: this.#pageId });\n }\n async innerHTML() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"innerHTML\", null], { pageId: this.#pageId });\n }\n async innerText() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"innerText\", null], { pageId: this.#pageId });\n }\n async allTextContents() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"allTextContents\", null], { pageId: this.#pageId });\n }\n async allInnerTexts() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"allInnerTexts\", null], { pageId: this.#pageId });\n }\n async waitFor(options) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"waitFor\", options || {}], { pageId: this.#pageId });\n }\n async boundingBox() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"boundingBox\", null], { pageId: this.#pageId });\n }\n async setInputFiles(files) {\n // Serialize files - if they have buffers, convert to base64\n let serializedFiles = files;\n if (Array.isArray(files) && files.length > 0 && typeof files[0] === 'object' && files[0].buffer) {\n serializedFiles = files.map(f => ({\n name: f.name,\n mimeType: f.mimeType,\n buffer: typeof f.buffer === 'string' ? f.buffer : btoa(String.fromCharCode(...new Uint8Array(f.buffer)))\n }));\n }\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"setInputFiles\", serializedFiles], { pageId: this.#pageId });\n }\n async screenshot(options) {\n const base64 = await __pw_invoke(\"locatorAction\", [...this._getInfo(), \"screenshot\", options || {}], { pageId: this.#pageId });\n return base64;\n }\n async dragTo(target) {\n const targetInfo = target._getInfo();\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"dragTo\", targetInfo], { pageId: this.#pageId });\n }\n async scrollIntoViewIfNeeded() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"scrollIntoViewIfNeeded\", null], { pageId: this.#pageId });\n }\n async highlight() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"highlight\", null], { pageId: this.#pageId });\n }\n async evaluate(fn, arg) {\n const fnString = typeof fn === 'function' ? fn.toString() : fn;\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"evaluate\", [fnString, arg]], { pageId: this.#pageId });\n }\n async evaluateAll(fn, arg) {\n const fnString = typeof fn === 'function' ? fn.toString() : fn;\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"evaluateAll\", [fnString, arg]], { pageId: this.#pageId });\n }\n locator(selector) {\n return this._chain(\"css\", selector, null);\n }\n // Chaining: getBy* methods within a locator\n getByRole(role, options) {\n return this._chain(\"role\", role, serializeOptions(options));\n }\n getByText(text) {\n return this._chain(\"text\", text, null);\n }\n getByLabel(label) {\n return this._chain(\"label\", label, null);\n }\n getByPlaceholder(placeholder) {\n return this._chain(\"placeholder\", placeholder, null);\n }\n getByTestId(testId) {\n return this._chain(\"testId\", testId, null);\n }\n getByAltText(altText) {\n return this._chain(\"altText\", altText, null);\n }\n getByTitle(title) {\n return this._chain(\"title\", title, null);\n }\n async all() {\n const n = await this.count();\n const result = [];\n for (let i = 0; i < n; i++) {\n result.push(this.nth(i));\n }\n return result;\n }\n nth(index) {\n const existingOpts = this.#options ? JSON.parse(this.#options) : {};\n return new Locator(this.#type, this.#value, JSON.stringify({ ...existingOpts, nth: index }), this.#pageId);\n }\n first() {\n return this.nth(0);\n }\n last() {\n return this.nth(-1);\n }\n filter(options) {\n const existingOpts = this.#options ? JSON.parse(this.#options) : {};\n const serializedFilter = { ...options };\n // Use duck-typing RegExp detection (instanceof fails across isolated-vm boundary)\n const hasText = options.hasText;\n if (hasText && typeof hasText === 'object' && typeof hasText.source === 'string' && typeof hasText.flags === 'string') {\n serializedFilter.hasText = { $regex: hasText.source, $flags: hasText.flags };\n }\n const hasNotText = options.hasNotText;\n if (hasNotText && typeof hasNotText === 'object' && typeof hasNotText.source === 'string' && typeof hasNotText.flags === 'string') {\n serializedFilter.hasNotText = { $regex: hasNotText.source, $flags: hasNotText.flags };\n }\n // Serialize has/hasNot locators using duck-typing\n const has = options.has;\n if (has && typeof has === 'object' && typeof has._getInfo === 'function') {\n serializedFilter.has = { $locator: has._getInfo() };\n }\n const hasNot = options.hasNot;\n if (hasNot && typeof hasNot === 'object' && typeof hasNot._getInfo === 'function') {\n serializedFilter.hasNot = { $locator: hasNot._getInfo() };\n }\n return new Locator(this.#type, this.#value, JSON.stringify({ ...existingOpts, filter: serializedFilter }), this.#pageId);\n }\n or(other) {\n // Create a composite locator that matches either this or other\n const thisInfo = this._getInfo();\n const otherInfo = other._getInfo();\n return new Locator(\"or\", JSON.stringify([thisInfo, otherInfo]), null, this.#pageId);\n }\n and(other) {\n // Create a composite locator that matches both this and other\n const thisInfo = this._getInfo();\n const otherInfo = other._getInfo();\n return new Locator(\"and\", JSON.stringify([thisInfo, otherInfo]), null, this.#pageId);\n }\n }\n globalThis.Locator = Locator;\n})();\n`);\n\n // Extend expect with locator matchers (only if test-environment already defined expect)\n context.evalSync(`\n(function() {\n // Helper to create locator matchers\n function createLocatorMatchers(locator, baseMatchers) {\n const info = locator._getInfo();\n const pageId = locator._getPageId ? locator._getPageId() : \"page_0\";\n\n // Helper for serializing regex values\n function serializeExpected(expected) {\n if (expected instanceof RegExp) {\n return { $regex: expected.source, $flags: expected.flags };\n }\n return expected;\n }\n\n const locatorMatchers = {\n async toBeVisible(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeVisible\", null, false, options?.timeout], { pageId });\n },\n async toContainText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainText\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveValue(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveValue\", expected, false, options?.timeout], { pageId });\n },\n async toBeEnabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEnabled\", null, false, options?.timeout], { pageId });\n },\n async toBeChecked(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeChecked\", null, false, options?.timeout], { pageId });\n },\n async toHaveAttribute(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAttribute\", { name, value: serializeExpected(value) }, false, options?.timeout], { pageId });\n },\n async toHaveText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveText\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveCount(count, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCount\", count, false, options?.timeout], { pageId });\n },\n async toBeHidden(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeHidden\", null, false, options?.timeout], { pageId });\n },\n async toBeDisabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeDisabled\", null, false, options?.timeout], { pageId });\n },\n async toBeFocused(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeFocused\", null, false, options?.timeout], { pageId });\n },\n async toBeEmpty(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEmpty\", null, false, options?.timeout], { pageId });\n },\n // New matchers\n async toBeAttached(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeAttached\", null, false, options?.timeout], { pageId });\n },\n async toBeEditable(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEditable\", null, false, options?.timeout], { pageId });\n },\n async toHaveClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveClass\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toContainClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainClass\", expected, false, options?.timeout], { pageId });\n },\n async toHaveId(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveId\", expected, false, options?.timeout], { pageId });\n },\n async toBeInViewport(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeInViewport\", null, false, options?.timeout], { pageId });\n },\n async toHaveCSS(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCSS\", { name, value: serializeExpected(value) }, false, options?.timeout], { pageId });\n },\n async toHaveJSProperty(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveJSProperty\", { name, value }, false, options?.timeout], { pageId });\n },\n async toHaveAccessibleName(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleName\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveAccessibleDescription(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleDescription\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveRole(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveRole\", expected, false, options?.timeout], { pageId });\n },\n not: {\n async toBeVisible(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeVisible\", null, true, options?.timeout], { pageId });\n },\n async toContainText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainText\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveValue(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveValue\", expected, true, options?.timeout], { pageId });\n },\n async toBeEnabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEnabled\", null, true, options?.timeout], { pageId });\n },\n async toBeChecked(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeChecked\", null, true, options?.timeout], { pageId });\n },\n async toHaveAttribute(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAttribute\", { name, value: serializeExpected(value) }, true, options?.timeout], { pageId });\n },\n async toHaveText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveText\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveCount(count, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCount\", count, true, options?.timeout], { pageId });\n },\n async toBeHidden(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeHidden\", null, true, options?.timeout], { pageId });\n },\n async toBeDisabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeDisabled\", null, true, options?.timeout], { pageId });\n },\n async toBeFocused(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeFocused\", null, true, options?.timeout], { pageId });\n },\n async toBeEmpty(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEmpty\", null, true, options?.timeout], { pageId });\n },\n // New negated matchers\n async toBeAttached(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeAttached\", null, true, options?.timeout], { pageId });\n },\n async toBeEditable(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEditable\", null, true, options?.timeout], { pageId });\n },\n async toHaveClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveClass\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toContainClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainClass\", expected, true, options?.timeout], { pageId });\n },\n async toHaveId(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveId\", expected, true, options?.timeout], { pageId });\n },\n async toBeInViewport(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeInViewport\", null, true, options?.timeout], { pageId });\n },\n async toHaveCSS(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCSS\", { name, value: serializeExpected(value) }, true, options?.timeout], { pageId });\n },\n async toHaveJSProperty(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveJSProperty\", { name, value }, true, options?.timeout], { pageId });\n },\n async toHaveAccessibleName(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleName\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveAccessibleDescription(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleDescription\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveRole(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveRole\", expected, true, options?.timeout], { pageId });\n },\n }\n };\n\n // Merge locator matchers with base matchers from test-environment\n if (baseMatchers) {\n return {\n ...baseMatchers,\n ...locatorMatchers,\n not: { ...baseMatchers.not, ...locatorMatchers.not }\n };\n }\n return locatorMatchers;\n }\n\n // Helper to create page matchers\n function createPageMatchers(page, baseMatchers) {\n const pageId = page.__pageId || \"page_0\";\n\n function serializeExpected(expected) {\n if (expected instanceof RegExp) {\n return { $regex: expected.source, $flags: expected.flags };\n }\n return expected;\n }\n\n const pageMatchers = {\n async toHaveURL(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveURL\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveTitle(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveTitle\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n not: {\n async toHaveURL(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveURL\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveTitle(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveTitle\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n }\n };\n\n if (baseMatchers) {\n return {\n ...baseMatchers,\n ...pageMatchers,\n not: { ...baseMatchers.not, ...pageMatchers.not }\n };\n }\n return pageMatchers;\n }\n\n // Only extend expect if test-environment already defined it\n if (typeof globalThis.expect === 'function') {\n const originalExpect = globalThis.expect;\n globalThis.expect = function(actual) {\n const baseMatchers = originalExpect(actual);\n // If actual is a Locator, add locator-specific matchers\n if (actual && actual.constructor && actual.constructor.name === 'Locator') {\n return createLocatorMatchers(actual, baseMatchers);\n }\n // If actual is the page object (IsolatePage), add page-specific matchers\n if (actual && actual.__isPage === true) {\n return createPageMatchers(actual, baseMatchers);\n }\n return baseMatchers;\n };\n }\n // If test-environment not loaded, expect remains undefined\n})();\n`);\n\n // ========================================================================\n // Return Handle\n // ========================================================================\n\n return {\n dispose() {\n // Only remove listeners if page was provided directly\n if (page && requestHandler && responseHandler && consoleHandler) {\n page.off(\"request\", requestHandler);\n page.off(\"response\", responseHandler);\n page.off(\"console\", consoleHandler);\n }\n browserConsoleLogs.length = 0;\n networkRequests.length = 0;\n networkResponses.length = 0;\n },\n getBrowserConsoleLogs() {\n return [...browserConsoleLogs];\n },\n getNetworkRequests() {\n return [...networkRequests];\n },\n getNetworkResponses() {\n return [...networkResponses];\n },\n clearCollected() {\n browserConsoleLogs.length = 0;\n networkRequests.length = 0;\n networkResponses.length = 0;\n },\n };\n}\n"
|
|
5
|
+
"import ivm from \"isolated-vm\";\nimport type {\n PlaywrightOperation,\n} from \"@ricsam/isolate-protocol\";\nimport {\n DEFAULT_PLAYWRIGHT_HANDLER_META,\n} from \"./types.cjs\";\n\n// Re-export handler functions from handler.ts\nexport {\n createPlaywrightHandler,\n defaultPlaywrightHandler,\n getDefaultPlaywrightHandlerMetadata,\n} from \"./handler.cjs\";\n\n// Re-export protocol types\nexport type { PlaywrightOperation, PlaywrightResult, PlaywrightEvent, PlaywrightFileData } from \"@ricsam/isolate-protocol\";\nexport { DEFAULT_PLAYWRIGHT_HANDLER_META };\n\n// Re-export types from types.ts\nexport type {\n NetworkRequestInfo,\n NetworkResponseInfo,\n BrowserConsoleLogEntry,\n PlaywrightCallback,\n PlaywrightSetupOptions,\n PlaywrightHandle,\n} from \"./types.cjs\";\n\n// Import handler functions for use within this module\nimport {\n createPlaywrightHandler,\n getDefaultPlaywrightHandlerMetadata,\n} from \"./handler.cjs\";\nimport type {\n PlaywrightCallback,\n PlaywrightSetupOptions,\n PlaywrightHandle,\n NetworkRequestInfo,\n NetworkResponseInfo,\n BrowserConsoleLogEntry,\n} from \"./types.cjs\";\n\n// ============================================================================\n// Predicate Support Wrapper for Remote Handlers\n// ============================================================================\n\n/**\n * Wraps a remote handler (no direct page access) to support predicate-based\n * waitFor* operations. Predicate ops are handled locally by issuing sub-operations\n * through the handler and evaluating the predicate in the isolate.\n */\nfunction wrapHandlerWithPredicateSupport(\n handler: PlaywrightCallback,\n evaluatePredicate: (predicateId: number, data: unknown) => boolean,\n defaultTimeout: number,\n): PlaywrightCallback {\n return async (op) => {\n switch (op.type) {\n case \"waitForURLPredicate\": {\n const [predicateId, customTimeout, waitUntil] = op.args as [number, number?, string?];\n const effectiveTimeout = customTimeout ?? defaultTimeout;\n const startTime = Date.now();\n const pollInterval = 100;\n\n while (true) {\n // Get current URL via the handler\n const urlResult = await handler({ type: \"url\", args: [], pageId: op.pageId, contextId: op.contextId });\n if (urlResult.ok) {\n try {\n if (evaluatePredicate(predicateId, urlResult.value as string)) {\n return { ok: true };\n }\n } catch (e) {\n const error = e as Error;\n return { ok: false, error: { name: error.name, message: error.message } };\n }\n }\n if (effectiveTimeout > 0 && Date.now() - startTime >= effectiveTimeout) {\n return { ok: false, error: { name: \"Error\", message: `Timeout ${effectiveTimeout}ms exceeded waiting for URL` } };\n }\n await new Promise(r => setTimeout(r, pollInterval));\n }\n }\n case \"waitForResponsePredicateFinish\": {\n const [initialListenerId, predicateId, customTimeout] = op.args as [string, number, number?];\n const effectiveTimeout = customTimeout ?? defaultTimeout;\n const broadMatcher = { type: 'regex' as const, value: { $regex: '.*', $flags: '' } };\n const startTime = Date.now();\n let currentListenerId = initialListenerId;\n\n while (true) {\n // Wait for response data from current listener\n const finishResult = await handler({\n type: \"waitForResponseFinish\",\n args: [currentListenerId],\n pageId: op.pageId,\n contextId: op.contextId,\n });\n if (!finishResult.ok) return finishResult;\n const responseData = finishResult.value as Record<string, unknown>;\n\n // Evaluate predicate\n try {\n const serialized = {\n method: '',\n headers: Object.entries((responseData.headers || {}) as Record<string, string>),\n url: responseData.url as string,\n status: responseData.status as number,\n statusText: responseData.statusText as string,\n body: (responseData.text as string) || '',\n };\n if (evaluatePredicate(predicateId, serialized)) {\n return finishResult;\n }\n } catch (e) {\n const error = e as Error;\n return { ok: false, error: { name: error.name, message: error.message } };\n }\n\n if (effectiveTimeout > 0 && Date.now() - startTime >= effectiveTimeout) {\n return { ok: false, error: { name: \"Error\", message: `Timeout ${effectiveTimeout}ms exceeded waiting for response` } };\n }\n\n // Not matched — start next listener\n const remainingTimeout = effectiveTimeout > 0 ? Math.max(1, effectiveTimeout - (Date.now() - startTime)) : effectiveTimeout;\n const nextStartResult = await handler({\n type: \"waitForResponseStart\",\n args: [broadMatcher, remainingTimeout],\n pageId: op.pageId,\n contextId: op.contextId,\n });\n if (!nextStartResult.ok) return nextStartResult;\n currentListenerId = (nextStartResult.value as { listenerId: string }).listenerId;\n }\n }\n case \"waitForRequestPredicateFinish\": {\n const [initialListenerId, predicateId, customTimeout] = op.args as [string, number, number?];\n const effectiveTimeout = customTimeout ?? defaultTimeout;\n const broadMatcher = { type: 'regex' as const, value: { $regex: '.*', $flags: '' } };\n const startTime = Date.now();\n let currentListenerId = initialListenerId;\n\n while (true) {\n const finishResult = await handler({\n type: \"waitForRequestFinish\",\n args: [currentListenerId],\n pageId: op.pageId,\n contextId: op.contextId,\n });\n if (!finishResult.ok) return finishResult;\n const requestData = finishResult.value as Record<string, unknown>;\n\n try {\n const serialized = {\n method: requestData.method as string,\n headers: Object.entries((requestData.headers || {}) as Record<string, string>),\n url: requestData.url as string,\n body: (requestData.postData as string) || '',\n };\n if (evaluatePredicate(predicateId, serialized)) {\n return finishResult;\n }\n } catch (e) {\n const error = e as Error;\n return { ok: false, error: { name: error.name, message: error.message } };\n }\n\n if (effectiveTimeout > 0 && Date.now() - startTime >= effectiveTimeout) {\n return { ok: false, error: { name: \"Error\", message: `Timeout ${effectiveTimeout}ms exceeded waiting for request` } };\n }\n\n // Not matched — start next listener\n const remainingTimeout = effectiveTimeout > 0 ? Math.max(1, effectiveTimeout - (Date.now() - startTime)) : effectiveTimeout;\n const nextStartResult = await handler({\n type: \"waitForRequestStart\",\n args: [broadMatcher, remainingTimeout],\n pageId: op.pageId,\n contextId: op.contextId,\n });\n if (!nextStartResult.ok) return nextStartResult;\n currentListenerId = (nextStartResult.value as { listenerId: string }).listenerId;\n }\n }\n default:\n return handler(op);\n }\n };\n}\n\n// ============================================================================\n// Setup Playwright\n// ============================================================================\n\n/**\n * Set up playwright in an isolate context.\n *\n * For local use: provide `page` option (direct page access)\n * For remote use: provide `handler` option (callback pattern)\n */\nexport async function setupPlaywright(\n context: ivm.Context,\n options: PlaywrightSetupOptions\n): Promise<PlaywrightHandle> {\n const timeout = options.timeout ?? 30000;\n\n // Determine if we have a page or handler.\n // Handlers created via defaultPlaywrightHandler() carry page metadata so\n // event capture/collected data keeps working in handler-first mode.\n const explicitPage = \"page\" in options ? options.page : undefined;\n const handler = \"handler\" in options ? options.handler : undefined;\n const handlerMetadata = handler\n ? getDefaultPlaywrightHandlerMetadata(handler)\n : undefined;\n const page = explicitPage ?? handlerMetadata?.page;\n\n // Get lifecycle callbacks\n const createPage = \"createPage\" in options ? options.createPage : undefined;\n const createContext = \"createContext\" in options ? options.createContext : undefined;\n const readFile = \"readFile\" in options ? options.readFile : undefined;\n const writeFile = \"writeFile\" in options ? options.writeFile : undefined;\n\n if (!handler && !page) {\n throw new Error(\"Either page or handler must be provided to setupPlaywright\");\n }\n\n // State for collected data (only used when page is provided directly)\n const browserConsoleLogs: BrowserConsoleLogEntry[] = [];\n const networkRequests: NetworkRequestInfo[] = [];\n const networkResponses: NetworkResponseInfo[] = [];\n\n const global = context.global;\n\n // ========================================================================\n // Event Capture (only when page is provided directly)\n // ========================================================================\n\n let requestHandler: ((request: import(\"playwright\").Request) => void) | undefined;\n let responseHandler: ((response: import(\"playwright\").Response) => void) | undefined;\n let consoleHandler: ((msg: import(\"playwright\").ConsoleMessage) => void) | undefined;\n\n if (page) {\n // Get onEvent callback if provided\n const onEvent = \"onEvent\" in options ? options.onEvent : undefined;\n\n requestHandler = (request: import(\"playwright\").Request) => {\n const info: NetworkRequestInfo = {\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n postData: request.postData() ?? undefined,\n resourceType: request.resourceType(),\n timestamp: Date.now(),\n };\n networkRequests.push(info);\n\n if (onEvent) {\n onEvent({\n type: \"networkRequest\",\n url: info.url,\n method: info.method,\n headers: info.headers,\n postData: info.postData,\n resourceType: info.resourceType,\n timestamp: info.timestamp,\n });\n }\n };\n\n responseHandler = (response: import(\"playwright\").Response) => {\n const info: NetworkResponseInfo = {\n url: response.url(),\n status: response.status(),\n statusText: response.statusText(),\n headers: response.headers(),\n timestamp: Date.now(),\n };\n networkResponses.push(info);\n\n if (onEvent) {\n onEvent({\n type: \"networkResponse\",\n url: info.url,\n status: info.status,\n statusText: info.statusText,\n headers: info.headers,\n timestamp: info.timestamp,\n });\n }\n };\n\n consoleHandler = (msg: import(\"playwright\").ConsoleMessage) => {\n const args = msg.args().map((arg) => String(arg));\n const entry: BrowserConsoleLogEntry = {\n level: msg.type(),\n stdout: args.join(\" \"),\n timestamp: Date.now(),\n };\n browserConsoleLogs.push(entry);\n\n if (onEvent) {\n onEvent({\n type: \"browserConsoleLog\",\n level: entry.level,\n stdout: entry.stdout,\n timestamp: entry.timestamp,\n });\n }\n\n // Print to stdout if console option is true\n if (\"console\" in options && options.console) {\n const prefix = `[browser:${entry.level}]`;\n console.log(prefix, entry.stdout);\n }\n };\n\n page.on(\"request\", requestHandler);\n page.on(\"response\", responseHandler);\n page.on(\"console\", consoleHandler);\n }\n\n // ========================================================================\n // Injected JavaScript\n // ========================================================================\n\n // Helper function to invoke handler and handle errors\n context.evalSync(`\n(function() {\n globalThis.__pw_invoke_sync = function(type, args, options) {\n const op = JSON.stringify({ type, args, pageId: options?.pageId, contextId: options?.contextId });\n const resultJson = __Playwright_handler_ref.applySyncPromise(undefined, [op]);\n const result = JSON.parse(resultJson);\n if (result.ok) {\n return result.value;\n } else {\n const error = new Error(result.error.message);\n error.name = result.error.name;\n throw error;\n }\n };\n globalThis.__pw_invoke = async function(type, args, options) {\n return globalThis.__pw_invoke_sync(type, args, options);\n };\n})();\n`);\n\n // Predicate registry for waitForURL/Request/Response with function predicates\n context.evalSync(`\n(function() {\n const __pw_predicates = new Map();\n let __pw_next_id = 0;\n globalThis.__pw_register_predicate = function(fn) {\n const id = __pw_next_id++;\n __pw_predicates.set(id, fn);\n return id;\n };\n globalThis.__pw_unregister_predicate = function(id) {\n __pw_predicates.delete(id);\n };\n globalThis.__pw_evaluate_predicate = function(id, data) {\n const fn = __pw_predicates.get(id);\n if (!fn) throw new Error('Predicate not found: ' + id);\n const result = fn(data);\n if (result && typeof result === 'object' && typeof result.then === 'function') {\n throw new Error('Async predicates are not supported. Use a synchronous predicate function.');\n }\n return !!result;\n };\n})();\n`);\n\n // Get reference to the predicate evaluation function for host-side use\n const evaluatePredicateRef = context.global.getSync(\n '__pw_evaluate_predicate', { reference: true }\n ) as ivm.Reference<(id: number, data: unknown) => boolean>;\n\n // ========================================================================\n // Create Handler and Unified Handler Reference\n // ========================================================================\n\n const evaluatePredicateFn = (predicateId: number, data: unknown): boolean => {\n return evaluatePredicateRef.applySync(\n undefined,\n [new ivm.ExternalCopy(predicateId).copyInto(), new ivm.ExternalCopy(data).copyInto()]\n ) as boolean;\n };\n\n // Create handler with evaluatePredicate support.\n // When a page is available (either directly or through handler metadata),\n // create a handler with evaluatePredicate for efficient event-based predicate evaluation.\n // When only a remote handler is available (no page), wrap it to intercept predicate\n // operations and implement them via polling/sub-operations.\n let effectiveHandler: PlaywrightCallback;\n if (handler && handlerMetadata?.page) {\n // Handler-first mode with page metadata — recreate with evaluatePredicate\n effectiveHandler = createPlaywrightHandler(handlerMetadata.page, {\n ...handlerMetadata.options,\n evaluatePredicate: evaluatePredicateFn,\n });\n } else if (handler) {\n // Remote handler without page — wrap to handle predicate ops locally\n effectiveHandler = wrapHandlerWithPredicateSupport(handler, evaluatePredicateFn, timeout);\n } else if (page) {\n effectiveHandler = createPlaywrightHandler(page, {\n timeout,\n readFile,\n writeFile,\n createPage,\n createContext,\n evaluatePredicate: evaluatePredicateFn,\n });\n } else {\n throw new Error(\"Either page or handler must be provided to setupPlaywright\");\n }\n\n // Single handler reference that receives operation objects\n global.setSync(\n \"__Playwright_handler_ref\",\n new ivm.Reference(async (opJson: string): Promise<string> => {\n const op = JSON.parse(opJson) as PlaywrightOperation;\n const result = await effectiveHandler(op);\n return JSON.stringify(result);\n })\n );\n\n // IsolatePage class and page/context/browser globals\n context.evalSync(`\n(function() {\n // IsolatePage class - represents a page with a specific pageId\n class IsolatePage {\n #pageId; #contextId;\n constructor(pageId, contextId) {\n this.#pageId = pageId;\n this.#contextId = contextId;\n }\n get __isPage() { return true; }\n get __pageId() { return this.#pageId; }\n get __contextId() { return this.#contextId; }\n\n async goto(url, options) {\n await __pw_invoke(\"goto\", [url, options?.waitUntil || null], { pageId: this.#pageId });\n }\n async reload() {\n await __pw_invoke(\"reload\", [], { pageId: this.#pageId });\n }\n url() { return __pw_invoke_sync(\"url\", [], { pageId: this.#pageId }); }\n async title() { return __pw_invoke(\"title\", [], { pageId: this.#pageId }); }\n async content() { return __pw_invoke(\"content\", [], { pageId: this.#pageId }); }\n async waitForSelector(selector, options) {\n return __pw_invoke(\"waitForSelector\", [selector, options ? JSON.stringify(options) : null], { pageId: this.#pageId });\n }\n async waitForTimeout(ms) { return __pw_invoke(\"waitForTimeout\", [ms], { pageId: this.#pageId }); }\n async waitForLoadState(state) { return __pw_invoke(\"waitForLoadState\", [state || null], { pageId: this.#pageId }); }\n async evaluate(script, arg) {\n const hasArg = arguments.length > 1;\n if (hasArg) {\n const serialized = typeof script === \"function\" ? script.toString() : script;\n return __pw_invoke(\"evaluate\", [serialized, arg], { pageId: this.#pageId });\n }\n const serialized = typeof script === \"function\" ? \"(\" + script.toString() + \")()\" : script;\n return __pw_invoke(\"evaluate\", [serialized], { pageId: this.#pageId });\n }\n locator(selector) { return new Locator(\"css\", selector, null, this.#pageId); }\n getByRole(role, options) {\n if (options) {\n const serialized = { ...options };\n const name = options.name;\n if (name && typeof name === 'object' && typeof name.source === 'string' && typeof name.flags === 'string') {\n serialized.name = { $regex: name.source, $flags: name.flags };\n }\n return new Locator(\"role\", role, JSON.stringify(serialized), this.#pageId);\n }\n return new Locator(\"role\", role, null, this.#pageId);\n }\n getByText(text) { return new Locator(\"text\", text, null, this.#pageId); }\n getByLabel(label) { return new Locator(\"label\", label, null, this.#pageId); }\n getByPlaceholder(p) { return new Locator(\"placeholder\", p, null, this.#pageId); }\n getByTestId(id) { return new Locator(\"testId\", id, null, this.#pageId); }\n getByAltText(alt) { return new Locator(\"altText\", alt, null, this.#pageId); }\n getByTitle(title) { return new Locator(\"title\", title, null, this.#pageId); }\n frameLocator(selector) {\n const pageId = this.#pageId;\n return {\n locator(innerSelector) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"css\", innerSelector, null]]), null, pageId); },\n getByRole(role, options) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"role\", role, options ? JSON.stringify(options) : null]]), null, pageId); },\n getByText(text) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"text\", text, null]]), null, pageId); },\n getByLabel(label) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"label\", label, null]]), null, pageId); },\n getByPlaceholder(placeholder) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"placeholder\", placeholder, null]]), null, pageId); },\n getByTestId(testId) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"testId\", testId, null]]), null, pageId); },\n getByAltText(alt) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"altText\", alt, null]]), null, pageId); },\n getByTitle(title) { return new Locator(\"frame\", JSON.stringify([[\"css\", selector, null], [\"title\", title, null]]), null, pageId); },\n };\n }\n async goBack(options) {\n await __pw_invoke(\"goBack\", [options?.waitUntil || null], { pageId: this.#pageId });\n }\n async goForward(options) {\n await __pw_invoke(\"goForward\", [options?.waitUntil || null], { pageId: this.#pageId });\n }\n async waitForURL(url, options) {\n if (typeof url === 'function') {\n const predicateId = __pw_register_predicate(url);\n try {\n await __pw_invoke(\"waitForURLPredicate\", [predicateId, options?.timeout || null, options?.waitUntil || null], { pageId: this.#pageId });\n } finally {\n __pw_unregister_predicate(predicateId);\n }\n return;\n }\n let serializedUrl;\n if (typeof url === 'string') {\n serializedUrl = { type: 'string', value: url };\n } else if (url && typeof url === 'object' && typeof url.source === 'string' && typeof url.flags === 'string') {\n serializedUrl = { type: 'regex', value: { $regex: url.source, $flags: url.flags } };\n } else {\n serializedUrl = url;\n }\n return __pw_invoke(\"waitForURL\", [serializedUrl, options?.timeout || null, options?.waitUntil || null], { pageId: this.#pageId });\n }\n waitForRequest(urlOrPredicate, options) {\n if (typeof urlOrPredicate === 'function') {\n const userPredicate = urlOrPredicate;\n const wrappedPredicate = (data) => {\n const requestLike = {\n url: () => data.url,\n method: () => data.method,\n headers: () => Object.fromEntries(data.headers),\n headersArray: () => data.headers.map(h => ({ name: h[0], value: h[1] })),\n postData: () => data.body || null,\n };\n return userPredicate(requestLike);\n };\n const predicateId = __pw_register_predicate(wrappedPredicate);\n const pageId = this.#pageId;\n // Start listening immediately (before the user triggers the request)\n const broadMatcher = { type: 'regex', value: { $regex: '.*', $flags: '' } };\n const startResult = __pw_invoke_sync(\"waitForRequestStart\", [broadMatcher, options?.timeout || null], { pageId });\n const listenerId = startResult.listenerId;\n return {\n then(resolve, reject) {\n try {\n const r = __pw_invoke_sync(\"waitForRequestPredicateFinish\", [listenerId, predicateId, options?.timeout || null], { pageId });\n resolve({ url: () => r.url, method: () => r.method, headers: () => r.headers, postData: () => r.postData });\n } catch(e) { reject(e); } finally { __pw_unregister_predicate(predicateId); }\n }\n };\n }\n let serializedMatcher;\n if (typeof urlOrPredicate === 'string') {\n serializedMatcher = { type: 'string', value: urlOrPredicate };\n } else if (urlOrPredicate && typeof urlOrPredicate === 'object'\n && typeof urlOrPredicate.source === 'string'\n && typeof urlOrPredicate.flags === 'string') {\n serializedMatcher = { type: 'regex', value: { $regex: urlOrPredicate.source, $flags: urlOrPredicate.flags } };\n } else {\n throw new Error('waitForRequest requires a URL string, RegExp, or predicate function');\n }\n const startResult = __pw_invoke_sync(\"waitForRequestStart\", [serializedMatcher, options?.timeout || null], { pageId: this.#pageId });\n const listenerId = startResult.listenerId;\n const pageId = this.#pageId;\n return {\n then(resolve, reject) {\n try {\n const r = __pw_invoke_sync(\"waitForRequestFinish\", [listenerId], { pageId });\n resolve({ url: () => r.url, method: () => r.method, headers: () => r.headers, postData: () => r.postData });\n } catch(e) { reject(e); }\n }\n };\n }\n waitForResponse(urlOrPredicate, options) {\n if (typeof urlOrPredicate === 'function') {\n const userPredicate = urlOrPredicate;\n const wrappedPredicate = (data) => {\n const responseLike = {\n url: () => data.url,\n status: () => data.status,\n statusText: () => data.statusText,\n headers: () => Object.fromEntries(data.headers),\n headersArray: () => data.headers.map(h => ({ name: h[0], value: h[1] })),\n ok: () => data.status >= 200 && data.status < 300,\n };\n return userPredicate(responseLike);\n };\n const predicateId = __pw_register_predicate(wrappedPredicate);\n const pageId = this.#pageId;\n // Start listening immediately (before the user triggers the response)\n const broadMatcher = { type: 'regex', value: { $regex: '.*', $flags: '' } };\n const startResult = __pw_invoke_sync(\"waitForResponseStart\", [broadMatcher, options?.timeout || null], { pageId });\n const listenerId = startResult.listenerId;\n return {\n then(resolve, reject) {\n try {\n const r = __pw_invoke_sync(\"waitForResponsePredicateFinish\", [listenerId, predicateId, options?.timeout || null], { pageId });\n resolve({\n url: () => r.url, status: () => r.status, statusText: () => r.statusText,\n headers: () => r.headers, headersArray: () => r.headersArray,\n ok: () => r.ok, json: async () => r.json, text: async () => r.text, body: async () => r.body,\n });\n } catch(e) { reject(e); } finally { __pw_unregister_predicate(predicateId); }\n }\n };\n }\n let serializedMatcher;\n if (typeof urlOrPredicate === 'string') {\n serializedMatcher = { type: 'string', value: urlOrPredicate };\n } else if (urlOrPredicate && typeof urlOrPredicate === 'object'\n && typeof urlOrPredicate.source === 'string'\n && typeof urlOrPredicate.flags === 'string') {\n serializedMatcher = { type: 'regex', value: { $regex: urlOrPredicate.source, $flags: urlOrPredicate.flags } };\n } else {\n throw new Error('waitForResponse requires a URL string, RegExp, or predicate function');\n }\n const startResult = __pw_invoke_sync(\"waitForResponseStart\", [serializedMatcher, options?.timeout || null], { pageId: this.#pageId });\n const listenerId = startResult.listenerId;\n const pageId = this.#pageId;\n return {\n then(resolve, reject) {\n try {\n const r = __pw_invoke_sync(\"waitForResponseFinish\", [listenerId], { pageId });\n resolve({\n url: () => r.url, status: () => r.status, statusText: () => r.statusText,\n headers: () => r.headers, headersArray: () => r.headersArray,\n ok: () => r.ok, json: async () => r.json, text: async () => r.text, body: async () => r.body,\n });\n } catch(e) { reject(e); }\n }\n };\n }\n context() {\n const contextId = this.#contextId;\n return new IsolateContext(contextId);\n }\n async click(selector) { return this.locator(selector).click(); }\n async fill(selector, value) { return this.locator(selector).fill(value); }\n async textContent(selector) { return this.locator(selector).textContent(); }\n async innerText(selector) { return this.locator(selector).innerText(); }\n async innerHTML(selector) { return this.locator(selector).innerHTML(); }\n async getAttribute(selector, name) { return this.locator(selector).getAttribute(name); }\n async inputValue(selector) { return this.locator(selector).inputValue(); }\n async isVisible(selector) { return this.locator(selector).isVisible(); }\n async isEnabled(selector) { return this.locator(selector).isEnabled(); }\n async isChecked(selector) { return this.locator(selector).isChecked(); }\n async isHidden(selector) { return this.locator(selector).isHidden(); }\n async isDisabled(selector) { return this.locator(selector).isDisabled(); }\n async screenshot(options) { return __pw_invoke(\"screenshot\", [options || {}], { pageId: this.#pageId }); }\n async setViewportSize(size) { return __pw_invoke(\"setViewportSize\", [size], { pageId: this.#pageId }); }\n async viewportSize() { return __pw_invoke(\"viewportSize\", [], { pageId: this.#pageId }); }\n async emulateMedia(options) { return __pw_invoke(\"emulateMedia\", [options], { pageId: this.#pageId }); }\n async setExtraHTTPHeaders(headers) { return __pw_invoke(\"setExtraHTTPHeaders\", [headers], { pageId: this.#pageId }); }\n async bringToFront() { return __pw_invoke(\"bringToFront\", [], { pageId: this.#pageId }); }\n async close() { return __pw_invoke(\"close\", [], { pageId: this.#pageId }); }\n async isClosed() { return __pw_invoke(\"isClosed\", [], { pageId: this.#pageId }); }\n async pdf(options) { return __pw_invoke(\"pdf\", [options || {}], { pageId: this.#pageId }); }\n async pause() { return __pw_invoke(\"pause\", [], { pageId: this.#pageId }); }\n async frames() { return __pw_invoke(\"frames\", [], { pageId: this.#pageId }); }\n async mainFrame() { return __pw_invoke(\"mainFrame\", [], { pageId: this.#pageId }); }\n get keyboard() {\n const pageId = this.#pageId;\n return {\n async type(text, options) { return __pw_invoke(\"keyboardType\", [text, options], { pageId }); },\n async press(key, options) { return __pw_invoke(\"keyboardPress\", [key, options], { pageId }); },\n async down(key) { return __pw_invoke(\"keyboardDown\", [key], { pageId }); },\n async up(key) { return __pw_invoke(\"keyboardUp\", [key], { pageId }); },\n async insertText(text) { return __pw_invoke(\"keyboardInsertText\", [text], { pageId }); }\n };\n }\n get mouse() {\n const pageId = this.#pageId;\n return {\n async move(x, y, options) { return __pw_invoke(\"mouseMove\", [x, y, options], { pageId }); },\n async click(x, y, options) { return __pw_invoke(\"mouseClick\", [x, y, options], { pageId }); },\n async down(options) { return __pw_invoke(\"mouseDown\", [options], { pageId }); },\n async up(options) { return __pw_invoke(\"mouseUp\", [options], { pageId }); },\n async wheel(deltaX, deltaY) { return __pw_invoke(\"mouseWheel\", [deltaX, deltaY], { pageId }); }\n };\n }\n get request() {\n const pageId = this.#pageId;\n return {\n async fetch(url, options) {\n const result = await __pw_invoke(\"request\", [url, options?.method || \"GET\", options?.data, options?.headers], { pageId });\n return {\n status: () => result.status,\n ok: () => result.ok,\n headers: () => result.headers,\n json: async () => result.json,\n text: async () => result.text,\n body: async () => result.body,\n };\n },\n async get(url, options) { return this.fetch(url, { ...options, method: \"GET\" }); },\n async post(url, options) { return this.fetch(url, { ...options, method: \"POST\" }); },\n async put(url, options) { return this.fetch(url, { ...options, method: \"PUT\" }); },\n async delete(url, options) { return this.fetch(url, { ...options, method: \"DELETE\" }); },\n };\n }\n }\n globalThis.IsolatePage = IsolatePage;\n\n // IsolateContext class - represents a browser context with a specific contextId\n class IsolateContext {\n #contextId;\n constructor(contextId) { this.#contextId = contextId; }\n get __contextId() { return this.#contextId; }\n\n async newPage() {\n const result = await __pw_invoke(\"newPage\", [], { contextId: this.#contextId });\n return new IsolatePage(result.pageId, this.#contextId);\n }\n async close() { return __pw_invoke(\"closeContext\", [], { contextId: this.#contextId }); }\n async clearCookies() { return __pw_invoke(\"clearCookies\", [], { contextId: this.#contextId }); }\n async addCookies(cookies) { return __pw_invoke(\"addCookies\", [cookies], { contextId: this.#contextId }); }\n async cookies(urls) { return __pw_invoke(\"cookies\", [urls], { contextId: this.#contextId }); }\n }\n globalThis.IsolateContext = IsolateContext;\n\n // browser global - for creating new contexts\n globalThis.browser = {\n async newContext(options) {\n const result = await __pw_invoke(\"newContext\", [options || null]);\n return new IsolateContext(result.contextId);\n }\n };\n\n // context global - represents the default context\n globalThis.context = new IsolateContext(\"ctx_0\");\n\n // page global - represents the default page\n globalThis.page = new IsolatePage(\"page_0\", \"ctx_0\");\n})();\n`);\n\n // Locator class with pageId support\n context.evalSync(`\n(function() {\n // Helper to serialize options including RegExp\n function serializeOptions(options) {\n if (!options) return null;\n const serialized = { ...options };\n if (options.name && typeof options.name === 'object' && typeof options.name.source === 'string' && typeof options.name.flags === 'string') {\n serialized.name = { $regex: options.name.source, $flags: options.name.flags };\n }\n return JSON.stringify(serialized);\n }\n\n const INPUT_FILES_VALIDATION_ERROR =\n \"setInputFiles() expects a file path string, an array of file path strings, \" +\n \"a single inline file object ({ name, mimeType, buffer }), or an array of inline file objects.\";\n\n function isInlineFileObject(value) {\n return !!value\n && typeof value === 'object'\n && typeof value.name === 'string'\n && typeof value.mimeType === 'string'\n && 'buffer' in value;\n }\n\n function encodeInlineFileBuffer(buffer) {\n if (typeof buffer === 'string') {\n return buffer;\n }\n let bytes;\n if (buffer instanceof ArrayBuffer) {\n bytes = new Uint8Array(buffer);\n } else if (ArrayBuffer.isView(buffer)) {\n bytes = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n } else {\n throw new Error(\n \"setInputFiles() inline file buffer must be a base64 string, ArrayBuffer, or TypedArray.\"\n );\n }\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n function serializeInlineFile(file) {\n return {\n name: file.name,\n mimeType: file.mimeType,\n buffer: encodeInlineFileBuffer(file.buffer),\n };\n }\n\n function normalizeSetInputFilesArg(files) {\n if (typeof files === 'string') {\n return files;\n }\n if (isInlineFileObject(files)) {\n return serializeInlineFile(files);\n }\n if (!Array.isArray(files)) {\n throw new Error(INPUT_FILES_VALIDATION_ERROR);\n }\n if (files.length === 0) {\n return [];\n }\n\n let hasPaths = false;\n let hasInline = false;\n const inlineFiles = [];\n\n for (const file of files) {\n if (typeof file === 'string') {\n hasPaths = true;\n continue;\n }\n if (isInlineFileObject(file)) {\n hasInline = true;\n inlineFiles.push(serializeInlineFile(file));\n continue;\n }\n throw new Error(INPUT_FILES_VALIDATION_ERROR);\n }\n\n if (hasPaths && hasInline) {\n throw new Error(\n \"setInputFiles() does not support mixing file paths and inline file objects in the same array.\"\n );\n }\n return hasInline ? inlineFiles : files;\n }\n\n class Locator {\n #type; #value; #options; #pageId;\n constructor(type, value, options, pageId) {\n this.#type = type;\n this.#value = value;\n this.#options = options;\n this.#pageId = pageId || \"page_0\";\n }\n\n _getInfo() { return [this.#type, this.#value, this.#options]; }\n _getPageId() { return this.#pageId; }\n\n // Helper to create a chained locator\n _chain(childType, childValue, childOptions) {\n const parentInfo = this._getInfo();\n const childInfo = [childType, childValue, childOptions];\n return new Locator(\"chained\", JSON.stringify([parentInfo, childInfo]), null, this.#pageId);\n }\n\n async click() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"click\", null], { pageId: this.#pageId });\n }\n async dblclick() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"dblclick\", null], { pageId: this.#pageId });\n }\n async fill(text) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"fill\", text], { pageId: this.#pageId });\n }\n async type(text) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"type\", text], { pageId: this.#pageId });\n }\n async check() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"check\", null], { pageId: this.#pageId });\n }\n async uncheck() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"uncheck\", null], { pageId: this.#pageId });\n }\n async selectOption(value) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"selectOption\", value], { pageId: this.#pageId });\n }\n async clear() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"clear\", null], { pageId: this.#pageId });\n }\n async press(key) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"press\", key], { pageId: this.#pageId });\n }\n async hover() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"hover\", null], { pageId: this.#pageId });\n }\n async focus() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"focus\", null], { pageId: this.#pageId });\n }\n async textContent() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getText\", null], { pageId: this.#pageId });\n }\n async inputValue() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getValue\", null], { pageId: this.#pageId });\n }\n async isVisible() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isVisible\", null], { pageId: this.#pageId });\n }\n async isEnabled() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isEnabled\", null], { pageId: this.#pageId });\n }\n async isChecked() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isChecked\", null], { pageId: this.#pageId });\n }\n async count() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"count\", null], { pageId: this.#pageId });\n }\n async getAttribute(name) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"getAttribute\", name], { pageId: this.#pageId });\n }\n async isDisabled() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isDisabled\", null], { pageId: this.#pageId });\n }\n async isHidden() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"isHidden\", null], { pageId: this.#pageId });\n }\n async innerHTML() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"innerHTML\", null], { pageId: this.#pageId });\n }\n async innerText() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"innerText\", null], { pageId: this.#pageId });\n }\n async allTextContents() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"allTextContents\", null], { pageId: this.#pageId });\n }\n async allInnerTexts() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"allInnerTexts\", null], { pageId: this.#pageId });\n }\n async waitFor(options) {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"waitFor\", options || {}], { pageId: this.#pageId });\n }\n async boundingBox() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"boundingBox\", null], { pageId: this.#pageId });\n }\n async setInputFiles(files) {\n const serializedFiles = normalizeSetInputFilesArg(files);\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"setInputFiles\", serializedFiles], { pageId: this.#pageId });\n }\n async screenshot(options) {\n const base64 = await __pw_invoke(\"locatorAction\", [...this._getInfo(), \"screenshot\", options || {}], { pageId: this.#pageId });\n return base64;\n }\n async dragTo(target) {\n const targetInfo = target._getInfo();\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"dragTo\", targetInfo], { pageId: this.#pageId });\n }\n async scrollIntoViewIfNeeded() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"scrollIntoViewIfNeeded\", null], { pageId: this.#pageId });\n }\n async highlight() {\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"highlight\", null], { pageId: this.#pageId });\n }\n async evaluate(fn, arg) {\n const fnString = typeof fn === 'function' ? fn.toString() : fn;\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"evaluate\", [fnString, arg]], { pageId: this.#pageId });\n }\n async evaluateAll(fn, arg) {\n const fnString = typeof fn === 'function' ? fn.toString() : fn;\n return __pw_invoke(\"locatorAction\", [...this._getInfo(), \"evaluateAll\", [fnString, arg]], { pageId: this.#pageId });\n }\n locator(selector) {\n return this._chain(\"css\", selector, null);\n }\n // Chaining: getBy* methods within a locator\n getByRole(role, options) {\n return this._chain(\"role\", role, serializeOptions(options));\n }\n getByText(text) {\n return this._chain(\"text\", text, null);\n }\n getByLabel(label) {\n return this._chain(\"label\", label, null);\n }\n getByPlaceholder(placeholder) {\n return this._chain(\"placeholder\", placeholder, null);\n }\n getByTestId(testId) {\n return this._chain(\"testId\", testId, null);\n }\n getByAltText(altText) {\n return this._chain(\"altText\", altText, null);\n }\n getByTitle(title) {\n return this._chain(\"title\", title, null);\n }\n async all() {\n const n = await this.count();\n const result = [];\n for (let i = 0; i < n; i++) {\n result.push(this.nth(i));\n }\n return result;\n }\n nth(index) {\n const existingOpts = this.#options ? JSON.parse(this.#options) : {};\n return new Locator(this.#type, this.#value, JSON.stringify({ ...existingOpts, nth: index }), this.#pageId);\n }\n first() {\n return this.nth(0);\n }\n last() {\n return this.nth(-1);\n }\n filter(options) {\n const existingOpts = this.#options ? JSON.parse(this.#options) : {};\n const serializedFilter = { ...options };\n // Use duck-typing RegExp detection (instanceof fails across isolated-vm boundary)\n const hasText = options.hasText;\n if (hasText && typeof hasText === 'object' && typeof hasText.source === 'string' && typeof hasText.flags === 'string') {\n serializedFilter.hasText = { $regex: hasText.source, $flags: hasText.flags };\n }\n const hasNotText = options.hasNotText;\n if (hasNotText && typeof hasNotText === 'object' && typeof hasNotText.source === 'string' && typeof hasNotText.flags === 'string') {\n serializedFilter.hasNotText = { $regex: hasNotText.source, $flags: hasNotText.flags };\n }\n // Serialize has/hasNot locators using duck-typing\n const has = options.has;\n if (has && typeof has === 'object' && typeof has._getInfo === 'function') {\n serializedFilter.has = { $locator: has._getInfo() };\n }\n const hasNot = options.hasNot;\n if (hasNot && typeof hasNot === 'object' && typeof hasNot._getInfo === 'function') {\n serializedFilter.hasNot = { $locator: hasNot._getInfo() };\n }\n return new Locator(this.#type, this.#value, JSON.stringify({ ...existingOpts, filter: serializedFilter }), this.#pageId);\n }\n or(other) {\n // Create a composite locator that matches either this or other\n const thisInfo = this._getInfo();\n const otherInfo = other._getInfo();\n return new Locator(\"or\", JSON.stringify([thisInfo, otherInfo]), null, this.#pageId);\n }\n and(other) {\n // Create a composite locator that matches both this and other\n const thisInfo = this._getInfo();\n const otherInfo = other._getInfo();\n return new Locator(\"and\", JSON.stringify([thisInfo, otherInfo]), null, this.#pageId);\n }\n }\n globalThis.Locator = Locator;\n})();\n`);\n\n // Extend expect with locator matchers (only if test-environment already defined expect)\n context.evalSync(`\n(function() {\n // Helper to create locator matchers\n function createLocatorMatchers(locator, baseMatchers) {\n const info = locator._getInfo();\n const pageId = locator._getPageId ? locator._getPageId() : \"page_0\";\n\n // Helper for serializing regex values\n function serializeExpected(expected) {\n if (expected instanceof RegExp) {\n return { $regex: expected.source, $flags: expected.flags };\n }\n return expected;\n }\n\n const locatorMatchers = {\n async toBeVisible(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeVisible\", null, false, options?.timeout], { pageId });\n },\n async toContainText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainText\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveValue(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveValue\", expected, false, options?.timeout], { pageId });\n },\n async toBeEnabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEnabled\", null, false, options?.timeout], { pageId });\n },\n async toBeChecked(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeChecked\", null, false, options?.timeout], { pageId });\n },\n async toHaveAttribute(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAttribute\", { name, value: serializeExpected(value) }, false, options?.timeout], { pageId });\n },\n async toHaveText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveText\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveCount(count, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCount\", count, false, options?.timeout], { pageId });\n },\n async toBeHidden(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeHidden\", null, false, options?.timeout], { pageId });\n },\n async toBeDisabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeDisabled\", null, false, options?.timeout], { pageId });\n },\n async toBeFocused(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeFocused\", null, false, options?.timeout], { pageId });\n },\n async toBeEmpty(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEmpty\", null, false, options?.timeout], { pageId });\n },\n // New matchers\n async toBeAttached(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeAttached\", null, false, options?.timeout], { pageId });\n },\n async toBeEditable(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEditable\", null, false, options?.timeout], { pageId });\n },\n async toHaveClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveClass\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toContainClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainClass\", expected, false, options?.timeout], { pageId });\n },\n async toHaveId(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveId\", expected, false, options?.timeout], { pageId });\n },\n async toBeInViewport(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeInViewport\", null, false, options?.timeout], { pageId });\n },\n async toHaveCSS(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCSS\", { name, value: serializeExpected(value) }, false, options?.timeout], { pageId });\n },\n async toHaveJSProperty(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveJSProperty\", { name, value }, false, options?.timeout], { pageId });\n },\n async toHaveAccessibleName(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleName\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveAccessibleDescription(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleDescription\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveRole(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveRole\", expected, false, options?.timeout], { pageId });\n },\n not: {\n async toBeVisible(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeVisible\", null, true, options?.timeout], { pageId });\n },\n async toContainText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainText\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveValue(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveValue\", expected, true, options?.timeout], { pageId });\n },\n async toBeEnabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEnabled\", null, true, options?.timeout], { pageId });\n },\n async toBeChecked(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeChecked\", null, true, options?.timeout], { pageId });\n },\n async toHaveAttribute(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAttribute\", { name, value: serializeExpected(value) }, true, options?.timeout], { pageId });\n },\n async toHaveText(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveText\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveCount(count, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCount\", count, true, options?.timeout], { pageId });\n },\n async toBeHidden(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeHidden\", null, true, options?.timeout], { pageId });\n },\n async toBeDisabled(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeDisabled\", null, true, options?.timeout], { pageId });\n },\n async toBeFocused(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeFocused\", null, true, options?.timeout], { pageId });\n },\n async toBeEmpty(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEmpty\", null, true, options?.timeout], { pageId });\n },\n // New negated matchers\n async toBeAttached(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeAttached\", null, true, options?.timeout], { pageId });\n },\n async toBeEditable(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeEditable\", null, true, options?.timeout], { pageId });\n },\n async toHaveClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveClass\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toContainClass(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toContainClass\", expected, true, options?.timeout], { pageId });\n },\n async toHaveId(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveId\", expected, true, options?.timeout], { pageId });\n },\n async toBeInViewport(options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toBeInViewport\", null, true, options?.timeout], { pageId });\n },\n async toHaveCSS(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveCSS\", { name, value: serializeExpected(value) }, true, options?.timeout], { pageId });\n },\n async toHaveJSProperty(name, value, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveJSProperty\", { name, value }, true, options?.timeout], { pageId });\n },\n async toHaveAccessibleName(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleName\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveAccessibleDescription(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveAccessibleDescription\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveRole(expected, options) {\n return __pw_invoke(\"expectLocator\", [...info, \"toHaveRole\", expected, true, options?.timeout], { pageId });\n },\n }\n };\n\n // Merge locator matchers with base matchers from test-environment\n if (baseMatchers) {\n return {\n ...baseMatchers,\n ...locatorMatchers,\n not: { ...baseMatchers.not, ...locatorMatchers.not }\n };\n }\n return locatorMatchers;\n }\n\n // Helper to create page matchers\n function createPageMatchers(page, baseMatchers) {\n const pageId = page.__pageId || \"page_0\";\n\n function serializeExpected(expected) {\n if (expected instanceof RegExp) {\n return { $regex: expected.source, $flags: expected.flags };\n }\n return expected;\n }\n\n const pageMatchers = {\n async toHaveURL(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveURL\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n async toHaveTitle(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveTitle\", serializeExpected(expected), false, options?.timeout], { pageId });\n },\n not: {\n async toHaveURL(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveURL\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n async toHaveTitle(expected, options) {\n return __pw_invoke(\"expectPage\", [\"toHaveTitle\", serializeExpected(expected), true, options?.timeout], { pageId });\n },\n }\n };\n\n if (baseMatchers) {\n return {\n ...baseMatchers,\n ...pageMatchers,\n not: { ...baseMatchers.not, ...pageMatchers.not }\n };\n }\n return pageMatchers;\n }\n\n // Only extend expect if test-environment already defined it\n if (typeof globalThis.expect === 'function') {\n const originalExpect = globalThis.expect;\n globalThis.expect = function(actual) {\n const baseMatchers = originalExpect(actual);\n // If actual is a Locator, add locator-specific matchers\n if (actual && actual.constructor && actual.constructor.name === 'Locator') {\n return createLocatorMatchers(actual, baseMatchers);\n }\n // If actual is the page object (IsolatePage), add page-specific matchers\n if (actual && actual.__isPage === true) {\n return createPageMatchers(actual, baseMatchers);\n }\n return baseMatchers;\n };\n }\n // If test-environment not loaded, expect remains undefined\n})();\n`);\n\n // ========================================================================\n // Return Handle\n // ========================================================================\n\n return {\n dispose() {\n // Only remove listeners if page was provided directly\n if (page && requestHandler && responseHandler && consoleHandler) {\n page.off(\"request\", requestHandler);\n page.off(\"response\", responseHandler);\n page.off(\"console\", consoleHandler);\n }\n browserConsoleLogs.length = 0;\n networkRequests.length = 0;\n networkResponses.length = 0;\n },\n getBrowserConsoleLogs() {\n return [...browserConsoleLogs];\n },\n getNetworkRequests() {\n return [...networkRequests];\n },\n getNetworkResponses() {\n return [...networkResponses];\n },\n clearCollected() {\n browserConsoleLogs.length = 0;\n networkRequests.length = 0;\n networkResponses.length = 0;\n },\n };\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CA8LlB;AAAA,EAGC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAgOlB;AAAA,EAGC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAmOlB;AAAA,EAMC,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI,QAAQ,kBAAkB,mBAAmB,gBAAgB;AAAA,QAC/D,KAAK,IAAI,WAAW,cAAc;AAAA,QAClC,KAAK,IAAI,YAAY,eAAe;AAAA,QACpC,KAAK,IAAI,WAAW,cAAc;AAAA,MACpC;AAAA,MACA,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS;AAAA;AAAA,IAE5B,qBAAqB,GAAG;AAAA,MACtB,OAAO,CAAC,GAAG,kBAAkB;AAAA;AAAA,IAE/B,kBAAkB,GAAG;AAAA,MACnB,OAAO,CAAC,GAAG,eAAe;AAAA;AAAA,IAE5B,mBAAmB,GAAG;AAAA,MACpB,OAAO,CAAC,GAAG,gBAAgB;AAAA;AAAA,IAE7B,cAAc,GAAG;AAAA,MACf,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS;AAAA;AAAA,EAE9B;AAAA;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAgTlB;AAAA,EAGC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAwSlB;AAAA,EAGC,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAmOlB;AAAA,EAMC,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI,QAAQ,kBAAkB,mBAAmB,gBAAgB;AAAA,QAC/D,KAAK,IAAI,WAAW,cAAc;AAAA,QAClC,KAAK,IAAI,YAAY,eAAe;AAAA,QACpC,KAAK,IAAI,WAAW,cAAc;AAAA,MACpC;AAAA,MACA,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS;AAAA;AAAA,IAE5B,qBAAqB,GAAG;AAAA,MACtB,OAAO,CAAC,GAAG,kBAAkB;AAAA;AAAA,IAE/B,kBAAkB,GAAG;AAAA,MACnB,OAAO,CAAC,GAAG,eAAe;AAAA;AAAA,IAE5B,mBAAmB,GAAG;AAAA,MACpB,OAAO,CAAC,GAAG,gBAAgB;AAAA;AAAA,IAE7B,cAAc,GAAG;AAAA,MACf,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,SAAS;AAAA,MACzB,iBAAiB,SAAS;AAAA;AAAA,EAE9B;AAAA;",
|
|
8
|
+
"debugId": "2C9A0105748F8D9364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
package/dist/cjs/types.cjs.map
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/types.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * Client-safe types for @ricsam/isolate-playwright\n * This module can be imported without loading isolated-vm\n */\n\n// Re-export protocol types\nexport type {\n PlaywrightOperation,\n PlaywrightResult,\n PlaywrightEvent,\n PlaywrightFileData,\n} from \"@ricsam/isolate-protocol\";\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\nexport interface NetworkRequestInfo {\n url: string;\n method: string;\n headers: Record<string, string>;\n postData?: string;\n resourceType: string;\n timestamp: number;\n}\n\nexport interface NetworkResponseInfo {\n url: string;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n timestamp: number;\n}\n\n/**\n * Browser console log entry - logs from the page context (not sandbox).\n */\nexport interface BrowserConsoleLogEntry {\n level: string;\n
|
|
5
|
+
"/**\n * Client-safe types for @ricsam/isolate-playwright\n * This module can be imported without loading isolated-vm\n */\n\n// Re-export protocol types\nexport type {\n PlaywrightOperation,\n PlaywrightResult,\n PlaywrightEvent,\n PlaywrightFileData,\n} from \"@ricsam/isolate-protocol\";\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\nexport interface NetworkRequestInfo {\n url: string;\n method: string;\n headers: Record<string, string>;\n postData?: string;\n resourceType: string;\n timestamp: number;\n}\n\nexport interface NetworkResponseInfo {\n url: string;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n timestamp: number;\n}\n\n/**\n * Browser console log entry - logs from the page context (not sandbox).\n */\nexport interface BrowserConsoleLogEntry {\n level: string;\n stdout: string;\n timestamp: number;\n}\n\n/**\n * Callback type for handling playwright operations.\n * Used for remote execution where the page lives on the client.\n */\nexport type PlaywrightCallback = (\n op: import(\"@ricsam/isolate-protocol\").PlaywrightOperation\n) => Promise<import(\"@ricsam/isolate-protocol\").PlaywrightResult>;\n\n/**\n * Symbol key used to attach metadata to handlers created by\n * defaultPlaywrightHandler(). Enables adapter layers to keep local ergonomics\n * (event capture, collected data) without exposing page-mode in runtime options.\n */\nexport const DEFAULT_PLAYWRIGHT_HANDLER_META = Symbol.for(\n \"@ricsam/isolate-playwright/default-handler-meta\"\n);\n\n/**\n * Options for defaultPlaywrightHandler(page, options).\n */\nexport interface DefaultPlaywrightHandlerOptions {\n /** Default timeout for operations */\n timeout?: number;\n /** Callback to read files for setInputFiles() with file paths */\n readFile?: (filePath: string) => Promise<import(\"@ricsam/isolate-protocol\").PlaywrightFileData> | import(\"@ricsam/isolate-protocol\").PlaywrightFileData;\n /** Callback to write files for screenshot()/pdf() with path option */\n writeFile?: (filePath: string, data: Buffer) => Promise<void> | void;\n /** Callback to create new pages when context.newPage() is called */\n createPage?: (context: import(\"playwright\").BrowserContext) => Promise<import(\"playwright\").Page> | import(\"playwright\").Page;\n /** Callback to create new contexts when browser.newContext() is called */\n createContext?: (options?: import(\"playwright\").BrowserContextOptions) => Promise<import(\"playwright\").BrowserContext> | import(\"playwright\").BrowserContext;\n /** Callback to evaluate a predicate function inside the isolate (used by waitForURL/Request/Response with function predicates) */\n evaluatePredicate?: (predicateId: number, data: unknown) => boolean;\n}\n\n/**\n * Metadata attached to handlers created by defaultPlaywrightHandler().\n */\nexport interface DefaultPlaywrightHandlerMetadata {\n page: import(\"playwright\").Page;\n options?: DefaultPlaywrightHandlerOptions;\n}\n\n/**\n * Handler created by defaultPlaywrightHandler().\n */\nexport type DefaultPlaywrightHandler = PlaywrightCallback & {\n [DEFAULT_PLAYWRIGHT_HANDLER_META]?: DefaultPlaywrightHandlerMetadata;\n};\n\n/**\n * Options for setting up playwright in an isolate.\n */\nexport interface PlaywrightSetupOptions {\n /** Direct page object (for local use) */\n page?: import(\"playwright\").Page;\n /** Handler callback (for remote use - daemon invokes this) */\n handler?: PlaywrightCallback;\n /** Default timeout for operations */\n timeout?: number;\n /** If true, browser console logs are printed to stdout */\n console?: boolean;\n /** Unified event callback for all playwright events */\n onEvent?: (event: import(\"@ricsam/isolate-protocol\").PlaywrightEvent) => void;\n /**\n * Callback to read files for setInputFiles() operations.\n * This allows the host to control which files the isolate can access.\n * If not provided, setInputFiles() with file paths will throw an error.\n */\n readFile?: (filePath: string) => Promise<import(\"@ricsam/isolate-protocol\").PlaywrightFileData> | import(\"@ricsam/isolate-protocol\").PlaywrightFileData;\n /**\n * Callback to write files for screenshot() and pdf() operations with path option.\n * This allows the host to control where files are written.\n * If not provided, screenshot()/pdf() with path option will throw an error.\n */\n writeFile?: (filePath: string, data: Buffer) => Promise<void> | void;\n /**\n * Callback invoked when context.newPage() is called from within the isolate.\n * Host creates/configures the new page. If not provided, newPage() will throw an error.\n * Receives the BrowserContext so you can call context.newPage().\n * @param context - The BrowserContext that requested the new page\n * @returns The new Page object\n */\n createPage?: (context: import(\"playwright\").BrowserContext) => Promise<import(\"playwright\").Page> | import(\"playwright\").Page;\n /**\n * Callback invoked when browser.newContext() is called from within the isolate.\n * Host creates/configures the new context. If not provided, newContext() will throw an error.\n * @param options - Browser context options passed from the isolate\n * @returns The new BrowserContext object\n */\n createContext?: (options?: import(\"playwright\").BrowserContextOptions) => Promise<import(\"playwright\").BrowserContext> | import(\"playwright\").BrowserContext;\n}\n\nexport interface PlaywrightHandle {\n dispose(): void;\n /** Get browser console logs (from the page, not sandbox) */\n getBrowserConsoleLogs(): BrowserConsoleLogEntry[];\n getNetworkRequests(): NetworkRequestInfo[];\n getNetworkResponses(): NetworkResponseInfo[];\n clearCollected(): void;\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDO,IAAM,kCAAkC,OAAO,IACpD,iDACF;",
|
|
8
8
|
"debugId": "A4FBA4399322C38C64756E2164756E21",
|