@browserbasehq/orca 3.7.0-preview.1 → 3.7.2-gemini-cua

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.
Files changed (165) hide show
  1. package/dist/cjs/lib/modelUtils.d.ts +10 -0
  2. package/dist/cjs/lib/modelUtils.js +11 -0
  3. package/dist/cjs/lib/modelUtils.js.map +1 -1
  4. package/dist/cjs/lib/v3/agent/AgentProvider.js +3 -0
  5. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  6. package/dist/cjs/lib/v3/agent/GoogleCUAClient.d.ts +23 -0
  7. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +363 -206
  8. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/tools/click.js +16 -5
  10. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js +1 -1
  12. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js +2 -2
  14. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +18 -7
  16. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  17. package/dist/cjs/lib/v3/agent/tools/scroll.js +1 -1
  18. package/dist/cjs/lib/v3/agent/tools/scroll.js.map +1 -1
  19. package/dist/cjs/lib/v3/agent/tools/type.js +13 -4
  20. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.d.ts +5 -2
  22. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.js +5 -7
  23. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.js.map +1 -1
  24. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +3 -1
  25. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  26. package/dist/cjs/lib/v3/api.d.ts +1 -1
  27. package/dist/cjs/lib/v3/api.js +11 -1
  28. package/dist/cjs/lib/v3/api.js.map +1 -1
  29. package/dist/cjs/lib/v3/cache/AgentCache.js +6 -1
  30. package/dist/cjs/lib/v3/cache/AgentCache.js.map +1 -1
  31. package/dist/cjs/lib/v3/external_clients/aisdk.js +2 -0
  32. package/dist/cjs/lib/v3/external_clients/aisdk.js.map +1 -1
  33. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +20 -0
  34. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  35. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +5 -4
  36. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  37. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +4 -0
  38. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +126 -20
  39. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  40. package/dist/cjs/lib/v3/index.d.ts +1 -1
  41. package/dist/cjs/lib/v3/launch/local.js +1 -1
  42. package/dist/cjs/lib/v3/launch/local.js.map +1 -1
  43. package/dist/cjs/lib/v3/llm/LLMProvider.js +9 -2
  44. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  45. package/dist/cjs/lib/v3/llm/aisdk.js +5 -3
  46. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  47. package/dist/cjs/lib/v3/llm/providerOptions.d.ts +7 -0
  48. package/dist/cjs/lib/v3/llm/providerOptions.js +9 -0
  49. package/dist/cjs/lib/v3/llm/providerOptions.js.map +1 -0
  50. package/dist/cjs/lib/v3/runtimePaths.js +0 -1
  51. package/dist/cjs/lib/v3/runtimePaths.js.map +1 -1
  52. package/dist/cjs/lib/v3/types/private/agent.d.ts +1 -1
  53. package/dist/cjs/lib/v3/types/private/agent.js +1 -0
  54. package/dist/cjs/lib/v3/types/private/agent.js.map +1 -1
  55. package/dist/cjs/lib/v3/types/public/agent.d.ts +1 -1
  56. package/dist/cjs/lib/v3/types/public/agent.js +3 -0
  57. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  58. package/dist/cjs/lib/v3/types/public/api.d.ts +53 -0
  59. package/dist/cjs/lib/v3/types/public/api.js +8 -0
  60. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  61. package/dist/cjs/lib/v3/types/public/model.d.ts +12 -0
  62. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  63. package/dist/cjs/lib/v3/types/public/options.d.ts +13 -0
  64. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  65. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js +4 -3
  66. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
  67. package/dist/cjs/lib/v3/understudy/a11y/snapshot/coordinateResolver.js +39 -1
  68. package/dist/cjs/lib/v3/understudy/a11y/snapshot/coordinateResolver.js.map +1 -1
  69. package/dist/cjs/lib/v3/understudy/locator.d.ts +12 -0
  70. package/dist/cjs/lib/v3/understudy/locator.js +44 -0
  71. package/dist/cjs/lib/v3/understudy/locator.js.map +1 -1
  72. package/dist/cjs/lib/v3/understudy/page.d.ts +22 -3
  73. package/dist/cjs/lib/v3/understudy/page.js +55 -1
  74. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  75. package/dist/cjs/lib/v3/v3.d.ts +14 -0
  76. package/dist/cjs/lib/v3/v3.js +81 -16
  77. package/dist/cjs/lib/v3/v3.js.map +1 -1
  78. package/dist/cjs/lib/v3/verifier/types.d.ts +3 -2
  79. package/dist/cjs/lib/v3/verifier/types.js.map +1 -1
  80. package/dist/cjs/lib/version.d.ts +1 -1
  81. package/dist/cjs/lib/version.js +1 -1
  82. package/dist/cjs/lib/version.js.map +1 -1
  83. package/dist/esm/lib/modelUtils.d.ts +10 -0
  84. package/dist/esm/lib/modelUtils.js +9 -0
  85. package/dist/esm/lib/modelUtils.js.map +1 -1
  86. package/dist/esm/lib/v3/agent/AgentProvider.js +3 -0
  87. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  88. package/dist/esm/lib/v3/agent/GoogleCUAClient.d.ts +23 -0
  89. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +363 -206
  90. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  91. package/dist/esm/lib/v3/agent/tools/click.js +16 -5
  92. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  93. package/dist/esm/lib/v3/agent/tools/clickAndHold.js +1 -1
  94. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  95. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js +2 -2
  96. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  97. package/dist/esm/lib/v3/agent/tools/fillFormVision.js +19 -8
  98. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  99. package/dist/esm/lib/v3/agent/tools/scroll.js +1 -1
  100. package/dist/esm/lib/v3/agent/tools/scroll.js.map +1 -1
  101. package/dist/esm/lib/v3/agent/tools/type.js +13 -4
  102. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  103. package/dist/esm/lib/v3/agent/utils/coordinateNormalization.d.ts +5 -2
  104. package/dist/esm/lib/v3/agent/utils/coordinateNormalization.js +5 -7
  105. package/dist/esm/lib/v3/agent/utils/coordinateNormalization.js.map +1 -1
  106. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +3 -1
  107. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  108. package/dist/esm/lib/v3/api.d.ts +1 -1
  109. package/dist/esm/lib/v3/api.js +11 -1
  110. package/dist/esm/lib/v3/api.js.map +1 -1
  111. package/dist/esm/lib/v3/cache/AgentCache.js +6 -1
  112. package/dist/esm/lib/v3/cache/AgentCache.js.map +1 -1
  113. package/dist/esm/lib/v3/external_clients/aisdk.js +2 -0
  114. package/dist/esm/lib/v3/external_clients/aisdk.js.map +1 -1
  115. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +20 -0
  116. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  117. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +5 -4
  118. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  119. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.d.ts +4 -0
  120. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +126 -20
  121. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  122. package/dist/esm/lib/v3/index.d.ts +1 -1
  123. package/dist/esm/lib/v3/launch/local.js +1 -1
  124. package/dist/esm/lib/v3/launch/local.js.map +1 -1
  125. package/dist/esm/lib/v3/llm/LLMProvider.js +9 -2
  126. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  127. package/dist/esm/lib/v3/llm/aisdk.js +5 -3
  128. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  129. package/dist/esm/lib/v3/llm/providerOptions.d.ts +7 -0
  130. package/dist/esm/lib/v3/llm/providerOptions.js +6 -0
  131. package/dist/esm/lib/v3/llm/providerOptions.js.map +1 -0
  132. package/dist/esm/lib/v3/runtimePaths.js +0 -1
  133. package/dist/esm/lib/v3/runtimePaths.js.map +1 -1
  134. package/dist/esm/lib/v3/types/private/agent.d.ts +1 -1
  135. package/dist/esm/lib/v3/types/private/agent.js +1 -0
  136. package/dist/esm/lib/v3/types/private/agent.js.map +1 -1
  137. package/dist/esm/lib/v3/types/public/agent.d.ts +1 -1
  138. package/dist/esm/lib/v3/types/public/agent.js +3 -0
  139. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  140. package/dist/esm/lib/v3/types/public/api.d.ts +53 -0
  141. package/dist/esm/lib/v3/types/public/api.js +8 -0
  142. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  143. package/dist/esm/lib/v3/types/public/model.d.ts +12 -0
  144. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  145. package/dist/esm/lib/v3/types/public/options.d.ts +13 -0
  146. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  147. package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js +4 -3
  148. package/dist/esm/lib/v3/understudy/a11y/snapshot/capture.js.map +1 -1
  149. package/dist/esm/lib/v3/understudy/a11y/snapshot/coordinateResolver.js +39 -1
  150. package/dist/esm/lib/v3/understudy/a11y/snapshot/coordinateResolver.js.map +1 -1
  151. package/dist/esm/lib/v3/understudy/locator.d.ts +12 -0
  152. package/dist/esm/lib/v3/understudy/locator.js +44 -0
  153. package/dist/esm/lib/v3/understudy/locator.js.map +1 -1
  154. package/dist/esm/lib/v3/understudy/page.d.ts +22 -3
  155. package/dist/esm/lib/v3/understudy/page.js +55 -1
  156. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  157. package/dist/esm/lib/v3/v3.d.ts +14 -0
  158. package/dist/esm/lib/v3/v3.js +82 -17
  159. package/dist/esm/lib/v3/v3.js.map +1 -1
  160. package/dist/esm/lib/v3/verifier/types.d.ts +3 -2
  161. package/dist/esm/lib/v3/verifier/types.js.map +1 -1
  162. package/dist/esm/lib/version.d.ts +1 -1
  163. package/dist/esm/lib/version.js +1 -1
  164. package/dist/esm/lib/version.js.map +1 -1
  165. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/public/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { ClientOptions as AnthropicClientOptionsBase } from \"@anthropic-ai/sdk\";\nimport type {\n LanguageModelV2,\n LanguageModelV2Middleware,\n} from \"@ai-sdk/provider\";\nimport type { ClientOptions as OpenAIClientOptionsBase } from \"openai\";\nimport type { AgentProviderType } from \"./agent.js\";\n\nexport type OpenAIClientOptions = Pick<\n OpenAIClientOptionsBase,\n \"baseURL\" | \"apiKey\"\n>;\n\nexport type AnthropicClientOptions = Pick<\n AnthropicClientOptionsBase,\n \"baseURL\" | \"apiKey\"\n>;\n\nexport interface GoogleServiceAccountCredentials {\n type?: \"service_account\";\n project_id?: string;\n private_key_id?: string;\n private_key: string;\n client_email: string;\n client_id?: string;\n auth_uri?: string;\n token_uri?: string;\n auth_provider_x509_cert_url?: string;\n client_x509_cert_url?: string;\n universe_domain?: string;\n}\n\nexport interface GoogleServiceAccountAuth {\n type: \"googleServiceAccount\";\n credentials: GoogleServiceAccountCredentials;\n scopes?: string | string[];\n projectId?: string;\n universeDomain?: string;\n}\n\nexport interface AzureEntraIdAuth {\n type: \"azureEntraId\";\n token: string;\n}\n\nexport type ModelAuth = GoogleServiceAccountAuth | AzureEntraIdAuth;\n\nexport interface VertexProviderOptions {\n project: string;\n location: string;\n baseURL?: string;\n headers?: Record<string, string>;\n}\n\nexport interface AzureProviderOptions {\n resourceName?: string;\n baseURL?: string;\n apiVersion?: string;\n useDeploymentBasedUrls?: boolean;\n headers?: Record<string, string>;\n}\n\nexport type ModelProviderOptions =\n | { vertex: VertexProviderOptions; azure?: never }\n | { azure: AzureProviderOptions; vertex?: never };\n\nexport type AnthropicJsonSchemaObject = {\n definitions?: {\n MySchema?: {\n properties?: Record<string, unknown>;\n required?: string[];\n };\n };\n properties?: Record<string, unknown>;\n required?: string[];\n} & Record<string, unknown>;\n\nexport interface LLMTool {\n type: \"function\";\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}\n\nexport type AISDKProvider = (modelName: string) => LanguageModelV2;\n// Represents a function that takes options (like apiKey) and returns an AISDKProvider\nexport type AISDKCustomProvider = (options: ClientOptions) => AISDKProvider;\n\nexport type AvailableModel =\n | \"gpt-4.1\"\n | \"gpt-4.1-mini\"\n | \"gpt-4.1-nano\"\n | \"o4-mini\"\n | \"o3\"\n | \"o3-mini\"\n | \"o1\"\n | \"o1-mini\"\n | \"gpt-4o\"\n | \"gpt-4o-mini\"\n | \"gpt-4o-2024-08-06\"\n | \"gpt-4.5-preview\"\n | \"o1-preview\"\n | \"cerebras-llama-3.3-70b\"\n | \"cerebras-llama-3.1-8b\"\n | \"groq-llama-3.3-70b-versatile\"\n | \"groq-llama-3.3-70b-specdec\"\n | \"gemini-1.5-flash\"\n | \"gemini-1.5-pro\"\n | \"gemini-1.5-flash-8b\"\n | \"gemini-2.0-flash-lite\"\n | \"gemini-2.0-flash\"\n | \"gemini-2.5-flash-preview-04-17\"\n | \"gemini-2.5-pro-preview-03-25\"\n | string;\n\nexport type ModelProvider =\n | \"openai\"\n | \"anthropic\"\n | \"cerebras\"\n | \"groq\"\n | \"google\"\n | \"aisdk\";\n\n/**\n * Effort levels for Claude adaptive thinking.\n * Used with Claude 4.6+ models (claude-opus-4-6, claude-sonnet-4-6).\n * - \"none\": Disable adaptive thinking entirely\n * - \"low\": Claude minimizes thinking, skips for simple tasks\n * - \"medium\": Claude uses moderate thinking, may skip for simple queries (default)\n * - \"high\": Claude always thinks with deep reasoning\n * - \"xhigh\": Deeper reasoning than \"high\" (Opus 4.7/4.8 and Fable 5 only)\n * - \"max\": Claude always thinks with no constraints\n */\nexport type ThinkingEffort =\n | \"none\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"xhigh\"\n | \"max\";\n\nexport type ClientOptions = (OpenAIClientOptions | AnthropicClientOptions) & {\n apiKey?: string;\n provider?: AgentProviderType;\n auth?: ModelAuth;\n providerOptions?: ModelProviderOptions;\n baseURL?: string;\n /** OpenAI organization ID */\n organization?: string;\n /** Delay between agent actions in ms */\n waitBetweenActions?: number;\n /**\n * @deprecated For Claude 4.6+ models, use `thinkingEffort` instead.\n * Anthropic thinking budget for extended thinking (used with older Claude models like 4.5).\n * Sets `thinking.type: \"enabled\"` with the specified `budget_tokens`.\n */\n thinkingBudget?: number;\n /**\n * Effort level for Claude adaptive thinking (Claude 4.6+ models only).\n * Uses `thinking.type: \"adaptive\"` with `output_config.effort`.\n * This is the recommended approach for Claude Opus 4.6 and Sonnet 4.6.\n * @see https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking\n */\n thinkingEffort?: ThinkingEffort;\n /** Environment type for CUA agents (browser, mac, windows, ubuntu) */\n environment?: string;\n /** Max images for Microsoft FARA agent */\n maxImages?: number;\n /** Temperature for model inference */\n temperature?: number;\n /** Custom headers sent with every request to the provider */\n headers?: Record<string, string>;\n /** Reasoning effort for reasoning-capable models (e.g., \"none\", \"low\", \"medium\", \"high\") */\n reasoningEffort?: string;\n};\n\nexport type ModelConfiguration =\n | AvailableModel\n | (ClientOptions & {\n modelName: AvailableModel;\n /**\n * Optional AI SDK middleware applied to every LanguageModelV2 created for this model.\n * Use this to intercept LLM calls for usage tracking, logging, request transforms, etc.\n *\n * Only effective when running locally (direct mode). Cannot be serialized over HTTP,\n */\n middleware?: LanguageModelV2Middleware;\n });\n"]}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/public/model.ts"],"names":[],"mappings":"","sourcesContent":["import type { ClientOptions as AnthropicClientOptionsBase } from \"@anthropic-ai/sdk\";\nimport type {\n LanguageModelV2,\n LanguageModelV2Middleware,\n} from \"@ai-sdk/provider\";\nimport type { ClientOptions as OpenAIClientOptionsBase } from \"openai\";\nimport type { AgentProviderType } from \"./agent.js\";\n\nexport type OpenAIClientOptions = Pick<\n OpenAIClientOptionsBase,\n \"baseURL\" | \"apiKey\"\n>;\n\nexport type AnthropicClientOptions = Pick<\n AnthropicClientOptionsBase,\n \"baseURL\" | \"apiKey\"\n>;\n\nexport interface GoogleServiceAccountCredentials {\n type?: \"service_account\";\n project_id?: string;\n private_key_id?: string;\n private_key: string;\n client_email: string;\n client_id?: string;\n auth_uri?: string;\n token_uri?: string;\n auth_provider_x509_cert_url?: string;\n client_x509_cert_url?: string;\n universe_domain?: string;\n}\n\nexport interface GoogleServiceAccountAuth {\n type: \"googleServiceAccount\";\n credentials: GoogleServiceAccountCredentials;\n scopes?: string | string[];\n projectId?: string;\n universeDomain?: string;\n}\n\nexport interface AzureEntraIdAuth {\n type: \"azureEntraId\";\n token: string;\n}\n\nexport type ModelAuth = GoogleServiceAccountAuth | AzureEntraIdAuth;\n\nexport interface VertexProviderOptions {\n project: string;\n location: string;\n baseURL?: string;\n headers?: Record<string, string>;\n}\n\nexport interface AzureProviderOptions {\n resourceName?: string;\n baseURL?: string;\n apiVersion?: string;\n useDeploymentBasedUrls?: boolean;\n headers?: Record<string, string>;\n}\n\nexport type ModelProviderOptions =\n | { vertex: VertexProviderOptions; azure?: never }\n | { azure: AzureProviderOptions; vertex?: never };\n\nexport type AnthropicJsonSchemaObject = {\n definitions?: {\n MySchema?: {\n properties?: Record<string, unknown>;\n required?: string[];\n };\n };\n properties?: Record<string, unknown>;\n required?: string[];\n} & Record<string, unknown>;\n\nexport interface LLMTool {\n type: \"function\";\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}\n\nexport type AISDKProvider = (modelName: string) => LanguageModelV2;\n// Represents a function that takes options (like apiKey) and returns an AISDKProvider\nexport type AISDKCustomProvider = (options: ClientOptions) => AISDKProvider;\n\nexport type AvailableModel =\n | \"gpt-4.1\"\n | \"gpt-4.1-mini\"\n | \"gpt-4.1-nano\"\n | \"o4-mini\"\n | \"o3\"\n | \"o3-mini\"\n | \"o1\"\n | \"o1-mini\"\n | \"gpt-4o\"\n | \"gpt-4o-mini\"\n | \"gpt-4o-2024-08-06\"\n | \"gpt-4.5-preview\"\n | \"o1-preview\"\n | \"cerebras-llama-3.3-70b\"\n | \"cerebras-llama-3.1-8b\"\n | \"groq-llama-3.3-70b-versatile\"\n | \"groq-llama-3.3-70b-specdec\"\n | \"gemini-1.5-flash\"\n | \"gemini-1.5-pro\"\n | \"gemini-1.5-flash-8b\"\n | \"gemini-2.0-flash-lite\"\n | \"gemini-2.0-flash\"\n | \"gemini-2.5-flash-preview-04-17\"\n | \"gemini-2.5-pro-preview-03-25\"\n | string;\n\nexport type ModelProvider =\n | \"openai\"\n | \"anthropic\"\n | \"cerebras\"\n | \"groq\"\n | \"google\"\n | \"aisdk\";\n\n/**\n * Effort levels for Claude adaptive thinking.\n * Used with Claude 4.6+ models (claude-opus-4-6, claude-sonnet-4-6).\n * - \"none\": Disable adaptive thinking entirely\n * - \"low\": Claude minimizes thinking, skips for simple tasks\n * - \"medium\": Claude uses moderate thinking, may skip for simple queries (default)\n * - \"high\": Claude always thinks with deep reasoning\n * - \"xhigh\": Deeper reasoning than \"high\" (Opus 4.7/4.8 and Fable 5 only)\n * - \"max\": Claude always thinks with no constraints\n */\nexport type ThinkingEffort =\n | \"none\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"xhigh\"\n | \"max\";\n\nexport type OpenAIEndpointFormat = \"responses\" | \"chat\";\n\nexport type ClientOptions = (OpenAIClientOptions | AnthropicClientOptions) & {\n apiKey?: string;\n provider?: AgentProviderType;\n auth?: ModelAuth;\n providerOptions?: ModelProviderOptions;\n baseURL?: string;\n /** OpenAI organization ID */\n organization?: string;\n /** Delay between agent actions in ms */\n waitBetweenActions?: number;\n /**\n * @deprecated For Claude 4.6+ models, use `thinkingEffort` instead.\n * Anthropic thinking budget for extended thinking (used with older Claude models like 4.5).\n * Sets `thinking.type: \"enabled\"` with the specified `budget_tokens`.\n */\n thinkingBudget?: number;\n /**\n * Effort level for Claude adaptive thinking (Claude 4.6+ models only).\n * Uses `thinking.type: \"adaptive\"` with `output_config.effort`.\n * This is the recommended approach for Claude Opus 4.6 and Sonnet 4.6.\n * @see https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking\n */\n thinkingEffort?: ThinkingEffort;\n /** Environment type for CUA agents (browser, mac, windows, ubuntu) */\n environment?: string;\n /**\n * Request API for the Google CUA agent: \"generateContent\" (default) or the\n * stateful \"interactions\" API.\n */\n googleApi?: \"generateContent\" | \"interactions\";\n /** Max images for Microsoft FARA agent */\n maxImages?: number;\n /** Temperature for model inference */\n temperature?: number;\n /** Custom headers sent with every request to the provider */\n headers?: Record<string, string>;\n /** Reasoning effort for reasoning-capable models (e.g., \"none\", \"low\", \"medium\", \"high\") */\n reasoningEffort?: string;\n /**\n * Wire format used against the OpenAI-compatible endpoint at `baseURL`.\n * Defaults to the Responses API. Use `chat` for providers that expose only\n * an OpenAI-compatible Chat Completions endpoint (e.g. Databricks).\n */\n openaiEndpointFormat?: OpenAIEndpointFormat;\n};\n\nexport type ModelConfiguration =\n | AvailableModel\n | (ClientOptions & {\n modelName: AvailableModel;\n /**\n * Optional AI SDK middleware applied to every LanguageModelV2 created for this model.\n * Use this to intercept LLM calls for usage tracking, logging, request transforms, etc.\n *\n * Only effective when running locally (direct mode). Cannot be serialized over HTTP,\n */\n middleware?: LanguageModelV2Middleware;\n });\n"]}
@@ -58,6 +58,19 @@ export interface V3Options {
58
58
  */
59
59
  keepAlive?: boolean;
60
60
  localBrowserLaunchOptions?: LocalBrowserLaunchOptions;
61
+ /**
62
+ * Actuate coordinate pointer actions as touch (a real `Input.dispatchTouchEvent`
63
+ * tap) instead of mouse input. Mobile layouts commonly gate their handlers on
64
+ * touch/pointer events, where a synthesized mouse click never registers — e.g. a
65
+ * size selector that keeps reporting "please choose a size". Set this when the
66
+ * session renders a mobile layout (e.g. Browserbase `browserSettings.os:
67
+ * "mobile"`).
68
+ *
69
+ * Explicit opt-in only — nothing is derived from the session.
70
+ *
71
+ * @default false
72
+ */
73
+ useTouch?: boolean;
61
74
  model?: ModelConfiguration;
62
75
  llmClient?: LLMClient;
63
76
  systemPrompt?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/public/options.ts"],"names":[],"mappings":";;;AAIA,qCAGkB;AAIlB,0DAA0D;AAC7C,QAAA,+BAA+B,GAAG,wCAA+B,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { LLMClient } from \"../../llm/LLMClient.js\";\nimport { ModelConfiguration } from \"./model.js\";\nimport { LogLine } from \"./logs.js\";\nimport {\n type BrowserbaseSessionCreateParams,\n LocalBrowserLaunchOptionsSchema,\n} from \"./api.js\";\n\nexport type V3Env = \"LOCAL\" | \"BROWSERBASE\";\n\n// Re-export for backwards compatibility (camelCase alias)\nexport const localBrowserLaunchOptionsSchema = LocalBrowserLaunchOptionsSchema;\n\nexport type LocalBrowserLaunchOptions = z.infer<\n typeof LocalBrowserLaunchOptionsSchema\n>;\n\n/** Constructor options for V3 */\nexport interface V3Options {\n env: V3Env;\n /**\n * Optional external session identifier to use for flow logging/event storage.\n * When omitted, Stagehand falls back to its internal instance id.\n * This currently ends up 1:1 with the Browserbase session id when one exists,\n * but callers should not rely on that remaining a permanent invariant.\n */\n sessionId?: string;\n // Browserbase (required when env = \"BROWSERBASE\")\n apiKey?: string;\n projectId?: string;\n /**\n * Optional: fine-tune Browserbase session creation or resume an existing session.\n */\n browserbaseSessionCreateParams?: BrowserbaseSessionCreateParams;\n browserbaseSessionID?: string;\n /**\n * Controls browser keepalive behavior. When set, it overrides any value in\n * browserbaseSessionCreateParams.keepAlive.\n */\n keepAlive?: boolean;\n\n // Local Chromium (optional)\n localBrowserLaunchOptions?: LocalBrowserLaunchOptions;\n\n model?: ModelConfiguration;\n llmClient?: LLMClient; // allow user to pass their own\n systemPrompt?: string;\n logInferenceToFile?: boolean;\n experimental?: boolean;\n verbose?: 0 | 1 | 2;\n selfHeal?: boolean;\n // V2 compatibility fields - only included because the server imports this type and supports V2\n waitForCaptchaSolves?: boolean;\n actTimeoutMs?: number;\n /** Disable pino logging backend (useful for tests or minimal environments). */\n disablePino?: boolean;\n /** Optional external logger hook for integrating with host apps. */\n logger?: (line: LogLine) => void;\n /** Directory used to persist cached actions for act(). */\n cacheDir?: string;\n domSettleTimeout?: number;\n disableAPI?: boolean;\n /**\n * When true, enables server-side caching for API requests.\n * When false, disables server-side caching.\n * Defaults to true (caching enabled).\n * Can be overridden per-method in act(), extract(), and observe() options.\n */\n serverCache?: boolean;\n}\n"]}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/public/options.ts"],"names":[],"mappings":";;;AAIA,qCAGkB;AAIlB,0DAA0D;AAC7C,QAAA,+BAA+B,GAAG,wCAA+B,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { LLMClient } from \"../../llm/LLMClient.js\";\nimport { ModelConfiguration } from \"./model.js\";\nimport { LogLine } from \"./logs.js\";\nimport {\n type BrowserbaseSessionCreateParams,\n LocalBrowserLaunchOptionsSchema,\n} from \"./api.js\";\n\nexport type V3Env = \"LOCAL\" | \"BROWSERBASE\";\n\n// Re-export for backwards compatibility (camelCase alias)\nexport const localBrowserLaunchOptionsSchema = LocalBrowserLaunchOptionsSchema;\n\nexport type LocalBrowserLaunchOptions = z.infer<\n typeof LocalBrowserLaunchOptionsSchema\n>;\n\n/** Constructor options for V3 */\nexport interface V3Options {\n env: V3Env;\n /**\n * Optional external session identifier to use for flow logging/event storage.\n * When omitted, Stagehand falls back to its internal instance id.\n * This currently ends up 1:1 with the Browserbase session id when one exists,\n * but callers should not rely on that remaining a permanent invariant.\n */\n sessionId?: string;\n // Browserbase (required when env = \"BROWSERBASE\")\n apiKey?: string;\n projectId?: string;\n /**\n * Optional: fine-tune Browserbase session creation or resume an existing session.\n */\n browserbaseSessionCreateParams?: BrowserbaseSessionCreateParams;\n browserbaseSessionID?: string;\n /**\n * Controls browser keepalive behavior. When set, it overrides any value in\n * browserbaseSessionCreateParams.keepAlive.\n */\n keepAlive?: boolean;\n\n // Local Chromium (optional)\n localBrowserLaunchOptions?: LocalBrowserLaunchOptions;\n\n /**\n * Actuate coordinate pointer actions as touch (a real `Input.dispatchTouchEvent`\n * tap) instead of mouse input. Mobile layouts commonly gate their handlers on\n * touch/pointer events, where a synthesized mouse click never registers — e.g. a\n * size selector that keeps reporting \"please choose a size\". Set this when the\n * session renders a mobile layout (e.g. Browserbase `browserSettings.os:\n * \"mobile\"`).\n *\n * Explicit opt-in only — nothing is derived from the session.\n *\n * @default false\n */\n useTouch?: boolean;\n\n model?: ModelConfiguration;\n llmClient?: LLMClient; // allow user to pass their own\n systemPrompt?: string;\n logInferenceToFile?: boolean;\n experimental?: boolean;\n verbose?: 0 | 1 | 2;\n selfHeal?: boolean;\n // V2 compatibility fields - only included because the server imports this type and supports V2\n waitForCaptchaSolves?: boolean;\n actTimeoutMs?: number;\n /** Disable pino logging backend (useful for tests or minimal environments). */\n disablePino?: boolean;\n /** Optional external logger hook for integrating with host apps. */\n logger?: (line: LogLine) => void;\n /** Directory used to persist cached actions for act(). */\n cacheDir?: string;\n domSettleTimeout?: number;\n disableAPI?: boolean;\n /**\n * When true, enables server-side caching for API requests.\n * When false, disables server-side caching.\n * Defaults to true (caching enabled).\n * Can be overridden per-method in act(), extract(), and observe() options.\n */\n serverCache?: boolean;\n}\n"]}
@@ -161,14 +161,15 @@ async function tryScopedSnapshot(page, options, context, pierce, sessionToIndex,
161
161
  }
162
162
  }
163
163
  const scopedUrlMap = { ...urlMap };
164
+ const wellFormedOutline = outline.toWellFormed();
164
165
  const snapshot = {
165
- combinedTree: outline,
166
+ combinedTree: wellFormedOutline,
166
167
  combinedXpathMap: scopedXpathMap,
167
168
  combinedUrlMap: scopedUrlMap,
168
169
  perFrame: [
169
170
  {
170
171
  frameId: targetFrameId,
171
- outline,
172
+ outline: wellFormedOutline,
172
173
  xpathMap,
173
174
  urlMap,
174
175
  },
@@ -573,7 +574,7 @@ function mergeFramesIntoSnapshot(context, perFrameMaps, perFrameOutlines, absPre
573
574
  const rootOutline = perFrameOutlines.find((o) => o.frameId === context.rootId)?.outline ??
574
575
  perFrameOutlines[0]?.outline ??
575
576
  "";
576
- const combinedTree = (0, treeFormatUtils_js_1.injectSubtrees)(rootOutline, idToTree);
577
+ const combinedTree = (0, treeFormatUtils_js_1.injectSubtrees)(rootOutline, idToTree).toWellFormed();
577
578
  return {
578
579
  combinedTree,
579
580
  combinedXpathMap,
@@ -1 +1 @@
1
- {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/capture.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { Page } from \"../../page.js\";\nimport { Frame } from \"../../frame.js\";\nimport {\n FrameSelectorResolver,\n type ResolvedNode,\n type SelectorQuery,\n} from \"../../selectorResolver.js\";\nimport { v3Logger } from \"../../../logger.js\";\nimport type {\n FrameContext,\n FrameDomMaps,\n FrameParentIndex,\n HybridSnapshot,\n SnapshotOptions,\n SessionDomIndex,\n} from \"../../../types/private/index.js\";\nimport { a11yForFrame } from \"./a11yTree.js\";\nimport {\n resolveCssFocusFrameAndTail,\n resolveFocusFrameAndTail,\n listChildrenOf,\n} from \"./focusSelectors.js\";\nimport {\n buildSessionDomIndex,\n domMapsForSession,\n relativizeXPath,\n} from \"./domTree.js\";\nimport { injectSubtrees } from \"./treeFormatUtils.js\";\nimport { ownerSession, parentSession } from \"./sessions.js\";\nimport { normalizeXPath, prefixXPath } from \"./xpathUtils.js\";\n\ntype IgnoredNodeMap = Map<string, Set<number>>;\ntype Interval = { start: number; end: number };\ntype ExclusionIntervalsByFrame = Map<string, Interval[]>;\ntype ChildFrameHost = { childFrameId: string; hostBackendNodeId: number };\ntype ChildFramesByParent = Map<string, ChildFrameHost[]>;\n\n/**\n * Capture a hybrid DOM + Accessibility snapshot for the provided page.\n *\n * Flow overview:\n * 1. (Optional) Scope directly to a requested selector. We walk iframe hops to\n * find the owning frame, build just that frame’s DOM + AX tree, and bail out\n * early when the subtree satisfies the caller.\n * 2. Build DOM indexes for every unique CDP session. DOM.getDocument is called\n * once per session and hydrated so per-frame slices can share the result.\n * 3. Slice each frame’s DOM data from its session index and fetch its AX tree.\n * This yields relative XPath/tag/url maps for the document rooted at that frame.\n * 4. Walk the frame tree to compute absolute iframe prefixes. Every child frame\n * needs the XPath of the iframe element that hosts it so we can prefix maps.\n * 5. Merge all per-frame results into global combined maps and stitch the text\n * outline. The final payload mirrors the legacy shape but is built in layers.\n *\n * Each numbered block below references the step above for easier debugging.\n */\nexport async function captureHybridSnapshot(\n page: Page,\n options?: SnapshotOptions,\n): Promise<HybridSnapshot> {\n const pierce = options?.pierceShadow ?? true;\n const includeIframes = options?.includeIframes !== false;\n const hasIgnoreSelectors = (options?.ignoreSelectors?.length ?? 0) > 0;\n\n const context = buildFrameContext(page);\n const framesInScope = includeIframes ? [...context.frames] : [context.rootId];\n if (!framesInScope.includes(context.rootId)) {\n framesInScope.unshift(context.rootId);\n }\n\n if (!hasIgnoreSelectors) {\n const scopedSnapshot = await tryScopedSnapshot(\n page,\n options,\n context,\n pierce,\n new Map<string, SessionDomIndex>(),\n new Map(),\n );\n if (scopedSnapshot) return scopedSnapshot;\n }\n\n const sessionToIndex = await buildSessionIndexes(page, framesInScope, pierce);\n const ignoredNodesByFrame = await resolveIgnoredNodes(\n page,\n options?.ignoreSelectors,\n context,\n sessionToIndex,\n );\n const exclusionIntervalsByFrame = await buildFrameExclusionIntervals(\n page,\n context,\n sessionToIndex,\n ignoredNodesByFrame,\n );\n if (hasIgnoreSelectors) {\n const scopedSnapshot = await tryScopedSnapshot(\n page,\n options,\n context,\n pierce,\n sessionToIndex,\n exclusionIntervalsByFrame,\n );\n if (scopedSnapshot) return scopedSnapshot;\n }\n\n const { perFrameMaps, perFrameOutlines } = await collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n options,\n pierce,\n framesInScope,\n exclusionIntervalsByFrame,\n );\n const { absPrefix, iframeHostEncByChild } = await computeFramePrefixes(\n page,\n context,\n perFrameMaps,\n framesInScope,\n );\n\n return mergeFramesIntoSnapshot(\n context,\n perFrameMaps,\n perFrameOutlines,\n absPrefix,\n iframeHostEncByChild,\n framesInScope,\n );\n}\n\n/**\n * Snapshot the current frame tree so downstream helpers have consistent topology\n * without re-querying CDP. The map is intentionally shallow (frameId → parentId)\n * so it is serializable/testable without holding on to CDP handles.\n */\nexport function buildFrameContext(page: Page): FrameContext {\n const rootId = page.mainFrameId();\n const frameTree = page.asProtocolFrameTree(rootId);\n const parentByFrame: FrameParentIndex = new Map();\n (function index(n: Protocol.Page.FrameTree, parent: string | null) {\n parentByFrame.set(n.frame.id, parent);\n for (const c of n.childFrames ?? []) index(c, n.frame.id);\n })(frameTree, null);\n const frames = page.listAllFrameIds();\n return { rootId, parentByFrame, frames };\n}\n\n/**\n * Step 1 – scoped snapshot fast-path. If a selector is provided we try to:\n * 1) Resolve the selector (XPath or CSS) across iframes.\n * 2) Build DOM + AX data only for the owning frame.\n * 3) Bail out early when the selector's subtree satisfies the request.\n *\n * Returns `null` when scoping fails (e.g., selector miss) so the caller can\n * fall back to the full multi-frame snapshot.\n */\nexport async function tryScopedSnapshot(\n page: Page,\n options: SnapshotOptions | undefined,\n context: FrameContext,\n pierce: boolean,\n sessionToIndex: Map<string, SessionDomIndex>,\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): Promise<HybridSnapshot | null> {\n const requestedFocus = options?.focusSelector?.trim();\n if (!requestedFocus) return null;\n\n const logScopeFallback = () => {\n v3Logger({\n message: `Unable to narrow scope with selector. Falling back to using full DOM`,\n level: 1,\n auxiliary: {\n arguments: {\n value: `selector: ${options?.focusSelector?.trim()}`,\n type: \"string\",\n },\n },\n });\n };\n\n try {\n let targetFrameId: string;\n let tailSelector: string | undefined;\n let absPrefix: string | undefined;\n\n const looksLikeXPath =\n /^xpath=/i.test(requestedFocus) || requestedFocus.startsWith(\"/\");\n if (looksLikeXPath) {\n const focus = normalizeXPath(requestedFocus);\n const hit = await resolveFocusFrameAndTail(\n page,\n focus,\n context.parentByFrame,\n context.rootId,\n );\n targetFrameId = hit.targetFrameId;\n tailSelector = hit.tailXPath || undefined;\n absPrefix = hit.absPrefix;\n } else {\n const cssHit = await resolveCssFocusFrameAndTail(\n page,\n requestedFocus,\n context.parentByFrame,\n context.rootId,\n );\n targetFrameId = cssHit.targetFrameId;\n tailSelector = cssHit.tailSelector || undefined;\n absPrefix = cssHit.absPrefix;\n }\n\n const owningSess = ownerSession(page, targetFrameId);\n const parentId = context.parentByFrame.get(targetFrameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, targetFrameId);\n const { tagNameMap, xpathMap, scrollableMap } = await domMapsForSession(\n owningSess,\n targetFrameId,\n pierce,\n (fid, be) => `${page.getOrdinal(fid)}-${be}`,\n sameSessionAsParent,\n );\n\n const { outline, urlMap, scopeApplied } = await a11yForFrame(\n owningSess,\n targetFrameId,\n {\n focusSelector: tailSelector || undefined,\n isIgnoredBackendNode: makeIsIgnoredBackendNode(\n targetFrameId,\n ownerSessionIndexForFrame(page, targetFrameId, sessionToIndex),\n exclusionIntervalsByFrame,\n ),\n tagNameMap,\n experimental: options?.experimental ?? false,\n scrollableMap,\n encode: (backendNodeId) =>\n `${page.getOrdinal(targetFrameId)}-${backendNodeId}`,\n },\n );\n\n const scopedXpathMap: Record<string, string> = {};\n const isIgnoredBackendNode = makeIsIgnoredBackendNode(\n targetFrameId,\n ownerSessionIndexForFrame(page, targetFrameId, sessionToIndex),\n exclusionIntervalsByFrame,\n );\n const abs = absPrefix ?? \"\";\n const isRoot = !abs || abs === \"/\";\n if (isRoot) {\n for (const [encId, xp] of Object.entries(xpathMap)) {\n const backendNodeId = parseEncodedBackendNodeId(encId);\n if (\n typeof backendNodeId === \"number\" &&\n isIgnoredBackendNode?.(backendNodeId)\n ) {\n continue;\n }\n scopedXpathMap[encId] = xp;\n }\n } else {\n // Prefix relative XPaths so the scoped result matches the global encoding.\n for (const [encId, xp] of Object.entries(xpathMap)) {\n const backendNodeId = parseEncodedBackendNodeId(encId);\n if (\n typeof backendNodeId === \"number\" &&\n isIgnoredBackendNode?.(backendNodeId)\n ) {\n continue;\n }\n scopedXpathMap[encId] = prefixXPath(abs, xp);\n }\n }\n\n const scopedUrlMap: Record<string, string> = { ...urlMap };\n\n const snapshot: HybridSnapshot = {\n combinedTree: outline,\n combinedXpathMap: scopedXpathMap,\n combinedUrlMap: scopedUrlMap,\n perFrame: [\n {\n frameId: targetFrameId,\n outline,\n xpathMap,\n urlMap,\n },\n ],\n };\n\n if (scopeApplied) {\n return snapshot;\n }\n\n logScopeFallback();\n } catch {\n logScopeFallback();\n }\n return null;\n}\n\n/**\n * Step 2 – call DOM.getDocument once per unique CDP session and hydrate the\n * result so per-frame slices can share the structure. We key by session id\n * because same process iframes live inside the same session.\n */\nexport async function buildSessionIndexes(\n page: Page,\n frames: string[],\n pierce: boolean,\n): Promise<Map<string, SessionDomIndex>> {\n const sessionToIndex = new Map<string, SessionDomIndex>();\n const sessionById = new Map<string, CDPSessionLike>();\n for (const frameId of frames) {\n const sess = ownerSession(page, frameId);\n const sid = sess.id ?? \"root\";\n if (!sessionById.has(sid)) sessionById.set(sid, sess);\n }\n for (const [sid, sess] of sessionById.entries()) {\n const idx = await buildSessionDomIndex(sess, pierce);\n sessionToIndex.set(sid, idx);\n }\n return sessionToIndex;\n}\n\n/**\n * Step 3 – derive per-frame DOM maps and accessibility outlines.\n * Each frame:\n * - slices the shared session index down to its document root\n * - builds frame-aware encoded ids (ordinal-backendNodeId)\n * - collects tag/xpath/scrollability maps for DOM-based lookups\n * - fetches its AX tree to produce outlines and URL maps\n */\nexport async function collectPerFrameMaps(\n page: Page,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n options: SnapshotOptions | undefined,\n pierce: boolean,\n frameIds: string[],\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): Promise<{\n perFrameMaps: Map<string, FrameDomMaps>;\n perFrameOutlines: Array<{ frameId: string; outline: string }>;\n}> {\n const perFrameMaps = new Map<string, FrameDomMaps>();\n const perFrameOutlines: Array<{ frameId: string; outline: string }> = [];\n\n for (const frameId of frameIds) {\n const sess = ownerSession(page, frameId);\n const sid = sess.id ?? \"root\";\n let idx = sessionToIndex.get(sid);\n if (!idx) {\n idx = await buildSessionDomIndex(sess, pierce);\n sessionToIndex.set(sid, idx);\n }\n\n const parentId = context.parentByFrame.get(frameId);\n const sameSessionAsParent =\n !!parentId && ownerSession(page, parentId) === sess;\n\n const docRootBe = await resolveFrameDocRootBackendId(\n page,\n frameId,\n idx,\n sameSessionAsParent,\n );\n\n const tagNameMap: Record<string, string> = {};\n const xpathMap: Record<string, string> = {};\n const scrollableMap: Record<string, boolean> = {};\n const isIgnoredBackendNode = makeIsIgnoredBackendNode(\n frameId,\n idx,\n exclusionIntervalsByFrame,\n );\n const enc = (be: number) => `${page.getOrdinal(frameId)}-${be}`;\n const baseAbs = idx.absByBe.get(docRootBe) ?? \"/\";\n\n for (const [be, nodeAbs] of idx.absByBe.entries()) {\n const nodeDocRoot = idx.docRootOf.get(be);\n if (nodeDocRoot !== docRootBe) continue;\n if (isIgnoredBackendNode?.(be)) continue;\n\n // Translate absolute XPaths into document-relative ones for this frame.\n const rel = relativizeXPath(baseAbs, nodeAbs);\n const key = enc(be);\n xpathMap[key] = rel;\n const tag = idx.tagByBe.get(be);\n if (tag) tagNameMap[key] = tag;\n if (idx.scrollByBe.get(be)) scrollableMap[key] = true;\n }\n\n const { outline, urlMap } = await a11yForFrame(sess, frameId, {\n isIgnoredBackendNode,\n experimental: options?.experimental ?? false,\n tagNameMap,\n scrollableMap,\n encode: (backendNodeId) => `${page.getOrdinal(frameId)}-${backendNodeId}`,\n });\n\n perFrameOutlines.push({ frameId, outline });\n perFrameMaps.set(frameId, { tagNameMap, xpathMap, scrollableMap, urlMap });\n }\n\n return { perFrameMaps, perFrameOutlines };\n}\n\nexport async function resolveIgnoredNodes(\n page: Page,\n ignoreSelectors: string[] | undefined,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n): Promise<IgnoredNodeMap> {\n const ignoredNodesByFrame: IgnoredNodeMap = new Map();\n\n for (const rawSelector of ignoreSelectors ?? []) {\n const selector = rawSelector.trim();\n if (!selector) continue;\n\n try {\n const resolved = await resolveIgnoredNodesForSelector(\n page,\n selector,\n context,\n sessionToIndex,\n );\n for (const match of resolved) {\n const nodes =\n ignoredNodesByFrame.get(match.frameId) ?? new Set<number>();\n nodes.add(match.backendNodeId);\n ignoredNodesByFrame.set(match.frameId, nodes);\n }\n } catch {\n continue;\n }\n }\n\n return ignoredNodesByFrame;\n}\n\nasync function resolveIgnoredNodesForSelector(\n page: Page,\n selector: string,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n): Promise<Array<{ frameId: string; backendNodeId: number }>> {\n const looksLikeXPath = /^xpath=/i.test(selector) || selector.startsWith(\"/\");\n\n if (looksLikeXPath) {\n const hit = await resolveFocusFrameAndTail(\n page,\n normalizeXPath(selector),\n context.parentByFrame,\n context.rootId,\n );\n const targetFrameId = hit.targetFrameId;\n const tailXPath = hit.tailXPath || \"/\";\n if (tailXPath === \"/\") {\n const idx = ownerSessionIndexForFrame(\n page,\n targetFrameId,\n sessionToIndex,\n );\n if (!idx) return [];\n const parentId = context.parentByFrame.get(targetFrameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, targetFrameId);\n const backendNodeId = await resolveFrameDocRootBackendId(\n page,\n targetFrameId,\n idx,\n sameSessionAsParent,\n );\n return [{ frameId: targetFrameId, backendNodeId }];\n }\n return resolveIgnoredNodesInFrame(page, targetFrameId, {\n kind: \"xpath\",\n value: tailXPath,\n });\n }\n\n const hit = await resolveCssFocusFrameAndTail(\n page,\n selector,\n context.parentByFrame,\n context.rootId,\n );\n const targetFrameId = hit.targetFrameId;\n return resolveIgnoredNodesInFrame(page, targetFrameId, {\n kind: \"css\",\n value: hit.tailSelector || selector,\n });\n}\n\nasync function resolveIgnoredNodesInFrame(\n page: Page,\n frameId: string,\n query: SelectorQuery,\n): Promise<Array<{ frameId: string; backendNodeId: number }>> {\n const session = ownerSession(page, frameId);\n const frame = new Frame(session, frameId, \"\", false);\n const resolver = new FrameSelectorResolver(frame);\n const resolvedNodes = await resolver.resolveAll(query);\n if (!resolvedNodes.length) return [];\n\n const backendNodeIds = await describeResolvedNodes(session, resolvedNodes);\n return backendNodeIds.map((backendNodeId) => ({ frameId, backendNodeId }));\n}\n\nasync function describeResolvedNodes(\n session: CDPSessionLike,\n resolvedNodes: ResolvedNode[],\n): Promise<number[]> {\n const backendNodeIds = new Set<number>();\n\n try {\n for (const resolvedNode of resolvedNodes) {\n const desc = await session.send<Protocol.DOM.DescribeNodeResponse>(\n \"DOM.describeNode\",\n { objectId: resolvedNode.objectId },\n );\n const backendNodeId = desc.node.backendNodeId;\n if (typeof backendNodeId === \"number\") {\n backendNodeIds.add(backendNodeId);\n }\n }\n } finally {\n await Promise.all(\n resolvedNodes.map((resolvedNode) =>\n session\n .send(\"Runtime.releaseObject\", { objectId: resolvedNode.objectId })\n .catch(() => {}),\n ),\n );\n }\n\n return [...backendNodeIds];\n}\n\nexport async function buildFrameExclusionIntervals(\n page: Page,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n ignoredNodesByFrame: IgnoredNodeMap,\n): Promise<ExclusionIntervalsByFrame> {\n const intervalsByFrame: ExclusionIntervalsByFrame = new Map();\n if (!ignoredNodesByFrame.size) return intervalsByFrame;\n const childFramesByParent = await resolveChildFramesByParent(page, context);\n const excludedFrames = new Set<string>();\n\n const pushInterval = (frameId: string, start: number, end: number) => {\n const intervals = intervalsByFrame.get(frameId) ?? [];\n intervals.push({ start, end });\n intervalsByFrame.set(frameId, intervals);\n };\n\n const excludeFrameSubtree = async (frameId: string): Promise<void> => {\n if (excludedFrames.has(frameId)) return;\n excludedFrames.add(frameId);\n\n const idx = ownerSessionIndexForFrame(page, frameId, sessionToIndex);\n if (!idx) return;\n const parentId = context.parentByFrame.get(frameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, frameId);\n const docRootBe = await resolveFrameDocRootBackendId(\n page,\n frameId,\n idx,\n sameSessionAsParent,\n );\n const start = idx.enterByBe.get(docRootBe);\n const end = idx.exitByBe.get(docRootBe);\n if (typeof start === \"number\" && typeof end === \"number\") {\n pushInterval(frameId, start, end);\n }\n\n for (const childFrameId of listChildrenOf(context.parentByFrame, frameId)) {\n await excludeFrameSubtree(childFrameId);\n }\n };\n\n const excludeIgnoredNode = async (\n frameId: string,\n backendNodeId: number,\n ): Promise<void> => {\n const idx = ownerSessionIndexForFrame(page, frameId, sessionToIndex);\n if (!idx) return;\n const start = idx.enterByBe.get(backendNodeId);\n const end = idx.exitByBe.get(backendNodeId);\n if (typeof start !== \"number\" || typeof end !== \"number\") return;\n\n pushInterval(frameId, start, end);\n for (const childFrame of childFramesByParent.get(frameId) ?? []) {\n const hostEnter = idx.enterByBe.get(childFrame.hostBackendNodeId);\n if (typeof hostEnter !== \"number\") continue;\n if (hostEnter < start || hostEnter > end) continue;\n await excludeFrameSubtree(childFrame.childFrameId);\n }\n };\n\n for (const [frameId, backendNodeIds] of ignoredNodesByFrame.entries()) {\n for (const backendNodeId of backendNodeIds) {\n await excludeIgnoredNode(frameId, backendNodeId);\n }\n }\n\n for (const [frameId, intervals] of intervalsByFrame.entries()) {\n intervals.sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: Interval[] = [];\n for (const interval of intervals) {\n const prev = merged[merged.length - 1];\n if (!prev || interval.start > prev.end) {\n merged.push({ ...interval });\n continue;\n }\n if (interval.end > prev.end) prev.end = interval.end;\n }\n intervalsByFrame.set(frameId, merged);\n }\n\n return intervalsByFrame;\n}\n\nasync function resolveChildFramesByParent(\n page: Page,\n context: FrameContext,\n): Promise<ChildFramesByParent> {\n const childFramesByParent: ChildFramesByParent = new Map();\n\n for (const frameId of context.frames) {\n const parentId = context.parentByFrame.get(frameId);\n if (!parentId) continue;\n\n const session = parentSession(page, context.parentByFrame, frameId);\n if (!session) continue;\n\n try {\n const { backendNodeId } = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n if (typeof backendNodeId !== \"number\") continue;\n const childFrames = childFramesByParent.get(parentId) ?? [];\n childFrames.push({\n childFrameId: frameId,\n hostBackendNodeId: backendNodeId,\n });\n childFramesByParent.set(parentId, childFrames);\n } catch {\n continue;\n }\n }\n\n return childFramesByParent;\n}\n\nfunction makeIsIgnoredBackendNode(\n frameId: string,\n idx: SessionDomIndex | undefined,\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): ((backendNodeId: number) => boolean) | undefined {\n if (!idx) return undefined;\n const intervals = exclusionIntervalsByFrame.get(frameId);\n if (!intervals?.length) return undefined;\n\n return (backendNodeId: number): boolean => {\n const enter = idx.enterByBe.get(backendNodeId);\n if (typeof enter !== \"number\") return false;\n\n let lo = 0;\n let hi = intervals.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const interval = intervals[mid]!;\n if (enter < interval.start) {\n hi = mid - 1;\n } else if (enter > interval.end) {\n lo = mid + 1;\n } else {\n return true;\n }\n }\n return false;\n };\n}\n\nfunction parseEncodedBackendNodeId(encodedId: string): number | undefined {\n const parts = encodedId.split(\"-\");\n if (parts.length !== 2) return undefined;\n const backendNodeId = Number(parts[1]);\n return Number.isFinite(backendNodeId) ? backendNodeId : undefined;\n}\n\nfunction ownerSessionIndexForFrame(\n page: Page,\n frameId: string,\n sessionToIndex: Map<string, SessionDomIndex>,\n): SessionDomIndex | undefined {\n const session = ownerSession(page, frameId);\n return sessionToIndex.get(session.id ?? \"root\");\n}\n\nasync function resolveFrameDocRootBackendId(\n page: Page,\n frameId: string,\n idx: SessionDomIndex,\n sameSessionAsParent: boolean,\n): Promise<number> {\n if (!sameSessionAsParent) return idx.rootBackend;\n const session = ownerSession(page, frameId);\n try {\n const { backendNodeId } = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n if (typeof backendNodeId === \"number\") {\n const docRootBe = idx.contentDocRootByIframe.get(backendNodeId);\n if (typeof docRootBe === \"number\") return docRootBe;\n }\n } catch {\n //\n }\n return idx.rootBackend;\n}\n\n/**\n * Step 4 – walk the frame tree (parent-first) to compute absolute prefixes for\n * every frame. The prefix is the absolute XPath of the iframe element hosting\n * the frame, so we can later convert relative XPaths into cross-frame ones.\n */\nexport async function computeFramePrefixes(\n page: Page,\n context: FrameContext,\n perFrameMaps: Map<string, FrameDomMaps>,\n frameIds: string[],\n): Promise<{\n absPrefix: Map<string, string>;\n iframeHostEncByChild: Map<string, string>;\n}> {\n const absPrefix = new Map<string, string>();\n const iframeHostEncByChild = new Map<string, string>();\n absPrefix.set(context.rootId, \"\");\n const included = new Set(frameIds);\n\n const queue: string[] = [];\n if (included.has(context.rootId)) {\n queue.push(context.rootId);\n }\n\n while (queue.length) {\n const parent = queue.shift()!;\n const parentAbs = absPrefix.get(parent)!;\n\n for (const child of context.frames) {\n if (!included.has(child)) continue;\n if (context.parentByFrame.get(child) !== parent) continue;\n queue.push(child);\n\n const parentSess = parentSession(page, context.parentByFrame, child);\n\n const ownerBackendNodeId = await (async () => {\n try {\n const { backendNodeId } = await parentSess.send<{\n backendNodeId?: number;\n }>(\"DOM.getFrameOwner\", { frameId: child });\n return backendNodeId;\n } catch {\n return undefined;\n }\n })();\n\n if (!ownerBackendNodeId) {\n // OOPIFs resolved via a different session inherit the parent prefix.\n absPrefix.set(child, parentAbs);\n continue;\n }\n\n const parentDom = perFrameMaps.get(parent);\n const iframeEnc = `${page.getOrdinal(parent)}-${ownerBackendNodeId}`;\n const iframeXPath = parentDom?.xpathMap[iframeEnc];\n\n const childAbs = iframeXPath\n ? prefixXPath(parentAbs || \"/\", iframeXPath)\n : parentAbs;\n\n absPrefix.set(child, childAbs);\n iframeHostEncByChild.set(child, iframeEnc);\n }\n }\n\n return { absPrefix, iframeHostEncByChild };\n}\n\n/**\n * Step 5 – merge per-frame maps into the combined snapshot payload. We prefix\n * each frame's relative XPaths with the absolute path collected in step 4,\n * merge URL maps, and stitch text outlines by nesting child trees under the\n * encoded id of their parent iframe host.\n */\nexport function mergeFramesIntoSnapshot(\n context: FrameContext,\n perFrameMaps: Map<string, FrameDomMaps>,\n perFrameOutlines: Array<{ frameId: string; outline: string }>,\n absPrefix: Map<string, string>,\n iframeHostEncByChild: Map<string, string>,\n frameIds: string[],\n): HybridSnapshot {\n const combinedXpathMap: Record<string, string> = {};\n const combinedUrlMap: Record<string, string> = {};\n\n for (const frameId of frameIds) {\n const maps = perFrameMaps.get(frameId);\n if (!maps) continue;\n\n const abs = absPrefix.get(frameId) ?? \"\";\n const isRoot = abs === \"\" || abs === \"/\";\n\n if (isRoot) {\n Object.assign(combinedXpathMap, maps.xpathMap);\n Object.assign(combinedUrlMap, maps.urlMap);\n continue;\n }\n\n for (const [encId, xp] of Object.entries(maps.xpathMap)) {\n combinedXpathMap[encId] = prefixXPath(abs, xp);\n }\n Object.assign(combinedUrlMap, maps.urlMap);\n }\n\n const idToTree = new Map<string, string>();\n for (const { frameId, outline } of perFrameOutlines) {\n const parentEnc = iframeHostEncByChild.get(frameId);\n // The key is the parent iframe's encoded id so injectSubtrees can nest lines.\n if (parentEnc) idToTree.set(parentEnc, outline);\n }\n\n const rootOutline =\n perFrameOutlines.find((o) => o.frameId === context.rootId)?.outline ??\n perFrameOutlines[0]?.outline ??\n \"\";\n const combinedTree = injectSubtrees(rootOutline, idToTree);\n\n return {\n combinedTree,\n combinedXpathMap,\n combinedUrlMap,\n perFrame: perFrameOutlines.map(({ frameId, outline }) => {\n const maps = perFrameMaps.get(frameId);\n return {\n frameId,\n outline,\n xpathMap: maps?.xpathMap ?? {},\n urlMap: maps?.urlMap ?? {},\n };\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/capture.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { Page } from \"../../page.js\";\nimport { Frame } from \"../../frame.js\";\nimport {\n FrameSelectorResolver,\n type ResolvedNode,\n type SelectorQuery,\n} from \"../../selectorResolver.js\";\nimport { v3Logger } from \"../../../logger.js\";\nimport type {\n FrameContext,\n FrameDomMaps,\n FrameParentIndex,\n HybridSnapshot,\n SnapshotOptions,\n SessionDomIndex,\n} from \"../../../types/private/index.js\";\nimport { a11yForFrame } from \"./a11yTree.js\";\nimport {\n resolveCssFocusFrameAndTail,\n resolveFocusFrameAndTail,\n listChildrenOf,\n} from \"./focusSelectors.js\";\nimport {\n buildSessionDomIndex,\n domMapsForSession,\n relativizeXPath,\n} from \"./domTree.js\";\nimport { injectSubtrees } from \"./treeFormatUtils.js\";\nimport { ownerSession, parentSession } from \"./sessions.js\";\nimport { normalizeXPath, prefixXPath } from \"./xpathUtils.js\";\n\ntype IgnoredNodeMap = Map<string, Set<number>>;\ntype Interval = { start: number; end: number };\ntype ExclusionIntervalsByFrame = Map<string, Interval[]>;\ntype ChildFrameHost = { childFrameId: string; hostBackendNodeId: number };\ntype ChildFramesByParent = Map<string, ChildFrameHost[]>;\ntype WellFormedString = string & { toWellFormed(): string };\n\n/**\n * Capture a hybrid DOM + Accessibility snapshot for the provided page.\n *\n * Flow overview:\n * 1. (Optional) Scope directly to a requested selector. We walk iframe hops to\n * find the owning frame, build just that frame’s DOM + AX tree, and bail out\n * early when the subtree satisfies the caller.\n * 2. Build DOM indexes for every unique CDP session. DOM.getDocument is called\n * once per session and hydrated so per-frame slices can share the result.\n * 3. Slice each frame’s DOM data from its session index and fetch its AX tree.\n * This yields relative XPath/tag/url maps for the document rooted at that frame.\n * 4. Walk the frame tree to compute absolute iframe prefixes. Every child frame\n * needs the XPath of the iframe element that hosts it so we can prefix maps.\n * 5. Merge all per-frame results into global combined maps and stitch the text\n * outline. The final payload mirrors the legacy shape but is built in layers.\n *\n * Each numbered block below references the step above for easier debugging.\n */\nexport async function captureHybridSnapshot(\n page: Page,\n options?: SnapshotOptions,\n): Promise<HybridSnapshot> {\n const pierce = options?.pierceShadow ?? true;\n const includeIframes = options?.includeIframes !== false;\n const hasIgnoreSelectors = (options?.ignoreSelectors?.length ?? 0) > 0;\n\n const context = buildFrameContext(page);\n const framesInScope = includeIframes ? [...context.frames] : [context.rootId];\n if (!framesInScope.includes(context.rootId)) {\n framesInScope.unshift(context.rootId);\n }\n\n if (!hasIgnoreSelectors) {\n const scopedSnapshot = await tryScopedSnapshot(\n page,\n options,\n context,\n pierce,\n new Map<string, SessionDomIndex>(),\n new Map(),\n );\n if (scopedSnapshot) return scopedSnapshot;\n }\n\n const sessionToIndex = await buildSessionIndexes(page, framesInScope, pierce);\n const ignoredNodesByFrame = await resolveIgnoredNodes(\n page,\n options?.ignoreSelectors,\n context,\n sessionToIndex,\n );\n const exclusionIntervalsByFrame = await buildFrameExclusionIntervals(\n page,\n context,\n sessionToIndex,\n ignoredNodesByFrame,\n );\n if (hasIgnoreSelectors) {\n const scopedSnapshot = await tryScopedSnapshot(\n page,\n options,\n context,\n pierce,\n sessionToIndex,\n exclusionIntervalsByFrame,\n );\n if (scopedSnapshot) return scopedSnapshot;\n }\n\n const { perFrameMaps, perFrameOutlines } = await collectPerFrameMaps(\n page,\n context,\n sessionToIndex,\n options,\n pierce,\n framesInScope,\n exclusionIntervalsByFrame,\n );\n const { absPrefix, iframeHostEncByChild } = await computeFramePrefixes(\n page,\n context,\n perFrameMaps,\n framesInScope,\n );\n\n return mergeFramesIntoSnapshot(\n context,\n perFrameMaps,\n perFrameOutlines,\n absPrefix,\n iframeHostEncByChild,\n framesInScope,\n );\n}\n\n/**\n * Snapshot the current frame tree so downstream helpers have consistent topology\n * without re-querying CDP. The map is intentionally shallow (frameId → parentId)\n * so it is serializable/testable without holding on to CDP handles.\n */\nexport function buildFrameContext(page: Page): FrameContext {\n const rootId = page.mainFrameId();\n const frameTree = page.asProtocolFrameTree(rootId);\n const parentByFrame: FrameParentIndex = new Map();\n (function index(n: Protocol.Page.FrameTree, parent: string | null) {\n parentByFrame.set(n.frame.id, parent);\n for (const c of n.childFrames ?? []) index(c, n.frame.id);\n })(frameTree, null);\n const frames = page.listAllFrameIds();\n return { rootId, parentByFrame, frames };\n}\n\n/**\n * Step 1 – scoped snapshot fast-path. If a selector is provided we try to:\n * 1) Resolve the selector (XPath or CSS) across iframes.\n * 2) Build DOM + AX data only for the owning frame.\n * 3) Bail out early when the selector's subtree satisfies the request.\n *\n * Returns `null` when scoping fails (e.g., selector miss) so the caller can\n * fall back to the full multi-frame snapshot.\n */\nexport async function tryScopedSnapshot(\n page: Page,\n options: SnapshotOptions | undefined,\n context: FrameContext,\n pierce: boolean,\n sessionToIndex: Map<string, SessionDomIndex>,\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): Promise<HybridSnapshot | null> {\n const requestedFocus = options?.focusSelector?.trim();\n if (!requestedFocus) return null;\n\n const logScopeFallback = () => {\n v3Logger({\n message: `Unable to narrow scope with selector. Falling back to using full DOM`,\n level: 1,\n auxiliary: {\n arguments: {\n value: `selector: ${options?.focusSelector?.trim()}`,\n type: \"string\",\n },\n },\n });\n };\n\n try {\n let targetFrameId: string;\n let tailSelector: string | undefined;\n let absPrefix: string | undefined;\n\n const looksLikeXPath =\n /^xpath=/i.test(requestedFocus) || requestedFocus.startsWith(\"/\");\n if (looksLikeXPath) {\n const focus = normalizeXPath(requestedFocus);\n const hit = await resolveFocusFrameAndTail(\n page,\n focus,\n context.parentByFrame,\n context.rootId,\n );\n targetFrameId = hit.targetFrameId;\n tailSelector = hit.tailXPath || undefined;\n absPrefix = hit.absPrefix;\n } else {\n const cssHit = await resolveCssFocusFrameAndTail(\n page,\n requestedFocus,\n context.parentByFrame,\n context.rootId,\n );\n targetFrameId = cssHit.targetFrameId;\n tailSelector = cssHit.tailSelector || undefined;\n absPrefix = cssHit.absPrefix;\n }\n\n const owningSess = ownerSession(page, targetFrameId);\n const parentId = context.parentByFrame.get(targetFrameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, targetFrameId);\n const { tagNameMap, xpathMap, scrollableMap } = await domMapsForSession(\n owningSess,\n targetFrameId,\n pierce,\n (fid, be) => `${page.getOrdinal(fid)}-${be}`,\n sameSessionAsParent,\n );\n\n const { outline, urlMap, scopeApplied } = await a11yForFrame(\n owningSess,\n targetFrameId,\n {\n focusSelector: tailSelector || undefined,\n isIgnoredBackendNode: makeIsIgnoredBackendNode(\n targetFrameId,\n ownerSessionIndexForFrame(page, targetFrameId, sessionToIndex),\n exclusionIntervalsByFrame,\n ),\n tagNameMap,\n experimental: options?.experimental ?? false,\n scrollableMap,\n encode: (backendNodeId) =>\n `${page.getOrdinal(targetFrameId)}-${backendNodeId}`,\n },\n );\n\n const scopedXpathMap: Record<string, string> = {};\n const isIgnoredBackendNode = makeIsIgnoredBackendNode(\n targetFrameId,\n ownerSessionIndexForFrame(page, targetFrameId, sessionToIndex),\n exclusionIntervalsByFrame,\n );\n const abs = absPrefix ?? \"\";\n const isRoot = !abs || abs === \"/\";\n if (isRoot) {\n for (const [encId, xp] of Object.entries(xpathMap)) {\n const backendNodeId = parseEncodedBackendNodeId(encId);\n if (\n typeof backendNodeId === \"number\" &&\n isIgnoredBackendNode?.(backendNodeId)\n ) {\n continue;\n }\n scopedXpathMap[encId] = xp;\n }\n } else {\n // Prefix relative XPaths so the scoped result matches the global encoding.\n for (const [encId, xp] of Object.entries(xpathMap)) {\n const backendNodeId = parseEncodedBackendNodeId(encId);\n if (\n typeof backendNodeId === \"number\" &&\n isIgnoredBackendNode?.(backendNodeId)\n ) {\n continue;\n }\n scopedXpathMap[encId] = prefixXPath(abs, xp);\n }\n }\n\n const scopedUrlMap: Record<string, string> = { ...urlMap };\n\n const wellFormedOutline = (outline as WellFormedString).toWellFormed();\n\n const snapshot: HybridSnapshot = {\n combinedTree: wellFormedOutline,\n combinedXpathMap: scopedXpathMap,\n combinedUrlMap: scopedUrlMap,\n perFrame: [\n {\n frameId: targetFrameId,\n outline: wellFormedOutline,\n xpathMap,\n urlMap,\n },\n ],\n };\n\n if (scopeApplied) {\n return snapshot;\n }\n\n logScopeFallback();\n } catch {\n logScopeFallback();\n }\n return null;\n}\n\n/**\n * Step 2 – call DOM.getDocument once per unique CDP session and hydrate the\n * result so per-frame slices can share the structure. We key by session id\n * because same process iframes live inside the same session.\n */\nexport async function buildSessionIndexes(\n page: Page,\n frames: string[],\n pierce: boolean,\n): Promise<Map<string, SessionDomIndex>> {\n const sessionToIndex = new Map<string, SessionDomIndex>();\n const sessionById = new Map<string, CDPSessionLike>();\n for (const frameId of frames) {\n const sess = ownerSession(page, frameId);\n const sid = sess.id ?? \"root\";\n if (!sessionById.has(sid)) sessionById.set(sid, sess);\n }\n for (const [sid, sess] of sessionById.entries()) {\n const idx = await buildSessionDomIndex(sess, pierce);\n sessionToIndex.set(sid, idx);\n }\n return sessionToIndex;\n}\n\n/**\n * Step 3 – derive per-frame DOM maps and accessibility outlines.\n * Each frame:\n * - slices the shared session index down to its document root\n * - builds frame-aware encoded ids (ordinal-backendNodeId)\n * - collects tag/xpath/scrollability maps for DOM-based lookups\n * - fetches its AX tree to produce outlines and URL maps\n */\nexport async function collectPerFrameMaps(\n page: Page,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n options: SnapshotOptions | undefined,\n pierce: boolean,\n frameIds: string[],\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): Promise<{\n perFrameMaps: Map<string, FrameDomMaps>;\n perFrameOutlines: Array<{ frameId: string; outline: string }>;\n}> {\n const perFrameMaps = new Map<string, FrameDomMaps>();\n const perFrameOutlines: Array<{ frameId: string; outline: string }> = [];\n\n for (const frameId of frameIds) {\n const sess = ownerSession(page, frameId);\n const sid = sess.id ?? \"root\";\n let idx = sessionToIndex.get(sid);\n if (!idx) {\n idx = await buildSessionDomIndex(sess, pierce);\n sessionToIndex.set(sid, idx);\n }\n\n const parentId = context.parentByFrame.get(frameId);\n const sameSessionAsParent =\n !!parentId && ownerSession(page, parentId) === sess;\n\n const docRootBe = await resolveFrameDocRootBackendId(\n page,\n frameId,\n idx,\n sameSessionAsParent,\n );\n\n const tagNameMap: Record<string, string> = {};\n const xpathMap: Record<string, string> = {};\n const scrollableMap: Record<string, boolean> = {};\n const isIgnoredBackendNode = makeIsIgnoredBackendNode(\n frameId,\n idx,\n exclusionIntervalsByFrame,\n );\n const enc = (be: number) => `${page.getOrdinal(frameId)}-${be}`;\n const baseAbs = idx.absByBe.get(docRootBe) ?? \"/\";\n\n for (const [be, nodeAbs] of idx.absByBe.entries()) {\n const nodeDocRoot = idx.docRootOf.get(be);\n if (nodeDocRoot !== docRootBe) continue;\n if (isIgnoredBackendNode?.(be)) continue;\n\n // Translate absolute XPaths into document-relative ones for this frame.\n const rel = relativizeXPath(baseAbs, nodeAbs);\n const key = enc(be);\n xpathMap[key] = rel;\n const tag = idx.tagByBe.get(be);\n if (tag) tagNameMap[key] = tag;\n if (idx.scrollByBe.get(be)) scrollableMap[key] = true;\n }\n\n const { outline, urlMap } = await a11yForFrame(sess, frameId, {\n isIgnoredBackendNode,\n experimental: options?.experimental ?? false,\n tagNameMap,\n scrollableMap,\n encode: (backendNodeId) => `${page.getOrdinal(frameId)}-${backendNodeId}`,\n });\n\n perFrameOutlines.push({ frameId, outline });\n perFrameMaps.set(frameId, { tagNameMap, xpathMap, scrollableMap, urlMap });\n }\n\n return { perFrameMaps, perFrameOutlines };\n}\n\nexport async function resolveIgnoredNodes(\n page: Page,\n ignoreSelectors: string[] | undefined,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n): Promise<IgnoredNodeMap> {\n const ignoredNodesByFrame: IgnoredNodeMap = new Map();\n\n for (const rawSelector of ignoreSelectors ?? []) {\n const selector = rawSelector.trim();\n if (!selector) continue;\n\n try {\n const resolved = await resolveIgnoredNodesForSelector(\n page,\n selector,\n context,\n sessionToIndex,\n );\n for (const match of resolved) {\n const nodes =\n ignoredNodesByFrame.get(match.frameId) ?? new Set<number>();\n nodes.add(match.backendNodeId);\n ignoredNodesByFrame.set(match.frameId, nodes);\n }\n } catch {\n continue;\n }\n }\n\n return ignoredNodesByFrame;\n}\n\nasync function resolveIgnoredNodesForSelector(\n page: Page,\n selector: string,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n): Promise<Array<{ frameId: string; backendNodeId: number }>> {\n const looksLikeXPath = /^xpath=/i.test(selector) || selector.startsWith(\"/\");\n\n if (looksLikeXPath) {\n const hit = await resolveFocusFrameAndTail(\n page,\n normalizeXPath(selector),\n context.parentByFrame,\n context.rootId,\n );\n const targetFrameId = hit.targetFrameId;\n const tailXPath = hit.tailXPath || \"/\";\n if (tailXPath === \"/\") {\n const idx = ownerSessionIndexForFrame(\n page,\n targetFrameId,\n sessionToIndex,\n );\n if (!idx) return [];\n const parentId = context.parentByFrame.get(targetFrameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, targetFrameId);\n const backendNodeId = await resolveFrameDocRootBackendId(\n page,\n targetFrameId,\n idx,\n sameSessionAsParent,\n );\n return [{ frameId: targetFrameId, backendNodeId }];\n }\n return resolveIgnoredNodesInFrame(page, targetFrameId, {\n kind: \"xpath\",\n value: tailXPath,\n });\n }\n\n const hit = await resolveCssFocusFrameAndTail(\n page,\n selector,\n context.parentByFrame,\n context.rootId,\n );\n const targetFrameId = hit.targetFrameId;\n return resolveIgnoredNodesInFrame(page, targetFrameId, {\n kind: \"css\",\n value: hit.tailSelector || selector,\n });\n}\n\nasync function resolveIgnoredNodesInFrame(\n page: Page,\n frameId: string,\n query: SelectorQuery,\n): Promise<Array<{ frameId: string; backendNodeId: number }>> {\n const session = ownerSession(page, frameId);\n const frame = new Frame(session, frameId, \"\", false);\n const resolver = new FrameSelectorResolver(frame);\n const resolvedNodes = await resolver.resolveAll(query);\n if (!resolvedNodes.length) return [];\n\n const backendNodeIds = await describeResolvedNodes(session, resolvedNodes);\n return backendNodeIds.map((backendNodeId) => ({ frameId, backendNodeId }));\n}\n\nasync function describeResolvedNodes(\n session: CDPSessionLike,\n resolvedNodes: ResolvedNode[],\n): Promise<number[]> {\n const backendNodeIds = new Set<number>();\n\n try {\n for (const resolvedNode of resolvedNodes) {\n const desc = await session.send<Protocol.DOM.DescribeNodeResponse>(\n \"DOM.describeNode\",\n { objectId: resolvedNode.objectId },\n );\n const backendNodeId = desc.node.backendNodeId;\n if (typeof backendNodeId === \"number\") {\n backendNodeIds.add(backendNodeId);\n }\n }\n } finally {\n await Promise.all(\n resolvedNodes.map((resolvedNode) =>\n session\n .send(\"Runtime.releaseObject\", { objectId: resolvedNode.objectId })\n .catch(() => {}),\n ),\n );\n }\n\n return [...backendNodeIds];\n}\n\nexport async function buildFrameExclusionIntervals(\n page: Page,\n context: FrameContext,\n sessionToIndex: Map<string, SessionDomIndex>,\n ignoredNodesByFrame: IgnoredNodeMap,\n): Promise<ExclusionIntervalsByFrame> {\n const intervalsByFrame: ExclusionIntervalsByFrame = new Map();\n if (!ignoredNodesByFrame.size) return intervalsByFrame;\n const childFramesByParent = await resolveChildFramesByParent(page, context);\n const excludedFrames = new Set<string>();\n\n const pushInterval = (frameId: string, start: number, end: number) => {\n const intervals = intervalsByFrame.get(frameId) ?? [];\n intervals.push({ start, end });\n intervalsByFrame.set(frameId, intervals);\n };\n\n const excludeFrameSubtree = async (frameId: string): Promise<void> => {\n if (excludedFrames.has(frameId)) return;\n excludedFrames.add(frameId);\n\n const idx = ownerSessionIndexForFrame(page, frameId, sessionToIndex);\n if (!idx) return;\n const parentId = context.parentByFrame.get(frameId);\n const sameSessionAsParent =\n !!parentId &&\n ownerSession(page, parentId) === ownerSession(page, frameId);\n const docRootBe = await resolveFrameDocRootBackendId(\n page,\n frameId,\n idx,\n sameSessionAsParent,\n );\n const start = idx.enterByBe.get(docRootBe);\n const end = idx.exitByBe.get(docRootBe);\n if (typeof start === \"number\" && typeof end === \"number\") {\n pushInterval(frameId, start, end);\n }\n\n for (const childFrameId of listChildrenOf(context.parentByFrame, frameId)) {\n await excludeFrameSubtree(childFrameId);\n }\n };\n\n const excludeIgnoredNode = async (\n frameId: string,\n backendNodeId: number,\n ): Promise<void> => {\n const idx = ownerSessionIndexForFrame(page, frameId, sessionToIndex);\n if (!idx) return;\n const start = idx.enterByBe.get(backendNodeId);\n const end = idx.exitByBe.get(backendNodeId);\n if (typeof start !== \"number\" || typeof end !== \"number\") return;\n\n pushInterval(frameId, start, end);\n for (const childFrame of childFramesByParent.get(frameId) ?? []) {\n const hostEnter = idx.enterByBe.get(childFrame.hostBackendNodeId);\n if (typeof hostEnter !== \"number\") continue;\n if (hostEnter < start || hostEnter > end) continue;\n await excludeFrameSubtree(childFrame.childFrameId);\n }\n };\n\n for (const [frameId, backendNodeIds] of ignoredNodesByFrame.entries()) {\n for (const backendNodeId of backendNodeIds) {\n await excludeIgnoredNode(frameId, backendNodeId);\n }\n }\n\n for (const [frameId, intervals] of intervalsByFrame.entries()) {\n intervals.sort((a, b) => a.start - b.start || a.end - b.end);\n const merged: Interval[] = [];\n for (const interval of intervals) {\n const prev = merged[merged.length - 1];\n if (!prev || interval.start > prev.end) {\n merged.push({ ...interval });\n continue;\n }\n if (interval.end > prev.end) prev.end = interval.end;\n }\n intervalsByFrame.set(frameId, merged);\n }\n\n return intervalsByFrame;\n}\n\nasync function resolveChildFramesByParent(\n page: Page,\n context: FrameContext,\n): Promise<ChildFramesByParent> {\n const childFramesByParent: ChildFramesByParent = new Map();\n\n for (const frameId of context.frames) {\n const parentId = context.parentByFrame.get(frameId);\n if (!parentId) continue;\n\n const session = parentSession(page, context.parentByFrame, frameId);\n if (!session) continue;\n\n try {\n const { backendNodeId } = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n if (typeof backendNodeId !== \"number\") continue;\n const childFrames = childFramesByParent.get(parentId) ?? [];\n childFrames.push({\n childFrameId: frameId,\n hostBackendNodeId: backendNodeId,\n });\n childFramesByParent.set(parentId, childFrames);\n } catch {\n continue;\n }\n }\n\n return childFramesByParent;\n}\n\nfunction makeIsIgnoredBackendNode(\n frameId: string,\n idx: SessionDomIndex | undefined,\n exclusionIntervalsByFrame: ExclusionIntervalsByFrame,\n): ((backendNodeId: number) => boolean) | undefined {\n if (!idx) return undefined;\n const intervals = exclusionIntervalsByFrame.get(frameId);\n if (!intervals?.length) return undefined;\n\n return (backendNodeId: number): boolean => {\n const enter = idx.enterByBe.get(backendNodeId);\n if (typeof enter !== \"number\") return false;\n\n let lo = 0;\n let hi = intervals.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const interval = intervals[mid]!;\n if (enter < interval.start) {\n hi = mid - 1;\n } else if (enter > interval.end) {\n lo = mid + 1;\n } else {\n return true;\n }\n }\n return false;\n };\n}\n\nfunction parseEncodedBackendNodeId(encodedId: string): number | undefined {\n const parts = encodedId.split(\"-\");\n if (parts.length !== 2) return undefined;\n const backendNodeId = Number(parts[1]);\n return Number.isFinite(backendNodeId) ? backendNodeId : undefined;\n}\n\nfunction ownerSessionIndexForFrame(\n page: Page,\n frameId: string,\n sessionToIndex: Map<string, SessionDomIndex>,\n): SessionDomIndex | undefined {\n const session = ownerSession(page, frameId);\n return sessionToIndex.get(session.id ?? \"root\");\n}\n\nasync function resolveFrameDocRootBackendId(\n page: Page,\n frameId: string,\n idx: SessionDomIndex,\n sameSessionAsParent: boolean,\n): Promise<number> {\n if (!sameSessionAsParent) return idx.rootBackend;\n const session = ownerSession(page, frameId);\n try {\n const { backendNodeId } = await session.send<{ backendNodeId?: number }>(\n \"DOM.getFrameOwner\",\n { frameId },\n );\n if (typeof backendNodeId === \"number\") {\n const docRootBe = idx.contentDocRootByIframe.get(backendNodeId);\n if (typeof docRootBe === \"number\") return docRootBe;\n }\n } catch {\n //\n }\n return idx.rootBackend;\n}\n\n/**\n * Step 4 – walk the frame tree (parent-first) to compute absolute prefixes for\n * every frame. The prefix is the absolute XPath of the iframe element hosting\n * the frame, so we can later convert relative XPaths into cross-frame ones.\n */\nexport async function computeFramePrefixes(\n page: Page,\n context: FrameContext,\n perFrameMaps: Map<string, FrameDomMaps>,\n frameIds: string[],\n): Promise<{\n absPrefix: Map<string, string>;\n iframeHostEncByChild: Map<string, string>;\n}> {\n const absPrefix = new Map<string, string>();\n const iframeHostEncByChild = new Map<string, string>();\n absPrefix.set(context.rootId, \"\");\n const included = new Set(frameIds);\n\n const queue: string[] = [];\n if (included.has(context.rootId)) {\n queue.push(context.rootId);\n }\n\n while (queue.length) {\n const parent = queue.shift()!;\n const parentAbs = absPrefix.get(parent)!;\n\n for (const child of context.frames) {\n if (!included.has(child)) continue;\n if (context.parentByFrame.get(child) !== parent) continue;\n queue.push(child);\n\n const parentSess = parentSession(page, context.parentByFrame, child);\n\n const ownerBackendNodeId = await (async () => {\n try {\n const { backendNodeId } = await parentSess.send<{\n backendNodeId?: number;\n }>(\"DOM.getFrameOwner\", { frameId: child });\n return backendNodeId;\n } catch {\n return undefined;\n }\n })();\n\n if (!ownerBackendNodeId) {\n // OOPIFs resolved via a different session inherit the parent prefix.\n absPrefix.set(child, parentAbs);\n continue;\n }\n\n const parentDom = perFrameMaps.get(parent);\n const iframeEnc = `${page.getOrdinal(parent)}-${ownerBackendNodeId}`;\n const iframeXPath = parentDom?.xpathMap[iframeEnc];\n\n const childAbs = iframeXPath\n ? prefixXPath(parentAbs || \"/\", iframeXPath)\n : parentAbs;\n\n absPrefix.set(child, childAbs);\n iframeHostEncByChild.set(child, iframeEnc);\n }\n }\n\n return { absPrefix, iframeHostEncByChild };\n}\n\n/**\n * Step 5 – merge per-frame maps into the combined snapshot payload. We prefix\n * each frame's relative XPaths with the absolute path collected in step 4,\n * merge URL maps, and stitch text outlines by nesting child trees under the\n * encoded id of their parent iframe host.\n */\nexport function mergeFramesIntoSnapshot(\n context: FrameContext,\n perFrameMaps: Map<string, FrameDomMaps>,\n perFrameOutlines: Array<{ frameId: string; outline: string }>,\n absPrefix: Map<string, string>,\n iframeHostEncByChild: Map<string, string>,\n frameIds: string[],\n): HybridSnapshot {\n const combinedXpathMap: Record<string, string> = {};\n const combinedUrlMap: Record<string, string> = {};\n\n for (const frameId of frameIds) {\n const maps = perFrameMaps.get(frameId);\n if (!maps) continue;\n\n const abs = absPrefix.get(frameId) ?? \"\";\n const isRoot = abs === \"\" || abs === \"/\";\n\n if (isRoot) {\n Object.assign(combinedXpathMap, maps.xpathMap);\n Object.assign(combinedUrlMap, maps.urlMap);\n continue;\n }\n\n for (const [encId, xp] of Object.entries(maps.xpathMap)) {\n combinedXpathMap[encId] = prefixXPath(abs, xp);\n }\n Object.assign(combinedUrlMap, maps.urlMap);\n }\n\n const idToTree = new Map<string, string>();\n for (const { frameId, outline } of perFrameOutlines) {\n const parentEnc = iframeHostEncByChild.get(frameId);\n // The key is the parent iframe's encoded id so injectSubtrees can nest lines.\n if (parentEnc) idToTree.set(parentEnc, outline);\n }\n\n const rootOutline =\n perFrameOutlines.find((o) => o.frameId === context.rootId)?.outline ??\n perFrameOutlines[0]?.outline ??\n \"\";\n const combinedTree = (\n injectSubtrees(rootOutline, idToTree) as WellFormedString\n ).toWellFormed();\n\n return {\n combinedTree,\n combinedXpathMap,\n combinedUrlMap,\n perFrame: perFrameOutlines.map(({ frameId, outline }) => {\n const maps = perFrameMaps.get(frameId);\n return {\n frameId,\n outline,\n xpathMap: maps?.xpathMap ?? {},\n urlMap: maps?.urlMap ?? {},\n };\n }),\n };\n}\n"]}
@@ -67,7 +67,45 @@ async function resolveXpathForLocation(page, x, y) {
67
67
  if (typeof be === "number" &&
68
68
  reportedFrameId &&
69
69
  reportedFrameId !== curFrameId) {
70
- const abs = await (0, xpathUtils_js_1.buildAbsoluteXPathFromChain)(iframeChain, curSession, be);
70
+ const chain = [...iframeChain];
71
+ const framePath = [];
72
+ let frameId = reportedFrameId;
73
+ while (frameId && frameId !== curFrameId) {
74
+ framePath.unshift(frameId);
75
+ frameId = parentByFrame.get(frameId);
76
+ }
77
+ let resolvedFramePath = false;
78
+ if (frameId === curFrameId) {
79
+ resolvedFramePath = true;
80
+ for (const childFrameId of framePath) {
81
+ const parentFrameId = parentByFrame.get(childFrameId);
82
+ if (!parentFrameId) {
83
+ resolvedFramePath = false;
84
+ break;
85
+ }
86
+ try {
87
+ const parentSession = page.getSessionForFrame(parentFrameId);
88
+ const { backendNodeId } = await parentSession.send("DOM.getFrameOwner", { frameId: childFrameId });
89
+ if (typeof backendNodeId !== "number") {
90
+ resolvedFramePath = false;
91
+ break;
92
+ }
93
+ chain.push({
94
+ parentSession,
95
+ iframeBackendNodeId: backendNodeId,
96
+ });
97
+ }
98
+ catch {
99
+ resolvedFramePath = false;
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ if (!resolvedFramePath) {
105
+ return null;
106
+ }
107
+ const leafSession = page.getSessionForFrame(reportedFrameId);
108
+ const abs = await (0, xpathUtils_js_1.buildAbsoluteXPathFromChain)(chain, leafSession, be);
71
109
  return abs
72
110
  ? { frameId: reportedFrameId, backendNodeId: be, absoluteXPath: abs }
73
111
  : null;
@@ -1 +1 @@
1
- {"version":3,"file":"coordinateResolver.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/coordinateResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { Page } from \"../../page.js\";\nimport { executionContexts } from \"../../executionContextRegistry.js\";\nimport { a11yScriptSources } from \"../../../dom/build/a11yScripts.generated.js\";\nimport { buildA11yInvocation } from \"../../a11yInvocation.js\";\nimport type { ResolvedLocation } from \"../../../types/private/snapshot.js\";\nimport { listChildrenOf } from \"./focusSelectors.js\";\nimport { buildAbsoluteXPathFromChain } from \"./xpathUtils.js\";\n\n/**\n * Resolve deepest node for a page coordinate and compute its absolute XPath across frames.\n * More efficient than building a full hybrid snapshot when only a single node’s XPath is needed.\n */\nexport async function resolveXpathForLocation(\n page: Page,\n x: number,\n y: number,\n): Promise<ResolvedLocation | null> {\n const tree = page.getFullFrameTree();\n const parentByFrame = new Map<string, string | null>();\n (function index(n: Protocol.Page.FrameTree, parent: string | null) {\n parentByFrame.set(n.frame.id, parent);\n for (const c of n.childFrames ?? []) index(c, n.frame.id);\n })(tree, null);\n\n const iframeChain: Array<{\n parentSession: CDPSessionLike;\n iframeBackendNodeId: number;\n }> = [];\n\n let curFrameId = page.mainFrameId();\n let curSession = page.getSessionForFrame(curFrameId);\n let curX = x;\n let curY = y;\n\n for (let depth = 0; depth < 8; depth++) {\n try {\n await curSession.send(\"DOM.enable\").catch(() => {});\n\n let sx = 0;\n let sy = 0;\n try {\n await curSession.send(\"Runtime.enable\").catch(() => {});\n const ctxId = await executionContexts\n .waitForMainWorld(curSession, curFrameId)\n .catch(() => {});\n const scrollExpr = buildA11yInvocation(\"getScrollOffsets\", []);\n const evalParams = ctxId\n ? {\n contextId: ctxId,\n expression: scrollExpr,\n returnByValue: true,\n }\n : { expression: scrollExpr, returnByValue: true };\n const { result } = await curSession.send<{\n result: { value?: { sx?: number; sy?: number } };\n }>(\"Runtime.evaluate\", evalParams);\n sx = Number(result?.value?.sx ?? 0);\n sy = Number(result?.value?.sy ?? 0);\n } catch {\n //\n }\n const xi = Math.max(0, Math.floor(curX + sx));\n const yi = Math.max(0, Math.floor(curY + sy));\n\n let res: { backendNodeId?: number; frameId?: string } | undefined;\n try {\n res = await curSession.send<{\n backendNodeId?: number;\n frameId?: string;\n }>(\"DOM.getNodeForLocation\", {\n x: xi,\n y: yi,\n includeUserAgentShadowDOM: false,\n ignorePointerEventsNone: false,\n });\n } catch {\n return null;\n }\n\n const be = res?.backendNodeId;\n const reportedFrameId = res?.frameId;\n if (\n typeof be === \"number\" &&\n reportedFrameId &&\n reportedFrameId !== curFrameId\n ) {\n const abs = await buildAbsoluteXPathFromChain(\n iframeChain,\n curSession,\n be,\n );\n return abs\n ? { frameId: reportedFrameId, backendNodeId: be, absoluteXPath: abs }\n : null;\n }\n\n if (typeof be !== \"number\") return null;\n\n let matchedChild: string | undefined;\n for (const fid of listChildrenOf(parentByFrame, curFrameId)) {\n try {\n const { backendNodeId } = await curSession.send<{\n backendNodeId?: number;\n }>(\"DOM.getFrameOwner\", { frameId: fid });\n if (backendNodeId === be) {\n matchedChild = fid;\n break;\n }\n } catch {\n continue;\n }\n }\n\n if (!matchedChild) {\n const abs = await buildAbsoluteXPathFromChain(\n iframeChain,\n curSession,\n be,\n );\n return abs\n ? { frameId: curFrameId, backendNodeId: be, absoluteXPath: abs }\n : null;\n }\n\n iframeChain.push({\n parentSession: curSession,\n iframeBackendNodeId: be,\n });\n\n let left = 0;\n let top = 0;\n try {\n const { object } = await curSession.send<{\n object: { objectId?: string };\n }>(\"DOM.resolveNode\", { backendNodeId: be });\n const objectId = object?.objectId;\n if (objectId) {\n const { result } = await curSession.send<{\n result: { value?: { left: number; top: number } };\n }>(\"Runtime.callFunctionOn\", {\n objectId,\n functionDeclaration: a11yScriptSources.getBoundingRectLite,\n returnByValue: true,\n });\n left = Number(result?.value?.left ?? 0);\n top = Number(result?.value?.top ?? 0);\n await curSession\n .send(\"Runtime.releaseObject\", { objectId })\n .catch(() => {});\n }\n } catch {\n //\n }\n curX = Math.max(0, curX - left);\n curY = Math.max(0, curY - top);\n curFrameId = matchedChild;\n curSession = page.getSessionForFrame(curFrameId);\n } catch {\n return null;\n }\n }\n return null;\n}\n"]}
1
+ {"version":3,"file":"coordinateResolver.js","sourceRoot":"","sources":["../../../../../../../lib/v3/understudy/a11y/snapshot/coordinateResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Protocol } from \"devtools-protocol\";\nimport type { CDPSessionLike } from \"../../cdp.js\";\nimport { Page } from \"../../page.js\";\nimport { executionContexts } from \"../../executionContextRegistry.js\";\nimport { a11yScriptSources } from \"../../../dom/build/a11yScripts.generated.js\";\nimport { buildA11yInvocation } from \"../../a11yInvocation.js\";\nimport type { ResolvedLocation } from \"../../../types/private/snapshot.js\";\nimport { listChildrenOf } from \"./focusSelectors.js\";\nimport { buildAbsoluteXPathFromChain } from \"./xpathUtils.js\";\n\n/**\n * Resolve deepest node for a page coordinate and compute its absolute XPath across frames.\n * More efficient than building a full hybrid snapshot when only a single node’s XPath is needed.\n */\nexport async function resolveXpathForLocation(\n page: Page,\n x: number,\n y: number,\n): Promise<ResolvedLocation | null> {\n const tree = page.getFullFrameTree();\n const parentByFrame = new Map<string, string | null>();\n (function index(n: Protocol.Page.FrameTree, parent: string | null) {\n parentByFrame.set(n.frame.id, parent);\n for (const c of n.childFrames ?? []) index(c, n.frame.id);\n })(tree, null);\n\n const iframeChain: Array<{\n parentSession: CDPSessionLike;\n iframeBackendNodeId: number;\n }> = [];\n\n let curFrameId = page.mainFrameId();\n let curSession = page.getSessionForFrame(curFrameId);\n let curX = x;\n let curY = y;\n\n for (let depth = 0; depth < 8; depth++) {\n try {\n await curSession.send(\"DOM.enable\").catch(() => {});\n\n let sx = 0;\n let sy = 0;\n try {\n await curSession.send(\"Runtime.enable\").catch(() => {});\n const ctxId = await executionContexts\n .waitForMainWorld(curSession, curFrameId)\n .catch(() => {});\n const scrollExpr = buildA11yInvocation(\"getScrollOffsets\", []);\n const evalParams = ctxId\n ? {\n contextId: ctxId,\n expression: scrollExpr,\n returnByValue: true,\n }\n : { expression: scrollExpr, returnByValue: true };\n const { result } = await curSession.send<{\n result: { value?: { sx?: number; sy?: number } };\n }>(\"Runtime.evaluate\", evalParams);\n sx = Number(result?.value?.sx ?? 0);\n sy = Number(result?.value?.sy ?? 0);\n } catch {\n //\n }\n const xi = Math.max(0, Math.floor(curX + sx));\n const yi = Math.max(0, Math.floor(curY + sy));\n\n let res: { backendNodeId?: number; frameId?: string } | undefined;\n try {\n res = await curSession.send<{\n backendNodeId?: number;\n frameId?: string;\n }>(\"DOM.getNodeForLocation\", {\n x: xi,\n y: yi,\n includeUserAgentShadowDOM: false,\n ignorePointerEventsNone: false,\n });\n } catch {\n return null;\n }\n\n const be = res?.backendNodeId;\n const reportedFrameId = res?.frameId;\n if (\n typeof be === \"number\" &&\n reportedFrameId &&\n reportedFrameId !== curFrameId\n ) {\n const chain = [...iframeChain];\n const framePath: string[] = [];\n let frameId: string | null | undefined = reportedFrameId;\n while (frameId && frameId !== curFrameId) {\n framePath.unshift(frameId);\n frameId = parentByFrame.get(frameId);\n }\n\n let resolvedFramePath = false;\n if (frameId === curFrameId) {\n resolvedFramePath = true;\n for (const childFrameId of framePath) {\n const parentFrameId = parentByFrame.get(childFrameId);\n if (!parentFrameId) {\n resolvedFramePath = false;\n break;\n }\n try {\n const parentSession = page.getSessionForFrame(parentFrameId);\n const { backendNodeId } = await parentSession.send<{\n backendNodeId?: number;\n }>(\"DOM.getFrameOwner\", { frameId: childFrameId });\n if (typeof backendNodeId !== \"number\") {\n resolvedFramePath = false;\n break;\n }\n\n chain.push({\n parentSession,\n iframeBackendNodeId: backendNodeId,\n });\n } catch {\n resolvedFramePath = false;\n break;\n }\n }\n }\n\n if (!resolvedFramePath) {\n return null;\n }\n\n const leafSession = page.getSessionForFrame(reportedFrameId);\n const abs = await buildAbsoluteXPathFromChain(chain, leafSession, be);\n return abs\n ? { frameId: reportedFrameId, backendNodeId: be, absoluteXPath: abs }\n : null;\n }\n\n if (typeof be !== \"number\") return null;\n\n let matchedChild: string | undefined;\n for (const fid of listChildrenOf(parentByFrame, curFrameId)) {\n try {\n const { backendNodeId } = await curSession.send<{\n backendNodeId?: number;\n }>(\"DOM.getFrameOwner\", { frameId: fid });\n if (backendNodeId === be) {\n matchedChild = fid;\n break;\n }\n } catch {\n continue;\n }\n }\n\n if (!matchedChild) {\n const abs = await buildAbsoluteXPathFromChain(\n iframeChain,\n curSession,\n be,\n );\n return abs\n ? { frameId: curFrameId, backendNodeId: be, absoluteXPath: abs }\n : null;\n }\n\n iframeChain.push({\n parentSession: curSession,\n iframeBackendNodeId: be,\n });\n\n let left = 0;\n let top = 0;\n try {\n const { object } = await curSession.send<{\n object: { objectId?: string };\n }>(\"DOM.resolveNode\", { backendNodeId: be });\n const objectId = object?.objectId;\n if (objectId) {\n const { result } = await curSession.send<{\n result: { value?: { left: number; top: number } };\n }>(\"Runtime.callFunctionOn\", {\n objectId,\n functionDeclaration: a11yScriptSources.getBoundingRectLite,\n returnByValue: true,\n });\n left = Number(result?.value?.left ?? 0);\n top = Number(result?.value?.top ?? 0);\n await curSession\n .send(\"Runtime.releaseObject\", { objectId })\n .catch(() => {});\n }\n } catch {\n //\n }\n curX = Math.max(0, curX - left);\n curY = Math.max(0, curY - top);\n curFrameId = matchedChild;\n curSession = page.getSessionForFrame(curFrameId);\n } catch {\n return null;\n }\n }\n return null;\n}\n"]}
@@ -104,6 +104,18 @@ export declare class Locator {
104
104
  button?: MouseButton;
105
105
  clickCount?: number;
106
106
  }): Promise<void>;
107
+ /**
108
+ * Tap the element at its visual center with a real (trusted) touch.
109
+ * Mirrors {@link click} but synthesizes touch input via `Input.dispatchTouchEvent`
110
+ * instead of mouse input, so mobile layouts that gate handlers on touch/pointer
111
+ * (`pointerType: "touch"`) events — where a mouse click never registers — respond
112
+ * correctly. This is the deterministic (selector-based) counterpart used when a
113
+ * recorded CUA `tap` step is replayed.
114
+ *
115
+ * Does not require touch emulation: CDP delivers a trusted touch sequence even on
116
+ * a session reporting `maxTouchPoints: 0`.
117
+ */
118
+ tap(): Promise<void>;
107
119
  /**
108
120
  * Dispatch a DOM 'click' MouseEvent on the element itself.
109
121
  * - Does not synthesize real pointer input; directly dispatches an event.
@@ -392,6 +392,50 @@ class Locator {
392
392
  }
393
393
  }
394
394
  }
395
+ /**
396
+ * Tap the element at its visual center with a real (trusted) touch.
397
+ * Mirrors {@link click} but synthesizes touch input via `Input.dispatchTouchEvent`
398
+ * instead of mouse input, so mobile layouts that gate handlers on touch/pointer
399
+ * (`pointerType: "touch"`) events — where a mouse click never registers — respond
400
+ * correctly. This is the deterministic (selector-based) counterpart used when a
401
+ * recorded CUA `tap` step is replayed.
402
+ *
403
+ * Does not require touch emulation: CDP delivers a trusted touch sequence even on
404
+ * a session reporting `maxTouchPoints: 0`.
405
+ */
406
+ async tap() {
407
+ const session = this.frame.session;
408
+ const { objectId } = await this.resolveNode();
409
+ try {
410
+ await session.send("DOM.scrollIntoViewIfNeeded", { objectId });
411
+ const box = await session.send("DOM.getBoxModel", { objectId });
412
+ if (!box.model)
413
+ throw new sdkErrors_js_1.ElementNotVisibleError(this.selector);
414
+ const { cx, cy } = this.centerFromBoxContent(box.model.content);
415
+ // Pipelined burst, matching click's press/release batching: CDP preserves
416
+ // per-session command order, so awaiting each dispatch in turn would only
417
+ // add a round trip (a full network RTT against a remote browser).
418
+ await Promise.all([
419
+ session.send("Input.dispatchTouchEvent", {
420
+ type: "touchStart",
421
+ touchPoints: [{ x: cx, y: cy }],
422
+ }),
423
+ session.send("Input.dispatchTouchEvent", {
424
+ type: "touchEnd",
425
+ touchPoints: [],
426
+ }),
427
+ ]);
428
+ }
429
+ finally {
430
+ try {
431
+ await session.send("Runtime.releaseObject", { objectId });
432
+ }
433
+ catch {
434
+ // If the context navigated or was destroyed (e.g., link opens new tab),
435
+ // releaseObject may fail with -32000. Ignore as best-effort cleanup.
436
+ }
437
+ }
438
+ }
395
439
  /**
396
440
  * Dispatch a DOM 'click' MouseEvent on the element itself.
397
441
  * - Does not synthesize real pointer input; directly dispatches an event.