@browserbasehq/orca 3.1.0-patch.0 → 3.1.0-patch.1

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 (387) hide show
  1. package/dist/cjs/cli.js +183 -0
  2. package/dist/cjs/cli.js.map +7 -0
  3. package/dist/cjs/index.d.ts +1 -0
  4. package/dist/cjs/index.js +24956 -0
  5. package/dist/cjs/index.js.map +7 -0
  6. package/dist/cjs/lib/inference.d.ts +65 -0
  7. package/dist/cjs/lib/inferenceLogUtils.d.ts +12 -0
  8. package/dist/cjs/lib/logger.d.ts +69 -0
  9. package/dist/cjs/lib/modelUtils.d.ts +11 -0
  10. package/dist/cjs/lib/prompt.d.ts +14 -0
  11. package/dist/cjs/lib/utils.d.ts +68 -0
  12. package/dist/cjs/lib/v3/agent/AgentClient.d.ts +19 -0
  13. package/dist/cjs/lib/v3/agent/AgentProvider.d.ts +20 -0
  14. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.d.ts +57 -0
  15. package/dist/cjs/lib/v3/agent/GoogleCUAClient.d.ts +74 -0
  16. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.d.ts +71 -0
  17. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +69 -0
  18. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.d.ts +12 -0
  19. package/dist/cjs/lib/v3/agent/tools/act.d.ts +12 -0
  20. package/dist/cjs/lib/v3/agent/tools/ariaTree.d.ts +5 -0
  21. package/dist/cjs/lib/v3/agent/tools/click.d.ts +6 -0
  22. package/dist/cjs/lib/v3/agent/tools/clickAndHold.d.ts +14 -0
  23. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.d.ts +7 -0
  24. package/dist/cjs/lib/v3/agent/tools/extract.d.ts +20 -0
  25. package/dist/cjs/lib/v3/agent/tools/fillFormVision.d.ts +12 -0
  26. package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +12 -0
  27. package/dist/cjs/lib/v3/agent/tools/goto.d.ts +12 -0
  28. package/dist/cjs/lib/v3/agent/tools/index.d.ts +92 -0
  29. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +24 -0
  30. package/dist/cjs/lib/v3/agent/tools/navback.d.ts +6 -0
  31. package/dist/cjs/lib/v3/agent/tools/screenshot.d.ts +6 -0
  32. package/dist/cjs/lib/v3/agent/tools/scroll.d.ts +19 -0
  33. package/dist/cjs/lib/v3/agent/tools/search.d.ts +15 -0
  34. package/dist/cjs/lib/v3/agent/tools/think.d.ts +6 -0
  35. package/dist/cjs/lib/v3/agent/tools/type.d.ts +7 -0
  36. package/dist/cjs/lib/v3/agent/tools/wait.d.ts +5 -0
  37. package/dist/cjs/lib/v3/agent/utils/actionMapping.d.ts +3 -0
  38. package/dist/cjs/lib/v3/agent/utils/coordinateNormalization.d.ts +13 -0
  39. package/dist/cjs/lib/v3/agent/utils/cuaKeyMapping.d.ts +10 -0
  40. package/dist/cjs/lib/v3/agent/utils/googleCustomToolHandler.d.ts +25 -0
  41. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.d.ts +22 -0
  42. package/dist/cjs/lib/v3/agent/utils/imageCompression.d.ts +53 -0
  43. package/dist/cjs/lib/v3/agent/utils/messageProcessing.d.ts +12 -0
  44. package/dist/cjs/lib/v3/agent/utils/screenshotHandler.d.ts +10 -0
  45. package/dist/cjs/lib/v3/agent/utils/validateExperimentalFeatures.d.ts +26 -0
  46. package/dist/cjs/lib/v3/agent/utils/xpath.d.ts +11 -0
  47. package/dist/cjs/lib/v3/api.d.ts +86 -0
  48. package/dist/cjs/lib/v3/cache/ActCache.d.ts +23 -0
  49. package/dist/cjs/lib/v3/cache/AgentCache.d.ts +109 -0
  50. package/dist/cjs/lib/v3/cache/CacheStorage.d.ts +17 -0
  51. package/dist/cjs/lib/v3/cache/serverAgentCache.d.ts +7 -0
  52. package/dist/cjs/lib/v3/cache/utils.d.ts +15 -0
  53. package/dist/cjs/lib/v3/cli.d.ts +2 -0
  54. package/dist/cjs/lib/v3/dom/a11yScripts/index.d.ts +11 -0
  55. package/dist/cjs/lib/v3/dom/build/a11yScripts.generated.d.ts +16 -0
  56. package/dist/cjs/lib/v3/dom/build/locatorScripts.generated.d.ts +52 -0
  57. package/dist/cjs/lib/v3/dom/build/reRenderScriptContent.d.ts +1 -0
  58. package/dist/cjs/lib/v3/dom/build/rerender-index.d.ts +0 -0
  59. package/dist/cjs/lib/v3/dom/build/rerender-index.js +1 -0
  60. package/dist/cjs/lib/v3/dom/build/screenshotScripts.generated.d.ts +4 -0
  61. package/dist/cjs/lib/v3/dom/build/scriptV3Content.d.ts +1 -0
  62. package/dist/cjs/lib/v3/dom/build/v3-index.d.ts +0 -0
  63. package/dist/cjs/lib/v3/dom/build/v3-index.js +1 -0
  64. package/dist/cjs/lib/v3/dom/genA11yScripts.d.ts +1 -0
  65. package/dist/cjs/lib/v3/dom/genDomScripts.d.ts +1 -0
  66. package/dist/cjs/lib/v3/dom/genLocatorScripts.d.ts +1 -0
  67. package/dist/cjs/lib/v3/dom/genScreenshotScripts.d.ts +1 -0
  68. package/dist/cjs/lib/v3/dom/index.d.ts +1 -0
  69. package/dist/cjs/lib/v3/dom/locatorScripts/counts.d.ts +15 -0
  70. package/dist/cjs/lib/v3/dom/locatorScripts/index.d.ts +4 -0
  71. package/dist/cjs/lib/v3/dom/locatorScripts/scripts.d.ts +37 -0
  72. package/dist/cjs/lib/v3/dom/locatorScripts/selectors.d.ts +4 -0
  73. package/dist/cjs/lib/v3/dom/locatorScripts/waitForSelector.d.ts +19 -0
  74. package/dist/cjs/lib/v3/dom/locatorScripts/xpathParser.d.ts +76 -0
  75. package/dist/cjs/lib/v3/dom/locatorScripts/xpathResolver.d.ts +9 -0
  76. package/dist/cjs/lib/v3/dom/piercer.entry.d.ts +1 -0
  77. package/dist/cjs/lib/v3/dom/piercer.runtime.d.ts +23 -0
  78. package/dist/cjs/lib/v3/dom/rerenderMissingShadows.entry.d.ts +1 -0
  79. package/dist/cjs/lib/v3/dom/rerenderMissingShadows.runtime.d.ts +1 -0
  80. package/dist/cjs/lib/v3/dom/screenshotScripts/index.d.ts +1 -0
  81. package/dist/cjs/lib/v3/dom/screenshotScripts/resolveMaskRect.d.ts +8 -0
  82. package/dist/cjs/lib/v3/external_clients/aisdk.d.ts +11 -0
  83. package/dist/cjs/lib/v3/external_clients/customOpenAI.d.ts +18 -0
  84. package/dist/cjs/lib/v3/flowLogger.d.ts +139 -0
  85. package/dist/cjs/lib/v3/handlers/actHandler.d.ts +21 -0
  86. package/dist/cjs/lib/v3/handlers/extractHandler.d.ts +31 -0
  87. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.d.ts +24 -0
  88. package/dist/cjs/lib/v3/handlers/handlerUtils/timeoutGuard.d.ts +2 -0
  89. package/dist/cjs/lib/v3/handlers/observeHandler.d.ts +17 -0
  90. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +32 -0
  91. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +33 -0
  92. package/dist/cjs/lib/v3/index.d.ts +18 -0
  93. package/dist/cjs/lib/v3/launch/browserbase.d.ts +7 -0
  94. package/dist/cjs/lib/v3/launch/local.d.ts +15 -0
  95. package/dist/cjs/lib/v3/llm/AnthropicClient.d.ts +16 -0
  96. package/dist/cjs/lib/v3/llm/CerebrasClient.d.ts +17 -0
  97. package/dist/cjs/lib/v3/llm/GoogleClient.d.ts +19 -0
  98. package/dist/cjs/lib/v3/llm/GroqClient.d.ts +17 -0
  99. package/dist/cjs/lib/v3/llm/LLMClient.d.ts +121 -0
  100. package/dist/cjs/lib/v3/llm/LLMProvider.d.ts +13 -0
  101. package/dist/cjs/lib/v3/llm/OpenAIClient.d.ts +15 -0
  102. package/dist/cjs/lib/v3/llm/aisdk.d.ts +15 -0
  103. package/dist/cjs/lib/v3/logger.d.ts +9 -0
  104. package/dist/cjs/lib/v3/mcp/connection.d.ts +11 -0
  105. package/dist/cjs/lib/v3/mcp/utils.d.ts +3 -0
  106. package/dist/cjs/lib/v3/shutdown/cleanupLocal.d.ts +14 -0
  107. package/dist/cjs/lib/v3/shutdown/supervisor.d.ts +11 -0
  108. package/dist/cjs/lib/v3/shutdown/supervisorClient.d.ts +15 -0
  109. package/dist/cjs/lib/v3/tests/agent-abort-signal.spec.js +113 -0
  110. package/dist/cjs/lib/v3/tests/agent-abort-signal.spec.js.map +7 -0
  111. package/dist/cjs/lib/v3/tests/agent-cache-self-heal.spec.js +102 -0
  112. package/dist/cjs/lib/v3/tests/agent-cache-self-heal.spec.js.map +7 -0
  113. package/dist/cjs/lib/v3/tests/agent-callbacks.spec.js +374 -0
  114. package/dist/cjs/lib/v3/tests/agent-callbacks.spec.js.map +7 -0
  115. package/dist/cjs/lib/v3/tests/agent-experimental-validation.spec.js +354 -0
  116. package/dist/cjs/lib/v3/tests/agent-experimental-validation.spec.js.map +7 -0
  117. package/dist/cjs/lib/v3/tests/agent-hybrid-mode.spec.js +247 -0
  118. package/dist/cjs/lib/v3/tests/agent-hybrid-mode.spec.js.map +7 -0
  119. package/dist/cjs/lib/v3/tests/agent-message-continuation.spec.js +105 -0
  120. package/dist/cjs/lib/v3/tests/agent-message-continuation.spec.js.map +7 -0
  121. package/dist/cjs/lib/v3/tests/agent-streaming.spec.js +126 -0
  122. package/dist/cjs/lib/v3/tests/agent-streaming.spec.js.map +7 -0
  123. package/dist/cjs/lib/v3/tests/cdp-session-detached.spec.js +44 -0
  124. package/dist/cjs/lib/v3/tests/cdp-session-detached.spec.js.map +7 -0
  125. package/dist/cjs/lib/v3/tests/click-count.spec.js +147 -0
  126. package/dist/cjs/lib/v3/tests/click-count.spec.js.map +7 -0
  127. package/dist/cjs/lib/v3/tests/connect-to-existing-browser.spec.js +54 -0
  128. package/dist/cjs/lib/v3/tests/connect-to-existing-browser.spec.js.map +7 -0
  129. package/dist/cjs/lib/v3/tests/context-addInitScript.spec.js +176 -0
  130. package/dist/cjs/lib/v3/tests/context-addInitScript.spec.js.map +7 -0
  131. package/dist/cjs/lib/v3/tests/default-page-tracking.spec.js +53 -0
  132. package/dist/cjs/lib/v3/tests/default-page-tracking.spec.js.map +7 -0
  133. package/dist/cjs/lib/v3/tests/downloads.spec.js +80 -0
  134. package/dist/cjs/lib/v3/tests/downloads.spec.js.map +7 -0
  135. package/dist/cjs/lib/v3/tests/frame-get-location-and-click.spec.js +53 -0
  136. package/dist/cjs/lib/v3/tests/frame-get-location-and-click.spec.js.map +7 -0
  137. package/dist/cjs/lib/v3/tests/iframe-ctx-addInitScript.spec.js +493 -0
  138. package/dist/cjs/lib/v3/tests/iframe-ctx-addInitScript.spec.js.map +7 -0
  139. package/dist/cjs/lib/v3/tests/keep-alive.child.js +92 -0
  140. package/dist/cjs/lib/v3/tests/keep-alive.child.js.map +7 -0
  141. package/dist/cjs/lib/v3/tests/keep-alive.helpers.js +568 -0
  142. package/dist/cjs/lib/v3/tests/keep-alive.helpers.js.map +7 -0
  143. package/dist/cjs/lib/v3/tests/keep-alive.spec.js +15 -0
  144. package/dist/cjs/lib/v3/tests/keep-alive.spec.js.map +7 -0
  145. package/dist/cjs/lib/v3/tests/keyboard.spec.js +296 -0
  146. package/dist/cjs/lib/v3/tests/keyboard.spec.js.map +7 -0
  147. package/dist/cjs/lib/v3/tests/locator-backend-node-id.spec.js +159 -0
  148. package/dist/cjs/lib/v3/tests/locator-backend-node-id.spec.js.map +7 -0
  149. package/dist/cjs/lib/v3/tests/locator-content-methods.spec.js +191 -0
  150. package/dist/cjs/lib/v3/tests/locator-content-methods.spec.js.map +7 -0
  151. package/dist/cjs/lib/v3/tests/locator-count-iframe.spec.js +108 -0
  152. package/dist/cjs/lib/v3/tests/locator-count-iframe.spec.js.map +7 -0
  153. package/dist/cjs/lib/v3/tests/locator-count.spec.js +71 -0
  154. package/dist/cjs/lib/v3/tests/locator-count.spec.js.map +7 -0
  155. package/dist/cjs/lib/v3/tests/locator-fill.spec.js +118 -0
  156. package/dist/cjs/lib/v3/tests/locator-fill.spec.js.map +7 -0
  157. package/dist/cjs/lib/v3/tests/locator-input-methods.spec.js +136 -0
  158. package/dist/cjs/lib/v3/tests/locator-input-methods.spec.js.map +7 -0
  159. package/dist/cjs/lib/v3/tests/locator-nth.spec.js +157 -0
  160. package/dist/cjs/lib/v3/tests/locator-nth.spec.js.map +7 -0
  161. package/dist/cjs/lib/v3/tests/locator-select-option.spec.js +242 -0
  162. package/dist/cjs/lib/v3/tests/locator-select-option.spec.js.map +7 -0
  163. package/dist/cjs/lib/v3/tests/logger-initialization.spec.js +547 -0
  164. package/dist/cjs/lib/v3/tests/logger-initialization.spec.js.map +7 -0
  165. package/dist/cjs/lib/v3/tests/multi-instance-logger.spec.js +269 -0
  166. package/dist/cjs/lib/v3/tests/multi-instance-logger.spec.js.map +7 -0
  167. package/dist/cjs/lib/v3/tests/nested-div.spec.js +23 -0
  168. package/dist/cjs/lib/v3/tests/nested-div.spec.js.map +7 -0
  169. package/dist/cjs/lib/v3/tests/page-addInitScript.spec.js +90 -0
  170. package/dist/cjs/lib/v3/tests/page-addInitScript.spec.js.map +7 -0
  171. package/dist/cjs/lib/v3/tests/page-console.spec.js +56 -0
  172. package/dist/cjs/lib/v3/tests/page-console.spec.js.map +7 -0
  173. package/dist/cjs/lib/v3/tests/page-drag-and-drop.spec.js +418 -0
  174. package/dist/cjs/lib/v3/tests/page-drag-and-drop.spec.js.map +7 -0
  175. package/dist/cjs/lib/v3/tests/page-goto-response.spec.js +35 -0
  176. package/dist/cjs/lib/v3/tests/page-goto-response.spec.js.map +7 -0
  177. package/dist/cjs/lib/v3/tests/page-hover.spec.js +167 -0
  178. package/dist/cjs/lib/v3/tests/page-hover.spec.js.map +7 -0
  179. package/dist/cjs/lib/v3/tests/page-screenshot.spec.js +295 -0
  180. package/dist/cjs/lib/v3/tests/page-screenshot.spec.js.map +7 -0
  181. package/dist/cjs/lib/v3/tests/page-scroll.spec.js +182 -0
  182. package/dist/cjs/lib/v3/tests/page-scroll.spec.js.map +7 -0
  183. package/dist/cjs/lib/v3/tests/page-send-cdp.spec.js +46 -0
  184. package/dist/cjs/lib/v3/tests/page-send-cdp.spec.js.map +7 -0
  185. package/dist/cjs/lib/v3/tests/perform-understudy-method.spec.js +98 -0
  186. package/dist/cjs/lib/v3/tests/perform-understudy-method.spec.js.map +7 -0
  187. package/dist/cjs/lib/v3/tests/setinputfiles.spec.js +148 -0
  188. package/dist/cjs/lib/v3/tests/setinputfiles.spec.js.map +7 -0
  189. package/dist/cjs/lib/v3/tests/shadow-iframe-oopif.spec.js +156 -0
  190. package/dist/cjs/lib/v3/tests/shadow-iframe-oopif.spec.js.map +7 -0
  191. package/dist/cjs/lib/v3/tests/shadow-iframe-spif.spec.js +156 -0
  192. package/dist/cjs/lib/v3/tests/shadow-iframe-spif.spec.js.map +7 -0
  193. package/dist/cjs/lib/v3/tests/testUtils.js +54 -0
  194. package/dist/cjs/lib/v3/tests/testUtils.js.map +7 -0
  195. package/dist/cjs/lib/v3/tests/text-selector-innermost.spec.js +100 -0
  196. package/dist/cjs/lib/v3/tests/text-selector-innermost.spec.js.map +7 -0
  197. package/dist/cjs/lib/v3/tests/timeouts.spec.js +32 -0
  198. package/dist/cjs/lib/v3/tests/timeouts.spec.js.map +7 -0
  199. package/dist/cjs/lib/v3/tests/user-data-dir.spec.js +65 -0
  200. package/dist/cjs/lib/v3/tests/user-data-dir.spec.js.map +7 -0
  201. package/dist/cjs/lib/v3/tests/v3.config.js +36 -0
  202. package/dist/cjs/lib/v3/tests/v3.config.js.map +7 -0
  203. package/dist/cjs/lib/v3/tests/v3.dynamic.config.js +67 -0
  204. package/dist/cjs/lib/v3/tests/v3.dynamic.config.js.map +7 -0
  205. package/dist/cjs/lib/v3/tests/v3.playwright.config.js +61 -0
  206. package/dist/cjs/lib/v3/tests/v3.playwright.config.js.map +7 -0
  207. package/dist/cjs/lib/v3/tests/wait-for-selector.spec.js +593 -0
  208. package/dist/cjs/lib/v3/tests/wait-for-selector.spec.js.map +7 -0
  209. package/dist/cjs/lib/v3/tests/wait-for-timeout.spec.js +97 -0
  210. package/dist/cjs/lib/v3/tests/wait-for-timeout.spec.js.map +7 -0
  211. package/dist/cjs/lib/v3/tests/xpath-for-location-deep.spec.js +77 -0
  212. package/dist/cjs/lib/v3/tests/xpath-for-location-deep.spec.js.map +7 -0
  213. package/dist/cjs/lib/v3/timeoutConfig.d.ts +2 -0
  214. package/dist/cjs/lib/v3/types/private/agent.d.ts +6 -0
  215. package/dist/cjs/lib/v3/types/private/api.d.ts +11 -0
  216. package/dist/cjs/lib/v3/types/private/cache.d.ts +128 -0
  217. package/dist/cjs/lib/v3/types/private/evaluator.d.ts +40 -0
  218. package/dist/cjs/lib/v3/types/private/handlers.d.ts +38 -0
  219. package/dist/cjs/lib/v3/types/private/index.d.ts +7 -0
  220. package/dist/cjs/lib/v3/types/private/internal.d.ts +39 -0
  221. package/dist/cjs/lib/v3/types/private/locator.d.ts +9 -0
  222. package/dist/cjs/lib/v3/types/private/network.d.ts +34 -0
  223. package/dist/cjs/lib/v3/types/private/shutdown.d.ts +19 -0
  224. package/dist/cjs/lib/v3/types/private/shutdownErrors.d.ts +12 -0
  225. package/dist/cjs/lib/v3/types/private/snapshot.d.ts +117 -0
  226. package/dist/cjs/lib/v3/types/public/agent.d.ts +595 -0
  227. package/dist/cjs/lib/v3/types/public/api.d.ts +1211 -0
  228. package/dist/cjs/lib/v3/types/public/apiErrors.d.ts +18 -0
  229. package/dist/cjs/lib/v3/types/public/index.d.ts +12 -0
  230. package/dist/cjs/lib/v3/types/public/locator.d.ts +9 -0
  231. package/dist/cjs/lib/v3/types/public/logs.d.ts +23 -0
  232. package/dist/cjs/lib/v3/types/public/methods.d.ts +56 -0
  233. package/dist/cjs/lib/v3/types/public/metrics.d.ts +27 -0
  234. package/dist/cjs/lib/v3/types/public/model.d.ts +65 -0
  235. package/dist/cjs/lib/v3/types/public/options.d.ts +70 -0
  236. package/dist/cjs/lib/v3/types/public/page.d.ts +18 -0
  237. package/dist/cjs/lib/v3/types/public/screenshotTypes.d.ts +25 -0
  238. package/dist/cjs/lib/v3/types/public/sdkErrors.d.ts +152 -0
  239. package/dist/cjs/lib/v3/understudy/a11y/snapshot/a11yTree.d.ts +15 -0
  240. package/dist/cjs/lib/v3/understudy/a11y/snapshot/activeElement.d.ts +8 -0
  241. package/dist/cjs/lib/v3/understudy/a11y/snapshot/capture.d.ts +77 -0
  242. package/dist/cjs/lib/v3/understudy/a11y/snapshot/coordinateResolver.d.ts +7 -0
  243. package/dist/cjs/lib/v3/understudy/a11y/snapshot/domTree.d.ts +46 -0
  244. package/dist/cjs/lib/v3/understudy/a11y/snapshot/focusSelectors.d.ts +24 -0
  245. package/dist/cjs/lib/v3/understudy/a11y/snapshot/index.d.ts +4 -0
  246. package/dist/cjs/lib/v3/understudy/a11y/snapshot/sessions.d.ts +16 -0
  247. package/dist/cjs/lib/v3/understudy/a11y/snapshot/treeFormatUtils.d.ts +28 -0
  248. package/dist/cjs/lib/v3/understudy/a11y/snapshot/xpathUtils.d.ts +26 -0
  249. package/dist/cjs/lib/v3/understudy/a11yInvocation.d.ts +8 -0
  250. package/dist/cjs/lib/v3/understudy/cdp.d.ts +69 -0
  251. package/dist/cjs/lib/v3/understudy/consoleMessage.d.ts +22 -0
  252. package/dist/cjs/lib/v3/understudy/context.d.ts +132 -0
  253. package/dist/cjs/lib/v3/understudy/deepLocator.d.ts +87 -0
  254. package/dist/cjs/lib/v3/understudy/executionContextRegistry.d.ts +15 -0
  255. package/dist/cjs/lib/v3/understudy/fileUploadUtils.d.ts +13 -0
  256. package/dist/cjs/lib/v3/understudy/frame.d.ts +69 -0
  257. package/dist/cjs/lib/v3/understudy/frameLocator.d.ts +50 -0
  258. package/dist/cjs/lib/v3/understudy/frameRegistry.d.ts +101 -0
  259. package/dist/cjs/lib/v3/understudy/initScripts.d.ts +2 -0
  260. package/dist/cjs/lib/v3/understudy/lifecycleWatcher.d.ts +64 -0
  261. package/dist/cjs/lib/v3/understudy/locator.d.ts +194 -0
  262. package/dist/cjs/lib/v3/understudy/locatorInvocation.d.ts +8 -0
  263. package/dist/cjs/lib/v3/understudy/navigationResponseTracker.d.ts +84 -0
  264. package/dist/cjs/lib/v3/understudy/networkManager.d.ts +53 -0
  265. package/dist/cjs/lib/v3/understudy/page.d.ts +354 -0
  266. package/dist/cjs/lib/v3/understudy/piercer.d.ts +4 -0
  267. package/dist/cjs/lib/v3/understudy/response.d.ts +137 -0
  268. package/dist/cjs/lib/v3/understudy/screenshotUtils.d.ts +16 -0
  269. package/dist/cjs/lib/v3/understudy/selectorResolver.d.ts +38 -0
  270. package/dist/cjs/lib/v3/v3.d.ts +191 -0
  271. package/dist/cjs/lib/v3/zodCompat.d.ts +12 -0
  272. package/dist/cjs/lib/v3Evaluator.d.ts +19 -0
  273. package/dist/cjs/lib/version.d.ts +5 -0
  274. package/dist/cjs/package.json +3 -0
  275. package/dist/cjs/tests/browserbase-session-accessors.test.js +101 -0
  276. package/dist/cjs/tests/browserbase-session-accessors.test.js.map +7 -0
  277. package/dist/cjs/tests/cache-llm-resolution.test.js +187 -0
  278. package/dist/cjs/tests/cache-llm-resolution.test.js.map +7 -0
  279. package/dist/cjs/tests/helpers/mockCDPSession.js +50 -0
  280. package/dist/cjs/tests/helpers/mockCDPSession.js.map +7 -0
  281. package/dist/cjs/tests/llm-provider.test.js +57 -0
  282. package/dist/cjs/tests/llm-provider.test.js.map +7 -0
  283. package/dist/cjs/tests/model-deprecation.test.js +132 -0
  284. package/dist/cjs/tests/model-deprecation.test.js.map +7 -0
  285. package/dist/cjs/tests/page-snapshot.test.js +58 -0
  286. package/dist/cjs/tests/page-snapshot.test.js.map +7 -0
  287. package/dist/cjs/tests/public-api/export-surface.test.js +76 -0
  288. package/dist/cjs/tests/public-api/export-surface.test.js.map +7 -0
  289. package/dist/cjs/tests/public-api/llm-and-agents.test.js +150 -0
  290. package/dist/cjs/tests/public-api/llm-and-agents.test.js.map +7 -0
  291. package/dist/cjs/tests/public-api/public-error-types.test.js +104 -0
  292. package/dist/cjs/tests/public-api/public-error-types.test.js.map +7 -0
  293. package/dist/cjs/tests/public-api/public-types.test.js +74 -0
  294. package/dist/cjs/tests/public-api/public-types.test.js.map +7 -0
  295. package/dist/cjs/tests/public-api/runtime-utils.test.js +53 -0
  296. package/dist/cjs/tests/public-api/runtime-utils.test.js.map +7 -0
  297. package/dist/cjs/tests/public-api/schema-utils.test.js +100 -0
  298. package/dist/cjs/tests/public-api/schema-utils.test.js.map +7 -0
  299. package/dist/cjs/tests/public-api/timeout-error-types.test.js +103 -0
  300. package/dist/cjs/tests/public-api/timeout-error-types.test.js.map +7 -0
  301. package/dist/cjs/tests/public-api/tool-type-export.test.js +47 -0
  302. package/dist/cjs/tests/public-api/tool-type-export.test.js.map +7 -0
  303. package/dist/cjs/tests/public-api/v3-core.test.js +104 -0
  304. package/dist/cjs/tests/public-api/v3-core.test.js.map +7 -0
  305. package/dist/cjs/tests/safety-confirmation.test.js +134 -0
  306. package/dist/cjs/tests/safety-confirmation.test.js.map +7 -0
  307. package/dist/cjs/tests/snapshot-a11y-resolvers.test.js +370 -0
  308. package/dist/cjs/tests/snapshot-a11y-resolvers.test.js.map +7 -0
  309. package/dist/cjs/tests/snapshot-a11y-tree-utils.test.js +294 -0
  310. package/dist/cjs/tests/snapshot-a11y-tree-utils.test.js.map +7 -0
  311. package/dist/cjs/tests/snapshot-capture-orchestration.test.js +403 -0
  312. package/dist/cjs/tests/snapshot-capture-orchestration.test.js.map +7 -0
  313. package/dist/cjs/tests/snapshot-cbor.test.js +197 -0
  314. package/dist/cjs/tests/snapshot-cbor.test.js.map +7 -0
  315. package/dist/cjs/tests/snapshot-dom-session-builders.test.js +246 -0
  316. package/dist/cjs/tests/snapshot-dom-session-builders.test.js.map +7 -0
  317. package/dist/cjs/tests/snapshot-dom-tree-utils.test.js +104 -0
  318. package/dist/cjs/tests/snapshot-dom-tree-utils.test.js.map +7 -0
  319. package/dist/cjs/tests/snapshot-focus-selectors-utils.test.js +45 -0
  320. package/dist/cjs/tests/snapshot-focus-selectors-utils.test.js.map +7 -0
  321. package/dist/cjs/tests/snapshot-frame-merge.test.js +388 -0
  322. package/dist/cjs/tests/snapshot-frame-merge.test.js.map +7 -0
  323. package/dist/cjs/tests/snapshot-tree-format-utils.test.js +106 -0
  324. package/dist/cjs/tests/snapshot-tree-format-utils.test.js.map +7 -0
  325. package/dist/cjs/tests/snapshot-xpath-utils.test.js +74 -0
  326. package/dist/cjs/tests/snapshot-xpath-utils.test.js.map +7 -0
  327. package/dist/cjs/tests/timeout-handlers.test.js +864 -0
  328. package/dist/cjs/tests/timeout-handlers.test.js.map +7 -0
  329. package/dist/cjs/tests/xpath-parser.test.js +314 -0
  330. package/dist/cjs/tests/xpath-parser.test.js.map +7 -0
  331. package/dist/cjs/tests/xpath-resolver.test.js +70 -0
  332. package/dist/cjs/tests/xpath-resolver.test.js.map +7 -0
  333. package/dist/cjs/tests/zod-enum-compatibility.test.js +119 -0
  334. package/dist/cjs/tests/zod-enum-compatibility.test.js.map +7 -0
  335. package/dist/esm/lib/modelUtils.d.ts +0 -3
  336. package/dist/esm/lib/modelUtils.js +2 -7
  337. package/dist/esm/lib/modelUtils.js.map +1 -1
  338. package/dist/esm/lib/v3/agent/tools/act.d.ts +1 -2
  339. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  340. package/dist/esm/lib/v3/agent/tools/extract.d.ts +1 -2
  341. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  342. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +1 -2
  343. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  344. package/dist/esm/lib/v3/agent/tools/index.d.ts +2 -2
  345. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  346. package/dist/esm/lib/v3/cli.d.ts +2 -0
  347. package/dist/esm/lib/v3/cli.js +10 -0
  348. package/dist/esm/lib/v3/cli.js.map +1 -0
  349. package/dist/esm/lib/v3/dom/build/rerender-index.d.ts +0 -0
  350. package/dist/esm/lib/v3/dom/build/rerender-index.js.map +1 -0
  351. package/dist/esm/lib/v3/dom/build/v3-index.d.ts +0 -0
  352. package/dist/esm/lib/v3/dom/build/v3-index.js.map +1 -0
  353. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -2
  354. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  355. package/dist/esm/lib/v3/index.d.ts +1 -0
  356. package/dist/esm/lib/v3/index.js +1 -0
  357. package/dist/esm/lib/v3/index.js.map +1 -1
  358. package/dist/esm/lib/v3/shutdown/supervisor.d.ts +7 -5
  359. package/dist/esm/lib/v3/shutdown/supervisor.js +62 -52
  360. package/dist/esm/lib/v3/shutdown/supervisor.js.map +1 -1
  361. package/dist/esm/lib/v3/shutdown/supervisorClient.js +48 -52
  362. package/dist/esm/lib/v3/shutdown/supervisorClient.js.map +1 -1
  363. package/dist/esm/lib/v3/tests/click-count.spec.js +47 -12
  364. package/dist/esm/lib/v3/tests/click-count.spec.js.map +2 -2
  365. package/dist/esm/lib/v3/tests/iframe-ctx-addInitScript.spec.js +67 -21
  366. package/dist/esm/lib/v3/tests/iframe-ctx-addInitScript.spec.js.map +2 -2
  367. package/dist/esm/lib/v3/tests/v3.playwright.config.js +3 -60
  368. package/dist/esm/lib/v3/tests/v3.playwright.config.js.map +2 -2
  369. package/dist/esm/lib/v3/types/private/shutdown.d.ts +1 -13
  370. package/dist/esm/lib/v3/types/private/shutdown.js.map +1 -1
  371. package/dist/esm/lib/v3/understudy/context.js +10 -1
  372. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  373. package/dist/esm/lib/v3/understudy/locator.js +2 -2
  374. package/dist/esm/lib/v3/understudy/locator.js.map +1 -1
  375. package/dist/esm/lib/v3/understudy/page.js +2 -1
  376. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  377. package/dist/esm/lib/v3/v3.js +10 -13
  378. package/dist/esm/lib/v3/v3.js.map +1 -1
  379. package/dist/esm/tests/public-api/export-surface.test.js +1 -0
  380. package/dist/esm/tests/public-api/export-surface.test.js.map +2 -2
  381. package/package.json +13 -9
  382. package/dist/esm/lib/v3/tests/envReporter.js +0 -57
  383. package/dist/esm/lib/v3/tests/envReporter.js.map +0 -7
  384. package/dist/esm/tests/agent-execution-model.test.js +0 -139
  385. package/dist/esm/tests/agent-execution-model.test.js.map +0 -7
  386. package/dist/esm/tests/model-utils.test.js +0 -43
  387. package/dist/esm/tests/model-utils.test.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../lib/v3/tests/click-count.spec.ts"],
4
- "sourcesContent": ["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\n\ntest.describe(\"Locator and Page click methods\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3TestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"locator.click() performs single click by default\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial count\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Perform single click on the textarea (the clickable area)\n const clickArea = page.locator(\"#textarea\");\n await clickArea.click();\n\n // Verify count incremented by 1\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"1\");\n });\n\n test(\"locator.click() with clickCount: 2 performs double-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial counts\n const countDisplay = page.locator(\"#count\");\n const dcCountDisplay = page.locator(\"#dcCount\");\n\n const initialCount = await countDisplay.inputValue();\n const initialDcCount = await dcCountDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n expect(initialDcCount).toBe(\"0\");\n\n // Perform double-click on the textarea\n const clickArea = page.locator(\"#textarea\");\n await clickArea.click({ clickCount: 2 });\n\n // Verify both counters incremented\n // Regular count should be 2 (one for each click in the double-click)\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"2\");\n\n // Double-click count should be 1 (one double-click event detected)\n const newDcCount = await dcCountDisplay.inputValue();\n expect(newDcCount).toBe(\"1\");\n });\n\n test(\"locator.click() with clickCount: 3 performs triple-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Perform triple-click on the textarea\n const clickArea = page.locator(\"#textarea\");\n await clickArea.click({ clickCount: 3 });\n\n // Verify count incremented by 3\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"3\");\n });\n\n test(\"page.click() performs single click with coordinates\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial count\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Get the centroid of the textarea to click\n const clickArea = page.locator(\"#textarea\");\n const { x, y } = await clickArea.centroid();\n\n // Perform single click using page.click() with coordinates\n await page.click(x, y);\n\n // Verify count incremented by 1\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"1\");\n });\n\n test(\"page.click() with clickCount: 2 performs double-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial counts\n const countDisplay = page.locator(\"#count\");\n const dcCountDisplay = page.locator(\"#dcCount\");\n\n const initialCount = await countDisplay.inputValue();\n const initialDcCount = await dcCountDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n expect(initialDcCount).toBe(\"0\");\n\n // Get the centroid of the textarea to click\n const clickArea = page.locator(\"#textarea\");\n const { x, y } = await clickArea.centroid();\n\n // Perform double-click using page.click() with coordinates\n await page.click(x, y, { clickCount: 2 });\n\n // Verify both counters incremented\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"2\");\n\n // Double-click count should be 1\n const newDcCount = await dcCountDisplay.inputValue();\n expect(newDcCount).toBe(\"1\");\n });\n\n test(\"page.click() with clickCount: 3 performs triple-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Get the centroid of the textarea to click\n const clickArea = page.locator(\"#textarea\");\n const { x, y } = await clickArea.centroid();\n\n // Perform triple-click using page.click() with coordinates\n await page.click(x, y, { clickCount: 3 });\n\n // Verify count incremented by 3\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"3\");\n });\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\n\n// Keep double-click verification event-based and deterministic.\n// Time-delta counters (Date.now() between mousedowns) are flaky at ms boundaries\n// and can miss valid double-clicks when synthetic input lands in the same millisecond.\nconst doubleClickFixtureUrl = `data:text/html,${encodeURIComponent(`<!DOCTYPE html>\n<html>\n <body>\n <div id=\"target\" style=\"width: 240px; height: 120px; border: 1px solid #000;\">target</div>\n <input id=\"clickCount\" value=\"0\" readonly />\n <input id=\"dblClickCount\" value=\"0\" readonly />\n <input id=\"lastClickDetail\" value=\"0\" readonly />\n <input id=\"lastDblClickDetail\" value=\"0\" readonly />\n <script>\n const target = document.getElementById(\"target\");\n const clickCount = document.getElementById(\"clickCount\");\n const dblClickCount = document.getElementById(\"dblClickCount\");\n const lastClickDetail = document.getElementById(\"lastClickDetail\");\n const lastDblClickDetail = document.getElementById(\"lastDblClickDetail\");\n let clicks = 0;\n let dblClicks = 0;\n\n target.addEventListener(\"click\", (event) => {\n clicks += 1;\n clickCount.value = String(clicks);\n lastClickDetail.value = String(event.detail);\n });\n\n target.addEventListener(\"dblclick\", (event) => {\n dblClicks += 1;\n dblClickCount.value = String(dblClicks);\n lastDblClickDetail.value = String(event.detail);\n });\n </script>\n </body>\n</html>`)}`;\n\ntest.describe(\"Locator and Page click methods\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3TestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"locator.click() performs single click by default\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial count\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Perform single click on the textarea (the clickable area)\n const clickArea = page.locator(\"#textarea\");\n await clickArea.click();\n\n // Verify count incremented by 1\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"1\");\n });\n\n test(\"locator.click() with clickCount: 2 performs double-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(doubleClickFixtureUrl);\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#clickCount\");\n const dcCountDisplay = page.locator(\"#dblClickCount\");\n const clickDetailDisplay = page.locator(\"#lastClickDetail\");\n const dblClickDetailDisplay = page.locator(\"#lastDblClickDetail\");\n\n const initialCount = await countDisplay.inputValue();\n const initialDcCount = await dcCountDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n expect(initialDcCount).toBe(\"0\");\n\n const clickArea = page.locator(\"#target\");\n await clickArea.click({ clickCount: 2 });\n\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"2\");\n\n const newDcCount = await dcCountDisplay.inputValue();\n expect(newDcCount).toBe(\"1\");\n // `dblclick` is the browser-level contract for double-click behavior.\n // Verifying `detail=2` ensures the click sequence is recognized as a true multi-click.\n expect(await clickDetailDisplay.inputValue()).toBe(\"2\");\n expect(await dblClickDetailDisplay.inputValue()).toBe(\"2\");\n });\n\n test(\"locator.click() with clickCount: 3 performs triple-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Perform triple-click on the textarea\n const clickArea = page.locator(\"#textarea\");\n await clickArea.click({ clickCount: 3 });\n\n // Verify count incremented by 3\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"3\");\n });\n\n test(\"page.click() performs single click with coordinates\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n // Get initial count\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Get the centroid of the textarea to click\n const clickArea = page.locator(\"#textarea\");\n const { x, y } = await clickArea.centroid();\n\n // Perform single click using page.click() with coordinates\n await page.click(x, y);\n\n // Verify count incremented by 1\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"1\");\n });\n\n test(\"page.click() with clickCount: 2 performs double-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(doubleClickFixtureUrl);\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#clickCount\");\n const dcCountDisplay = page.locator(\"#dblClickCount\");\n const clickDetailDisplay = page.locator(\"#lastClickDetail\");\n const dblClickDetailDisplay = page.locator(\"#lastDblClickDetail\");\n\n const initialCount = await countDisplay.inputValue();\n const initialDcCount = await dcCountDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n expect(initialDcCount).toBe(\"0\");\n\n const clickArea = page.locator(\"#target\");\n const { x, y } = await clickArea.centroid();\n\n await page.click(x, y, { clickCount: 2 });\n\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"2\");\n\n const newDcCount = await dcCountDisplay.inputValue();\n expect(newDcCount).toBe(\"1\");\n // `dblclick` is the browser-level contract for double-click behavior.\n // Verifying `detail=2` ensures the click sequence is recognized as a true multi-click.\n expect(await clickDetailDisplay.inputValue()).toBe(\"2\");\n expect(await dblClickDetailDisplay.inputValue()).toBe(\"2\");\n });\n\n test(\"page.click() with clickCount: 3 performs triple-click\", async () => {\n const page = v3.context.pages()[0];\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/click-test/\",\n );\n\n // Wait for page to be fully loaded\n await page.waitForLoadState(\"domcontentloaded\");\n\n const countDisplay = page.locator(\"#count\");\n const initialCount = await countDisplay.inputValue();\n expect(initialCount).toBe(\"0\");\n\n // Get the centroid of the textarea to click\n const clickArea = page.locator(\"#textarea\");\n const { x, y } = await clickArea.centroid();\n\n // Perform triple-click using page.click() with coordinates\n await page.click(x, y, { clickCount: 3 });\n\n // Verify count incremented by 3\n const newCount = await countDisplay.inputValue();\n expect(newCount).toBe(\"3\");\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,MAAM,cAAc;AAC7B,SAAS,UAAU;AACnB,SAAS,oBAAoB;AAK7B,MAAM,wBAAwB,kBAAkB,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QA8B3D,CAAC;AAET,KAAK,SAAS,kCAAkC,MAAM;AACpD,MAAI;AAEJ,OAAK,WAAW,YAAY;AAC1B,SAAK,IAAI,GAAG,YAAY;AACxB,UAAM,GAAG,KAAK;AAAA,EAChB,CAAC;AAED,OAAK,UAAU,YAAY;AACzB,UAAM,IAAI,QAAQ,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACpC,CAAC;AAED,OAAK,oDAAoD,YAAY;AACnE,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK;AAAA,MACT;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,kBAAkB;AAG9C,UAAM,eAAe,KAAK,QAAQ,QAAQ;AAC1C,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,WAAO,YAAY,EAAE,KAAK,GAAG;AAG7B,UAAM,YAAY,KAAK,QAAQ,WAAW;AAC1C,UAAM,UAAU,MAAM;AAGtB,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAAA,EAC3B,CAAC;AAED,OAAK,4DAA4D,YAAY;AAC3E,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK,KAAK,qBAAqB;AACrC,UAAM,KAAK,iBAAiB,kBAAkB;AAE9C,UAAM,eAAe,KAAK,QAAQ,aAAa;AAC/C,UAAM,iBAAiB,KAAK,QAAQ,gBAAgB;AACpD,UAAM,qBAAqB,KAAK,QAAQ,kBAAkB;AAC1D,UAAM,wBAAwB,KAAK,QAAQ,qBAAqB;AAEhE,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,UAAM,iBAAiB,MAAM,eAAe,WAAW;AACvD,WAAO,YAAY,EAAE,KAAK,GAAG;AAC7B,WAAO,cAAc,EAAE,KAAK,GAAG;AAE/B,UAAM,YAAY,KAAK,QAAQ,SAAS;AACxC,UAAM,UAAU,MAAM,EAAE,YAAY,EAAE,CAAC;AAEvC,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAEzB,UAAM,aAAa,MAAM,eAAe,WAAW;AACnD,WAAO,UAAU,EAAE,KAAK,GAAG;AAG3B,WAAO,MAAM,mBAAmB,WAAW,CAAC,EAAE,KAAK,GAAG;AACtD,WAAO,MAAM,sBAAsB,WAAW,CAAC,EAAE,KAAK,GAAG;AAAA,EAC3D,CAAC;AAED,OAAK,4DAA4D,YAAY;AAC3E,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK;AAAA,MACT;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,kBAAkB;AAE9C,UAAM,eAAe,KAAK,QAAQ,QAAQ;AAC1C,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,WAAO,YAAY,EAAE,KAAK,GAAG;AAG7B,UAAM,YAAY,KAAK,QAAQ,WAAW;AAC1C,UAAM,UAAU,MAAM,EAAE,YAAY,EAAE,CAAC;AAGvC,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAAA,EAC3B,CAAC;AAED,OAAK,uDAAuD,YAAY;AACtE,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK;AAAA,MACT;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,kBAAkB;AAG9C,UAAM,eAAe,KAAK,QAAQ,QAAQ;AAC1C,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,WAAO,YAAY,EAAE,KAAK,GAAG;AAG7B,UAAM,YAAY,KAAK,QAAQ,WAAW;AAC1C,UAAM,EAAE,GAAG,EAAE,IAAI,MAAM,UAAU,SAAS;AAG1C,UAAM,KAAK,MAAM,GAAG,CAAC;AAGrB,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAAA,EAC3B,CAAC;AAED,OAAK,yDAAyD,YAAY;AACxE,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK,KAAK,qBAAqB;AACrC,UAAM,KAAK,iBAAiB,kBAAkB;AAE9C,UAAM,eAAe,KAAK,QAAQ,aAAa;AAC/C,UAAM,iBAAiB,KAAK,QAAQ,gBAAgB;AACpD,UAAM,qBAAqB,KAAK,QAAQ,kBAAkB;AAC1D,UAAM,wBAAwB,KAAK,QAAQ,qBAAqB;AAEhE,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,UAAM,iBAAiB,MAAM,eAAe,WAAW;AACvD,WAAO,YAAY,EAAE,KAAK,GAAG;AAC7B,WAAO,cAAc,EAAE,KAAK,GAAG;AAE/B,UAAM,YAAY,KAAK,QAAQ,SAAS;AACxC,UAAM,EAAE,GAAG,EAAE,IAAI,MAAM,UAAU,SAAS;AAE1C,UAAM,KAAK,MAAM,GAAG,GAAG,EAAE,YAAY,EAAE,CAAC;AAExC,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAEzB,UAAM,aAAa,MAAM,eAAe,WAAW;AACnD,WAAO,UAAU,EAAE,KAAK,GAAG;AAG3B,WAAO,MAAM,mBAAmB,WAAW,CAAC,EAAE,KAAK,GAAG;AACtD,WAAO,MAAM,sBAAsB,WAAW,CAAC,EAAE,KAAK,GAAG;AAAA,EAC3D,CAAC;AAED,OAAK,yDAAyD,YAAY;AACxE,UAAM,OAAO,GAAG,QAAQ,MAAM,EAAE,CAAC;AACjC,UAAM,KAAK;AAAA,MACT;AAAA,IACF;AAGA,UAAM,KAAK,iBAAiB,kBAAkB;AAE9C,UAAM,eAAe,KAAK,QAAQ,QAAQ;AAC1C,UAAM,eAAe,MAAM,aAAa,WAAW;AACnD,WAAO,YAAY,EAAE,KAAK,GAAG;AAG7B,UAAM,YAAY,KAAK,QAAQ,WAAW;AAC1C,UAAM,EAAE,GAAG,EAAE,IAAI,MAAM,UAAU,SAAS;AAG1C,UAAM,KAAK,MAAM,GAAG,GAAG,EAAE,YAAY,EAAE,CAAC;AAGxC,UAAM,WAAW,MAAM,aAAa,WAAW;AAC/C,WAAO,QAAQ,EAAE,KAAK,GAAG;AAAA,EAC3B,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -132,10 +132,11 @@ async function closeAllPages(ctx) {
132
132
  const pages = ctx.pages();
133
133
  await Promise.allSettled(pages.map((page) => page.close()));
134
134
  }
135
- async function waitForChildFrame(page, timeoutMs = CHILD_FRAME_TIMEOUT_MS) {
135
+ async function waitForChildFrame(page, expectedChildUrl, timeoutMs = CHILD_FRAME_TIMEOUT_MS) {
136
136
  const mainFrameId = page.mainFrame().frameId;
137
137
  const deadline = Date.now() + timeoutMs;
138
138
  let observedFrameCount = 0;
139
+ const observedChildFrameIds = /* @__PURE__ */ new Set();
139
140
  let lastUrl = "";
140
141
  let lastLogAt = Date.now();
141
142
  while (Date.now() < deadline) {
@@ -148,29 +149,71 @@ async function waitForChildFrame(page, timeoutMs = CHILD_FRAME_TIMEOUT_MS) {
148
149
  url: lastUrl,
149
150
  mainFrameId,
150
151
  observedFrameCount,
151
- childIds
152
+ childIds,
153
+ expectedChildUrl
152
154
  });
153
155
  lastLogAt = Date.now();
154
156
  }
155
- const child = frames.find((f) => f.frameId !== mainFrameId);
156
- if (child) {
157
- try {
158
- const ready = await child.evaluate(() => document.readyState);
159
- if (ready === "complete") {
160
- debugLog("waitForChildFrame:ready", {
161
- childFrameId: child.frameId,
162
- url: lastUrl
163
- });
164
- return child;
165
- }
166
- } catch {
157
+ for (const childId of childIds) observedChildFrameIds.add(childId);
158
+ const childFrames = frames.filter((f) => f.frameId !== mainFrameId).reverse();
159
+ if (childFrames.length) {
160
+ const probes = await Promise.all(
161
+ childFrames.map(async (child) => {
162
+ try {
163
+ const state = await child.evaluate(() => ({
164
+ href: location.href,
165
+ readyState: document.readyState
166
+ }));
167
+ return {
168
+ child,
169
+ href: state.href,
170
+ readyState: state.readyState,
171
+ error: void 0
172
+ };
173
+ } catch (error) {
174
+ return {
175
+ child,
176
+ href: void 0,
177
+ readyState: void 0,
178
+ error: formatError(error)
179
+ };
180
+ }
181
+ })
182
+ );
183
+ const ready = probes.find(
184
+ (probe) => probe.readyState === "complete" && probe.href === expectedChildUrl
185
+ );
186
+ if (ready) {
187
+ debugLog("waitForChildFrame:ready", {
188
+ childFrameId: ready.child.frameId,
189
+ childSessionId: ready.child.sessionId ?? "root",
190
+ childUrl: ready.href ?? "<unknown>",
191
+ expectedChildUrl,
192
+ url: lastUrl
193
+ });
194
+ return ready.child;
195
+ }
196
+ if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {
197
+ debugLog("waitForChildFrame:not-ready", {
198
+ url: lastUrl,
199
+ mainFrameId,
200
+ expectedChildUrl,
201
+ probes: probes.map((probe) => ({
202
+ frameId: probe.child.frameId,
203
+ sessionId: probe.child.sessionId ?? "root",
204
+ readyState: probe.readyState ?? "<unknown>",
205
+ href: probe.href ?? "<unknown>",
206
+ error: probe.error ?? "<none>"
207
+ }))
208
+ });
209
+ lastLogAt = Date.now();
167
210
  }
168
211
  }
169
212
  await new Promise((r) => setTimeout(r, 100));
170
213
  }
171
214
  await logPageDiagnostics(page, "waitForChildFrame timeout");
172
215
  throw new Error(
173
- `Timed out waiting for child frame to load (timeout=${timeoutMs}ms, mainFrameId=${mainFrameId}, maxObservedFrames=${observedFrameCount}, url=${lastUrl || "<unknown>"})`
216
+ `Timed out waiting for child frame to load (timeout=${timeoutMs}ms, mainFrameId=${mainFrameId}, expectedChildUrl=${expectedChildUrl}, maxObservedFrames=${observedFrameCount}, observedChildFrameIds=[${[...observedChildFrameIds].join(",")}], url=${lastUrl || "<unknown>"})`
174
217
  );
175
218
  }
176
219
  async function waitForPageUrl(page, expectedUrlSubstring, timeoutMs = POPUP_URL_TIMEOUT_MS) {
@@ -278,6 +321,9 @@ async function waitForPopupPage(ctx, opener, timeoutMs = POPUP_TIMEOUT_MS) {
278
321
  );
279
322
  }
280
323
  test.describe("context.addInitScript with iframes", () => {
324
+ const OOPIF_CHILD_URL = "https://seanmcguire12.github.io/stagehand-oopif-sites/sites/form-filling/";
325
+ const SPIF_CHILD_URL = "https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/iframe.html";
326
+ const POPUP_SPIF_CHILD_URL = "https://browserbase.github.io/stagehand-eval-sites/sites/closed-shadow-dom-in-spif/embedded.html";
281
327
  if (isBrowserbase) {
282
328
  test.describe.configure({ mode: "serial" });
283
329
  }
@@ -318,7 +364,7 @@ test.describe("context.addInitScript with iframes", () => {
318
364
  "https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/",
319
365
  { waitUntil: "networkidle" }
320
366
  );
321
- const iframe = await waitForChildFrame(page);
367
+ const iframe = await waitForChildFrame(page, OOPIF_CHILD_URL);
322
368
  const mainBgColor = await page.mainFrame().evaluate(() => {
323
369
  return getComputedStyle(document.documentElement).backgroundColor;
324
370
  });
@@ -334,7 +380,7 @@ test.describe("context.addInitScript with iframes", () => {
334
380
  "https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/",
335
381
  { waitUntil: "networkidle" }
336
382
  );
337
- const iframe = await waitForChildFrame(page);
383
+ const iframe = await waitForChildFrame(page, SPIF_CHILD_URL);
338
384
  const mainBgColor = await page.mainFrame().evaluate(() => {
339
385
  return getComputedStyle(document.documentElement).backgroundColor;
340
386
  });
@@ -352,7 +398,7 @@ test.describe("context.addInitScript with iframes", () => {
352
398
  "https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/",
353
399
  { waitUntil: "networkidle" }
354
400
  );
355
- const iframe = await waitForChildFrame(page);
401
+ const iframe = await waitForChildFrame(page, OOPIF_CHILD_URL);
356
402
  const mainBgColor = await page.mainFrame().evaluate(() => {
357
403
  return getComputedStyle(document.documentElement).backgroundColor;
358
404
  });
@@ -368,7 +414,7 @@ test.describe("context.addInitScript with iframes", () => {
368
414
  "https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/",
369
415
  { waitUntil: "networkidle" }
370
416
  );
371
- const iframe = await waitForChildFrame(page);
417
+ const iframe = await waitForChildFrame(page, SPIF_CHILD_URL);
372
418
  const mainBgColor = await page.mainFrame().evaluate(() => {
373
419
  return getComputedStyle(document.documentElement).backgroundColor;
374
420
  });
@@ -406,7 +452,7 @@ test.describe("context.addInitScript with iframes", () => {
406
452
  "shadow-host"
407
453
  );
408
454
  await preparePopupForFrameAttach(popup, "shadow-host");
409
- const iframe = await waitForChildFrame(popup);
455
+ const iframe = await waitForChildFrame(popup, OOPIF_CHILD_URL);
410
456
  const mainBgColor = await popup.mainFrame().evaluate(() => {
411
457
  return getComputedStyle(document.documentElement).backgroundColor;
412
458
  });
@@ -432,7 +478,7 @@ test.describe("context.addInitScript with iframes", () => {
432
478
  "/stagehand-eval-sites/sites/closed-shadow-dom-in-spif/"
433
479
  );
434
480
  await preparePopupForFrameAttach(popup, "iframe");
435
- const iframe = await waitForChildFrame(popup);
481
+ const iframe = await waitForChildFrame(popup, POPUP_SPIF_CHILD_URL);
436
482
  const mainBgColor = await popup.mainFrame().evaluate(() => {
437
483
  return getComputedStyle(document.documentElement).backgroundColor;
438
484
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../lib/v3/tests/iframe-ctx-addInitScript.spec.ts"],
4
- "sourcesContent": ["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { V3Context } from \"../understudy/context.js\";\nimport type { Page } from \"../understudy/page.js\";\n\nconst isBrowserbase =\n (process.env.STAGEHAND_BROWSER_TARGET ?? \"local\").toLowerCase() ===\n \"browserbase\";\nconst MIN_TIMEOUT_MS = 3_000;\nconst MAX_TIMEOUT_MS = 120_000;\n\nconst parseBoundedTimeoutMs = (\n value: string | undefined,\n fallbackMs: number,\n): number => {\n const parsed = Number(value ?? fallbackMs);\n if (!Number.isFinite(parsed)) return fallbackMs;\n return Math.max(MIN_TIMEOUT_MS, Math.min(MAX_TIMEOUT_MS, parsed));\n};\n\nconst CHILD_FRAME_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_CHILD_FRAME_TIMEOUT_MS,\n isBrowserbase ? 80_000 : 40_000,\n);\nconst POPUP_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_POPUP_TIMEOUT_MS,\n isBrowserbase ? 60_000 : 40_000,\n);\nconst POPUP_URL_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_POPUP_URL_TIMEOUT_MS,\n isBrowserbase ? 80_000 : 40_000,\n);\nconst DEBUG_INTERVAL_MS = 5_000;\nconst iframeDebugEnabled = isBrowserbase || process.env.IFRAME_DEBUG === \"1\";\nconst TEST_VIEWPORT = { width: 1288, height: 711 };\n\ntype FrameTreeNode = {\n frame: { id: string; parentId?: string; url?: string };\n childFrames?: FrameTreeNode[];\n};\n\nconst formatError = (error: unknown): string => {\n if (error instanceof Error) return error.message;\n return String(error);\n};\n\nconst flattenFrameTree = (\n node: FrameTreeNode,\n out: Array<{ id: string; parentId: string | null; url: string }> = [],\n): Array<{ id: string; parentId: string | null; url: string }> => {\n out.push({\n id: node.frame.id,\n parentId: node.frame.parentId ?? null,\n url: node.frame.url ?? \"\",\n });\n for (const child of node.childFrames ?? []) {\n flattenFrameTree(child, out);\n }\n return out;\n};\n\nfunction debugLog(\n step: string,\n payload?: Record<string, unknown> | string,\n): void {\n if (!iframeDebugEnabled) return;\n if (payload === undefined) {\n console.log(`[iframe-debug] ${step}`);\n return;\n }\n if (typeof payload === \"string\") {\n console.log(`[iframe-debug] ${step}: ${payload}`);\n return;\n }\n try {\n console.log(`[iframe-debug] ${step}: ${JSON.stringify(payload)}`);\n } catch {\n console.log(`[iframe-debug] ${step}: <unserializable payload>`);\n }\n}\n\nasync function collectFrameSnapshot(\n page: Page,\n): Promise<Array<Record<string, unknown>>> {\n const known = new Map<string, ReturnType<Page[\"frames\"]>[number]>();\n known.set(page.mainFrame().frameId, page.mainFrame());\n for (const frame of page.frames()) known.set(frame.frameId, frame);\n\n return Promise.all(\n [...known.values()].map(async (frame) => {\n try {\n const state = await frame.evaluate(() => {\n return {\n href: location.href,\n readyState: document.readyState,\n visibilityState: document.visibilityState,\n iframeCount: document.querySelectorAll(\"iframe\").length,\n hasShadowHost: Boolean(document.querySelector(\"shadow-host\")),\n };\n });\n return {\n frameId: frame.frameId,\n sessionId: frame.sessionId ?? \"root\",\n ...state,\n };\n } catch (error) {\n return {\n frameId: frame.frameId,\n sessionId: frame.sessionId ?? \"root\",\n error: formatError(error),\n };\n }\n }),\n );\n}\n\nasync function logPageDiagnostics(\n page: Page,\n reason: string,\n markerSelector?: string,\n): Promise<void> {\n if (!iframeDebugEnabled) return;\n const diagnostics: Record<string, unknown> = {\n reason,\n pageUrl: page.url(),\n mainFrameId: page.mainFrame().frameId,\n knownFrameCount: page.frames().length,\n };\n\n try {\n const domState = await page.mainFrame().evaluate((marker) => {\n const el = marker ? document.querySelector(marker) : null;\n const rect =\n el instanceof Element ? el.getBoundingClientRect().toJSON() : null;\n return {\n href: location.href,\n readyState: document.readyState,\n visibilityState: document.visibilityState,\n hidden: document.hidden,\n hasFocus: document.hasFocus(),\n innerWidth: window.innerWidth,\n innerHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n markerSelector: marker,\n markerPresent: Boolean(el),\n markerRect: rect,\n iframeCount: document.querySelectorAll(\"iframe\").length,\n };\n }, markerSelector);\n diagnostics.domState = domState;\n } catch (error) {\n diagnostics.domStateError = formatError(error);\n }\n\n try {\n const frameTreeResponse = (await page.sendCDP(\"Page.getFrameTree\")) as {\n frameTree?: FrameTreeNode;\n };\n if (frameTreeResponse.frameTree) {\n diagnostics.cdpFrameTree = flattenFrameTree(frameTreeResponse.frameTree);\n }\n } catch (error) {\n diagnostics.cdpFrameTreeError = formatError(error);\n }\n\n diagnostics.frameSnapshot = await collectFrameSnapshot(page);\n debugLog(\"page-diagnostics\", diagnostics);\n}\n\nasync function closeAllPages(ctx: V3Context): Promise<void> {\n const pages = ctx.pages();\n await Promise.allSettled(pages.map((page) => page.close()));\n}\n\n/**\n * Poll until a child frame (non-main) appears on `page` and its document\n * has finished loading. Returns the child frame.\n */\nasync function waitForChildFrame(\n page: Page,\n timeoutMs = CHILD_FRAME_TIMEOUT_MS,\n): Promise<ReturnType<Page[\"frames\"]>[number]> {\n const mainFrameId = page.mainFrame().frameId;\n const deadline = Date.now() + timeoutMs;\n let observedFrameCount = 0;\n let lastUrl = \"\";\n let lastLogAt = Date.now();\n\n while (Date.now() < deadline) {\n const frames = page.frames();\n observedFrameCount = Math.max(observedFrameCount, frames.length);\n lastUrl = page.url();\n const childIds = frames\n .filter((f) => f.frameId !== mainFrameId)\n .map((f) => f.frameId);\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForChildFrame:progress\", {\n url: lastUrl,\n mainFrameId,\n observedFrameCount,\n childIds,\n });\n lastLogAt = Date.now();\n }\n const child = frames.find((f) => f.frameId !== mainFrameId);\n if (child) {\n try {\n const ready = await child.evaluate(() => document.readyState);\n if (ready === \"complete\") {\n debugLog(\"waitForChildFrame:ready\", {\n childFrameId: child.frameId,\n url: lastUrl,\n });\n return child;\n }\n } catch {\n // frame not ready yet\n }\n }\n await new Promise((r) => setTimeout(r, 100));\n }\n await logPageDiagnostics(page, \"waitForChildFrame timeout\");\n throw new Error(\n `Timed out waiting for child frame to load (timeout=${timeoutMs}ms, mainFrameId=${mainFrameId}, maxObservedFrames=${observedFrameCount}, url=${lastUrl || \"<unknown>\"})`,\n );\n}\n\nasync function waitForPageUrl(\n page: Page,\n expectedUrlSubstring: string,\n timeoutMs = POPUP_URL_TIMEOUT_MS,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastUrl = \"\";\n let lastLogAt = Date.now();\n while (Date.now() < deadline) {\n lastUrl = page.url();\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForPageUrl:progress\", {\n expectedUrlSubstring,\n lastUrl,\n });\n lastLogAt = Date.now();\n }\n if (lastUrl.includes(expectedUrlSubstring)) {\n debugLog(\"waitForPageUrl:ready\", {\n expectedUrlSubstring,\n lastUrl,\n });\n return;\n }\n await new Promise((r) => setTimeout(r, 100));\n }\n await logPageDiagnostics(\n page,\n `waitForPageUrl timeout for ${expectedUrlSubstring}`,\n );\n throw new Error(\n `Timed out waiting for popup URL to include \"${expectedUrlSubstring}\" (timeout=${timeoutMs}ms, lastUrl=${lastUrl || \"<unknown>\"})`,\n );\n}\n\nasync function preparePopupForFrameAttach(\n page: Page,\n markerSelector: string,\n timeoutMs = CHILD_FRAME_TIMEOUT_MS,\n): Promise<void> {\n debugLog(\"preparePopupForFrameAttach:start\", {\n markerSelector,\n timeoutMs,\n url: page.url(),\n });\n await page.waitForLoadState(\"domcontentloaded\", timeoutMs);\n await page.waitForSelector(markerSelector, {\n state: \"attached\",\n timeout: timeoutMs,\n });\n await page.mainFrame().evaluate(() => {\n const host = document.querySelector(\"shadow-host\");\n if (host instanceof HTMLElement) {\n host.scrollIntoView({ block: \"center\", inline: \"center\" });\n } else {\n window.scrollTo(0, document.body.scrollHeight);\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new Event(\"scroll\"));\n });\n await logPageDiagnostics(\n page,\n \"preparePopupForFrameAttach:ready\",\n markerSelector,\n );\n}\n\nasync function ensurePopupViewport(page: Page): Promise<void> {\n await page.setViewportSize(TEST_VIEWPORT.width, TEST_VIEWPORT.height);\n await logPageDiagnostics(page, \"ensurePopupViewport\");\n}\n\nasync function waitForPopupPage(\n ctx: V3Context,\n opener: Page,\n timeoutMs = POPUP_TIMEOUT_MS,\n): Promise<Page> {\n const openerMainFrameId = opener.mainFrame().frameId;\n const deadline = Date.now() + timeoutMs;\n let lastLogAt = Date.now();\n\n while (Date.now() < deadline) {\n const pages = ctx.pages();\n const popup = pages.find((candidate) => {\n return candidate.mainFrame().frameId !== openerMainFrameId;\n });\n if (popup) {\n debugLog(\"waitForPopupPage:found\", {\n openerMainFrameId,\n popupMainFrameId: popup.mainFrame().frameId,\n popupUrl: popup.url(),\n });\n return popup;\n }\n\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForPopupPage:progress\", {\n openerMainFrameId,\n observedPageIds: pages.map((p) => p.mainFrame().frameId),\n });\n lastLogAt = Date.now();\n }\n\n try {\n const active = await ctx.awaitActivePage(500);\n if (active.mainFrame().frameId !== openerMainFrameId) {\n debugLog(\"waitForPopupPage:active-non-opener\", {\n openerMainFrameId,\n activeMainFrameId: active.mainFrame().frameId,\n activeUrl: active.url(),\n });\n return active;\n }\n } catch {\n // keep polling until timeout\n }\n\n await new Promise((r) => setTimeout(r, 100));\n }\n\n const pageIds = ctx\n .pages()\n .map((p) => p.mainFrame().frameId)\n .join(\", \");\n throw new Error(\n `Timed out waiting for popup page (timeout=${timeoutMs}ms, openerMainFrameId=${openerMainFrameId}, observedPages=[${pageIds}])`,\n );\n}\n\ntest.describe(\"context.addInitScript with iframes\", () => {\n if (isBrowserbase) {\n test.describe.configure({ mode: \"serial\" });\n }\n\n let v3: V3;\n let ctx: V3Context;\n\n test.beforeAll(async () => {\n debugLog(\"beforeAll:config\", {\n browserTarget: process.env.STAGEHAND_BROWSER_TARGET ?? \"local\",\n childFrameTimeoutMs: CHILD_FRAME_TIMEOUT_MS,\n popupTimeoutMs: POPUP_TIMEOUT_MS,\n popupUrlTimeoutMs: POPUP_URL_TIMEOUT_MS,\n });\n v3 = new V3(v3TestConfig);\n await v3.init();\n ctx = v3.context;\n\n // Add init script that sets background to red\n await ctx.addInitScript(`\n (() => {\n document.addEventListener('DOMContentLoaded', () => {\n document.documentElement.style.backgroundColor = 'red';\n });\n })();\n `);\n });\n\n test.beforeEach(async () => {\n await closeAllPages(ctx);\n });\n\n test.afterEach(async () => {\n await closeAllPages(ctx);\n });\n\n test.afterAll(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"direct navigation\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n\n test.describe(\"via newPage\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n\n test.describe(\"via popup\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/ctx-add-init-script-oopif/\",\n { waitUntil: \"networkidle\" },\n );\n\n // Click link to open popup\n await page.locator(\"a\").click();\n debugLog(\"popup-oopif:clicked-link\", { openerUrl: page.url() });\n\n // Wait for popup to open and become active\n const popup = await waitForPopupPage(ctx, page);\n ctx.setActivePage(popup);\n await ensurePopupViewport(popup);\n await waitForPageUrl(\n popup,\n \"/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n );\n debugLog(\"popup-oopif:refresh-navigation\", { url: popup.url() });\n await popup.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n await logPageDiagnostics(\n popup,\n \"popup-oopif:after-refresh\",\n \"shadow-host\",\n );\n await preparePopupForFrameAttach(popup, \"shadow-host\");\n const iframe = await waitForChildFrame(popup);\n\n // Check popup main page background\n const mainBgColor = await popup.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/ctx-add-init-script-spif/\",\n { waitUntil: \"networkidle\" },\n );\n\n // Click link to open popup\n await page.locator(\"a\").click();\n debugLog(\"popup-spif:clicked-link\", { openerUrl: page.url() });\n\n // Wait for popup to open and become active\n const popup = await waitForPopupPage(ctx, page);\n ctx.setActivePage(popup);\n await ensurePopupViewport(popup);\n await waitForPageUrl(\n popup,\n \"/stagehand-eval-sites/sites/closed-shadow-dom-in-spif/\",\n );\n await preparePopupForFrameAttach(popup, \"iframe\");\n const iframe = await waitForChildFrame(popup);\n\n // Check popup main page background\n const mainBgColor = await popup.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { V3Context } from \"../understudy/context.js\";\nimport type { Page } from \"../understudy/page.js\";\n\nconst isBrowserbase =\n (process.env.STAGEHAND_BROWSER_TARGET ?? \"local\").toLowerCase() ===\n \"browserbase\";\nconst MIN_TIMEOUT_MS = 3_000;\nconst MAX_TIMEOUT_MS = 120_000;\n\nconst parseBoundedTimeoutMs = (\n value: string | undefined,\n fallbackMs: number,\n): number => {\n const parsed = Number(value ?? fallbackMs);\n if (!Number.isFinite(parsed)) return fallbackMs;\n return Math.max(MIN_TIMEOUT_MS, Math.min(MAX_TIMEOUT_MS, parsed));\n};\n\nconst CHILD_FRAME_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_CHILD_FRAME_TIMEOUT_MS,\n isBrowserbase ? 80_000 : 40_000,\n);\nconst POPUP_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_POPUP_TIMEOUT_MS,\n isBrowserbase ? 60_000 : 40_000,\n);\nconst POPUP_URL_TIMEOUT_MS = parseBoundedTimeoutMs(\n process.env.IFRAME_POPUP_URL_TIMEOUT_MS,\n isBrowserbase ? 80_000 : 40_000,\n);\nconst DEBUG_INTERVAL_MS = 5_000;\nconst iframeDebugEnabled = isBrowserbase || process.env.IFRAME_DEBUG === \"1\";\nconst TEST_VIEWPORT = { width: 1288, height: 711 };\n\ntype FrameTreeNode = {\n frame: { id: string; parentId?: string; url?: string };\n childFrames?: FrameTreeNode[];\n};\n\nconst formatError = (error: unknown): string => {\n if (error instanceof Error) return error.message;\n return String(error);\n};\n\nconst flattenFrameTree = (\n node: FrameTreeNode,\n out: Array<{ id: string; parentId: string | null; url: string }> = [],\n): Array<{ id: string; parentId: string | null; url: string }> => {\n out.push({\n id: node.frame.id,\n parentId: node.frame.parentId ?? null,\n url: node.frame.url ?? \"\",\n });\n for (const child of node.childFrames ?? []) {\n flattenFrameTree(child, out);\n }\n return out;\n};\n\nfunction debugLog(\n step: string,\n payload?: Record<string, unknown> | string,\n): void {\n if (!iframeDebugEnabled) return;\n if (payload === undefined) {\n console.log(`[iframe-debug] ${step}`);\n return;\n }\n if (typeof payload === \"string\") {\n console.log(`[iframe-debug] ${step}: ${payload}`);\n return;\n }\n try {\n console.log(`[iframe-debug] ${step}: ${JSON.stringify(payload)}`);\n } catch {\n console.log(`[iframe-debug] ${step}: <unserializable payload>`);\n }\n}\n\nasync function collectFrameSnapshot(\n page: Page,\n): Promise<Array<Record<string, unknown>>> {\n const known = new Map<string, ReturnType<Page[\"frames\"]>[number]>();\n known.set(page.mainFrame().frameId, page.mainFrame());\n for (const frame of page.frames()) known.set(frame.frameId, frame);\n\n return Promise.all(\n [...known.values()].map(async (frame) => {\n try {\n const state = await frame.evaluate(() => {\n return {\n href: location.href,\n readyState: document.readyState,\n visibilityState: document.visibilityState,\n iframeCount: document.querySelectorAll(\"iframe\").length,\n hasShadowHost: Boolean(document.querySelector(\"shadow-host\")),\n };\n });\n return {\n frameId: frame.frameId,\n sessionId: frame.sessionId ?? \"root\",\n ...state,\n };\n } catch (error) {\n return {\n frameId: frame.frameId,\n sessionId: frame.sessionId ?? \"root\",\n error: formatError(error),\n };\n }\n }),\n );\n}\n\nasync function logPageDiagnostics(\n page: Page,\n reason: string,\n markerSelector?: string,\n): Promise<void> {\n if (!iframeDebugEnabled) return;\n const diagnostics: Record<string, unknown> = {\n reason,\n pageUrl: page.url(),\n mainFrameId: page.mainFrame().frameId,\n knownFrameCount: page.frames().length,\n };\n\n try {\n const domState = await page.mainFrame().evaluate((marker) => {\n const el = marker ? document.querySelector(marker) : null;\n const rect =\n el instanceof Element ? el.getBoundingClientRect().toJSON() : null;\n return {\n href: location.href,\n readyState: document.readyState,\n visibilityState: document.visibilityState,\n hidden: document.hidden,\n hasFocus: document.hasFocus(),\n innerWidth: window.innerWidth,\n innerHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n markerSelector: marker,\n markerPresent: Boolean(el),\n markerRect: rect,\n iframeCount: document.querySelectorAll(\"iframe\").length,\n };\n }, markerSelector);\n diagnostics.domState = domState;\n } catch (error) {\n diagnostics.domStateError = formatError(error);\n }\n\n try {\n const frameTreeResponse = (await page.sendCDP(\"Page.getFrameTree\")) as {\n frameTree?: FrameTreeNode;\n };\n if (frameTreeResponse.frameTree) {\n diagnostics.cdpFrameTree = flattenFrameTree(frameTreeResponse.frameTree);\n }\n } catch (error) {\n diagnostics.cdpFrameTreeError = formatError(error);\n }\n\n diagnostics.frameSnapshot = await collectFrameSnapshot(page);\n debugLog(\"page-diagnostics\", diagnostics);\n}\n\nasync function closeAllPages(ctx: V3Context): Promise<void> {\n const pages = ctx.pages();\n await Promise.allSettled(pages.map((page) => page.close()));\n}\n\n/**\n * Poll until a child frame (non-main) appears on `page` and its document\n * has finished loading. Returns the child frame.\n */\nasync function waitForChildFrame(\n page: Page,\n expectedChildUrl: string,\n timeoutMs = CHILD_FRAME_TIMEOUT_MS,\n): Promise<ReturnType<Page[\"frames\"]>[number]> {\n const mainFrameId = page.mainFrame().frameId;\n const deadline = Date.now() + timeoutMs;\n let observedFrameCount = 0;\n const observedChildFrameIds = new Set<string>();\n let lastUrl = \"\";\n let lastLogAt = Date.now();\n\n while (Date.now() < deadline) {\n const frames = page.frames();\n observedFrameCount = Math.max(observedFrameCount, frames.length);\n lastUrl = page.url();\n const childIds = frames\n .filter((f) => f.frameId !== mainFrameId)\n .map((f) => f.frameId);\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForChildFrame:progress\", {\n url: lastUrl,\n mainFrameId,\n observedFrameCount,\n childIds,\n expectedChildUrl,\n });\n lastLogAt = Date.now();\n }\n for (const childId of childIds) observedChildFrameIds.add(childId);\n\n const childFrames = frames\n .filter((f) => f.frameId !== mainFrameId)\n // Prefer recently-discovered frames first; stale swapped frame ids\n // can remain visible in the registry while the live OOPIF is ready.\n .reverse();\n\n if (childFrames.length) {\n const probes = await Promise.all(\n childFrames.map(async (child) => {\n try {\n const state = await child.evaluate(() => ({\n href: location.href,\n readyState: document.readyState,\n }));\n return {\n child,\n href: state.href,\n readyState: state.readyState,\n error: undefined,\n };\n } catch (error) {\n return {\n child,\n href: undefined,\n readyState: undefined,\n error: formatError(error),\n };\n }\n }),\n );\n\n const ready = probes.find(\n (probe) =>\n probe.readyState === \"complete\" && probe.href === expectedChildUrl,\n );\n if (ready) {\n debugLog(\"waitForChildFrame:ready\", {\n childFrameId: ready.child.frameId,\n childSessionId: ready.child.sessionId ?? \"root\",\n childUrl: ready.href ?? \"<unknown>\",\n expectedChildUrl,\n url: lastUrl,\n });\n return ready.child;\n }\n\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForChildFrame:not-ready\", {\n url: lastUrl,\n mainFrameId,\n expectedChildUrl,\n probes: probes.map((probe) => ({\n frameId: probe.child.frameId,\n sessionId: probe.child.sessionId ?? \"root\",\n readyState: probe.readyState ?? \"<unknown>\",\n href: probe.href ?? \"<unknown>\",\n error: probe.error ?? \"<none>\",\n })),\n });\n lastLogAt = Date.now();\n }\n }\n await new Promise((r) => setTimeout(r, 100));\n }\n await logPageDiagnostics(page, \"waitForChildFrame timeout\");\n throw new Error(\n `Timed out waiting for child frame to load (timeout=${timeoutMs}ms, mainFrameId=${mainFrameId}, expectedChildUrl=${expectedChildUrl}, maxObservedFrames=${observedFrameCount}, observedChildFrameIds=[${[...observedChildFrameIds].join(\",\")}], url=${lastUrl || \"<unknown>\"})`,\n );\n}\n\nasync function waitForPageUrl(\n page: Page,\n expectedUrlSubstring: string,\n timeoutMs = POPUP_URL_TIMEOUT_MS,\n): Promise<void> {\n const deadline = Date.now() + timeoutMs;\n let lastUrl = \"\";\n let lastLogAt = Date.now();\n while (Date.now() < deadline) {\n lastUrl = page.url();\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForPageUrl:progress\", {\n expectedUrlSubstring,\n lastUrl,\n });\n lastLogAt = Date.now();\n }\n if (lastUrl.includes(expectedUrlSubstring)) {\n debugLog(\"waitForPageUrl:ready\", {\n expectedUrlSubstring,\n lastUrl,\n });\n return;\n }\n await new Promise((r) => setTimeout(r, 100));\n }\n await logPageDiagnostics(\n page,\n `waitForPageUrl timeout for ${expectedUrlSubstring}`,\n );\n throw new Error(\n `Timed out waiting for popup URL to include \"${expectedUrlSubstring}\" (timeout=${timeoutMs}ms, lastUrl=${lastUrl || \"<unknown>\"})`,\n );\n}\n\nasync function preparePopupForFrameAttach(\n page: Page,\n markerSelector: string,\n timeoutMs = CHILD_FRAME_TIMEOUT_MS,\n): Promise<void> {\n debugLog(\"preparePopupForFrameAttach:start\", {\n markerSelector,\n timeoutMs,\n url: page.url(),\n });\n await page.waitForLoadState(\"domcontentloaded\", timeoutMs);\n await page.waitForSelector(markerSelector, {\n state: \"attached\",\n timeout: timeoutMs,\n });\n await page.mainFrame().evaluate(() => {\n const host = document.querySelector(\"shadow-host\");\n if (host instanceof HTMLElement) {\n host.scrollIntoView({ block: \"center\", inline: \"center\" });\n } else {\n window.scrollTo(0, document.body.scrollHeight);\n window.scrollTo(0, 0);\n }\n window.dispatchEvent(new Event(\"scroll\"));\n });\n await logPageDiagnostics(\n page,\n \"preparePopupForFrameAttach:ready\",\n markerSelector,\n );\n}\n\nasync function ensurePopupViewport(page: Page): Promise<void> {\n await page.setViewportSize(TEST_VIEWPORT.width, TEST_VIEWPORT.height);\n await logPageDiagnostics(page, \"ensurePopupViewport\");\n}\n\nasync function waitForPopupPage(\n ctx: V3Context,\n opener: Page,\n timeoutMs = POPUP_TIMEOUT_MS,\n): Promise<Page> {\n const openerMainFrameId = opener.mainFrame().frameId;\n const deadline = Date.now() + timeoutMs;\n let lastLogAt = Date.now();\n\n while (Date.now() < deadline) {\n const pages = ctx.pages();\n const popup = pages.find((candidate) => {\n return candidate.mainFrame().frameId !== openerMainFrameId;\n });\n if (popup) {\n debugLog(\"waitForPopupPage:found\", {\n openerMainFrameId,\n popupMainFrameId: popup.mainFrame().frameId,\n popupUrl: popup.url(),\n });\n return popup;\n }\n\n if (iframeDebugEnabled && Date.now() - lastLogAt >= DEBUG_INTERVAL_MS) {\n debugLog(\"waitForPopupPage:progress\", {\n openerMainFrameId,\n observedPageIds: pages.map((p) => p.mainFrame().frameId),\n });\n lastLogAt = Date.now();\n }\n\n try {\n const active = await ctx.awaitActivePage(500);\n if (active.mainFrame().frameId !== openerMainFrameId) {\n debugLog(\"waitForPopupPage:active-non-opener\", {\n openerMainFrameId,\n activeMainFrameId: active.mainFrame().frameId,\n activeUrl: active.url(),\n });\n return active;\n }\n } catch {\n // keep polling until timeout\n }\n\n await new Promise((r) => setTimeout(r, 100));\n }\n\n const pageIds = ctx\n .pages()\n .map((p) => p.mainFrame().frameId)\n .join(\", \");\n throw new Error(\n `Timed out waiting for popup page (timeout=${timeoutMs}ms, openerMainFrameId=${openerMainFrameId}, observedPages=[${pageIds}])`,\n );\n}\n\ntest.describe(\"context.addInitScript with iframes\", () => {\n const OOPIF_CHILD_URL =\n \"https://seanmcguire12.github.io/stagehand-oopif-sites/sites/form-filling/\";\n const SPIF_CHILD_URL =\n \"https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/iframe.html\";\n const POPUP_SPIF_CHILD_URL =\n \"https://browserbase.github.io/stagehand-eval-sites/sites/closed-shadow-dom-in-spif/embedded.html\";\n\n if (isBrowserbase) {\n test.describe.configure({ mode: \"serial\" });\n }\n\n let v3: V3;\n let ctx: V3Context;\n\n test.beforeAll(async () => {\n debugLog(\"beforeAll:config\", {\n browserTarget: process.env.STAGEHAND_BROWSER_TARGET ?? \"local\",\n childFrameTimeoutMs: CHILD_FRAME_TIMEOUT_MS,\n popupTimeoutMs: POPUP_TIMEOUT_MS,\n popupUrlTimeoutMs: POPUP_URL_TIMEOUT_MS,\n });\n v3 = new V3(v3TestConfig);\n await v3.init();\n ctx = v3.context;\n\n // Add init script that sets background to red\n await ctx.addInitScript(`\n (() => {\n document.addEventListener('DOMContentLoaded', () => {\n document.documentElement.style.backgroundColor = 'red';\n });\n })();\n `);\n });\n\n test.beforeEach(async () => {\n await closeAllPages(ctx);\n });\n\n test.afterEach(async () => {\n await closeAllPages(ctx);\n });\n\n test.afterAll(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"direct navigation\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page, OOPIF_CHILD_URL);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page, SPIF_CHILD_URL);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n\n test.describe(\"via newPage\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page, OOPIF_CHILD_URL);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/spif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n\n const iframe = await waitForChildFrame(page, SPIF_CHILD_URL);\n\n // Check main page background\n const mainBgColor = await page.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n\n test.describe(\"via popup\", () => {\n test(\"with OOPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/ctx-add-init-script-oopif/\",\n { waitUntil: \"networkidle\" },\n );\n\n // Click link to open popup\n await page.locator(\"a\").click();\n debugLog(\"popup-oopif:clicked-link\", { openerUrl: page.url() });\n\n // Wait for popup to open and become active\n const popup = await waitForPopupPage(ctx, page);\n ctx.setActivePage(popup);\n await ensurePopupViewport(popup);\n await waitForPageUrl(\n popup,\n \"/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n );\n debugLog(\"popup-oopif:refresh-navigation\", { url: popup.url() });\n await popup.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/oopif-in-closed-shadow-dom/\",\n { waitUntil: \"networkidle\" },\n );\n await logPageDiagnostics(\n popup,\n \"popup-oopif:after-refresh\",\n \"shadow-host\",\n );\n await preparePopupForFrameAttach(popup, \"shadow-host\");\n const iframe = await waitForChildFrame(popup, OOPIF_CHILD_URL);\n\n // Check popup main page background\n const mainBgColor = await popup.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n\n test(\"with SPIF - sets background red in main page and iframe\", async () => {\n const page = await ctx.newPage();\n\n await page.goto(\n \"https://browserbase.github.io/stagehand-eval-sites/sites/ctx-add-init-script-spif/\",\n { waitUntil: \"networkidle\" },\n );\n\n // Click link to open popup\n await page.locator(\"a\").click();\n debugLog(\"popup-spif:clicked-link\", { openerUrl: page.url() });\n\n // Wait for popup to open and become active\n const popup = await waitForPopupPage(ctx, page);\n ctx.setActivePage(popup);\n await ensurePopupViewport(popup);\n await waitForPageUrl(\n popup,\n \"/stagehand-eval-sites/sites/closed-shadow-dom-in-spif/\",\n );\n await preparePopupForFrameAttach(popup, \"iframe\");\n const iframe = await waitForChildFrame(popup, POPUP_SPIF_CHILD_URL);\n\n // Check popup main page background\n const mainBgColor = await popup.mainFrame().evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(mainBgColor).toBe(\"rgb(255, 0, 0)\");\n\n const iframeBgColor = await iframe.evaluate(() => {\n return getComputedStyle(document.documentElement).backgroundColor;\n });\n expect(iframeBgColor).toBe(\"rgb(255, 0, 0)\");\n });\n });\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,39 +1,6 @@
1
1
  import { defineConfig } from "@playwright/test";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- const resolveRepoRoot = (startDir) => {
5
- let current = path.resolve(startDir);
6
- while (true) {
7
- if (fs.existsSync(path.join(current, "pnpm-workspace.yaml"))) {
8
- return current;
9
- }
10
- const parent = path.dirname(current);
11
- if (parent === current) {
12
- return startDir;
13
- }
14
- current = parent;
15
- }
16
- };
17
- const repoRoot = resolveRepoRoot(process.cwd());
18
- const distTestDir = path.join(
19
- repoRoot,
20
- "packages",
21
- "core",
22
- "dist",
23
- "esm",
24
- "lib",
25
- "v3",
26
- "tests"
27
- );
28
- const srcTestDir = path.join(
29
- repoRoot,
30
- "packages",
31
- "core",
32
- "lib",
33
- "v3",
34
- "tests"
35
- );
36
- const testDir = fs.existsSync(distTestDir) ? distTestDir : srcTestDir;
2
+ import { fileURLToPath } from "node:url";
3
+ const testDir = fileURLToPath(new URL(".", import.meta.url));
37
4
  const browserTarget = (process.env.STAGEHAND_BROWSER_TARGET ?? "local").toLowerCase();
38
5
  const isBrowserbase = browserTarget === "browserbase";
39
6
  const consoleReporter = process.env.PLAYWRIGHT_CONSOLE_REPORTER ?? "list";
@@ -46,34 +13,10 @@ const ciWorkerOverride = Number(
46
13
  );
47
14
  const bbWorkers = process.env.CI && Number.isFinite(ciWorkerOverride) && ciWorkerOverride > 0 ? ciWorkerOverride : 3;
48
15
  const ctrfJunitPath = process.env.CTRF_JUNIT_PATH;
49
- const envReporterPath = (() => {
50
- const distPath = path.join(
51
- repoRoot,
52
- "packages",
53
- "core",
54
- "dist",
55
- "esm",
56
- "lib",
57
- "v3",
58
- "tests",
59
- "envReporter.js"
60
- );
61
- if (fs.existsSync(distPath)) return distPath;
62
- return path.join(
63
- repoRoot,
64
- "packages",
65
- "core",
66
- "lib",
67
- "v3",
68
- "tests",
69
- "envReporter.ts"
70
- );
71
- })();
72
16
  const reporter = ctrfJunitPath ? [
73
17
  [consoleReporter],
74
- [envReporterPath],
75
18
  ["junit", { outputFile: ctrfJunitPath, includeProjectInTestName: true }]
76
- ] : [[consoleReporter], [envReporterPath]];
19
+ ] : [[consoleReporter]];
77
20
  var v3_playwright_config_default = defineConfig({
78
21
  testDir,
79
22
  timeout: 9e4,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../lib/v3/tests/v3.playwright.config.ts"],
4
- "sourcesContent": ["import { defineConfig, type ReporterDescription } from \"@playwright/test\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst resolveRepoRoot = (startDir: string): string => {\n let current = path.resolve(startDir);\n while (true) {\n if (fs.existsSync(path.join(current, \"pnpm-workspace.yaml\"))) {\n return current;\n }\n const parent = path.dirname(current);\n if (parent === current) {\n return startDir;\n }\n current = parent;\n }\n};\n\nconst repoRoot = resolveRepoRoot(process.cwd());\nconst distTestDir = path.join(\n repoRoot,\n \"packages\",\n \"core\",\n \"dist\",\n \"esm\",\n \"lib\",\n \"v3\",\n \"tests\",\n);\nconst srcTestDir = path.join(\n repoRoot,\n \"packages\",\n \"core\",\n \"lib\",\n \"v3\",\n \"tests\",\n);\nconst testDir = fs.existsSync(distTestDir) ? distTestDir : srcTestDir;\n\nconst browserTarget = (\n process.env.STAGEHAND_BROWSER_TARGET ?? \"local\"\n).toLowerCase();\nconst isBrowserbase = browserTarget === \"browserbase\";\nconst consoleReporter = process.env.PLAYWRIGHT_CONSOLE_REPORTER ?? \"list\";\n\nconst localWorkerOverride = Number(\n process.env.LOCAL_SESSION_LIMIT_PER_E2E_TEST,\n);\nconst localWorkers =\n Number.isFinite(localWorkerOverride) && localWorkerOverride > 0\n ? localWorkerOverride\n : process.env.CI\n ? 3\n : 5;\n\nconst ciWorkerOverride = Number(\n process.env.BROWSERBASE_SESSION_LIMIT_PER_E2E_TEST,\n);\nconst bbWorkers =\n process.env.CI && Number.isFinite(ciWorkerOverride) && ciWorkerOverride > 0\n ? ciWorkerOverride\n : 3;\n\nconst ctrfJunitPath = process.env.CTRF_JUNIT_PATH;\nconst envReporterPath = (() => {\n const distPath = path.join(\n repoRoot,\n \"packages\",\n \"core\",\n \"dist\",\n \"esm\",\n \"lib\",\n \"v3\",\n \"tests\",\n \"envReporter.js\",\n );\n if (fs.existsSync(distPath)) return distPath;\n return path.join(\n repoRoot,\n \"packages\",\n \"core\",\n \"lib\",\n \"v3\",\n \"tests\",\n \"envReporter.ts\",\n );\n})();\nconst reporter: ReporterDescription[] = ctrfJunitPath\n ? [\n [consoleReporter],\n [envReporterPath],\n [\"junit\", { outputFile: ctrfJunitPath, includeProjectInTestName: true }],\n ]\n : [[consoleReporter], [envReporterPath]];\n\nexport default defineConfig({\n testDir,\n timeout: 90_000,\n expect: { timeout: 10_000 },\n retries: process.env.CI ? 1 : 0,\n workers: isBrowserbase ? bbWorkers : localWorkers,\n fullyParallel: true,\n projects: [\n {\n name: isBrowserbase ? \"e2e-bb\" : \"e2e-local\",\n },\n ],\n reporter,\n use: {\n // we're not launching Playwright browsers in these tests; we connect via Puppeteer/CDP to V3.\n headless: false,\n },\n});\n"],
5
- "mappings": "AAAA,SAAS,oBAA8C;AACvD,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,MAAM,kBAAkB,CAAC,aAA6B;AACpD,MAAI,UAAU,KAAK,QAAQ,QAAQ;AACnC,SAAO,MAAM;AACX,QAAI,GAAG,WAAW,KAAK,KAAK,SAAS,qBAAqB,CAAC,GAAG;AAC5D,aAAO;AAAA,IACT;AACA,UAAM,SAAS,KAAK,QAAQ,OAAO;AACnC,QAAI,WAAW,SAAS;AACtB,aAAO;AAAA,IACT;AACA,cAAU;AAAA,EACZ;AACF;AAEA,MAAM,WAAW,gBAAgB,QAAQ,IAAI,CAAC;AAC9C,MAAM,cAAc,KAAK;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,aAAa,KAAK;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACA,MAAM,UAAU,GAAG,WAAW,WAAW,IAAI,cAAc;AAE3D,MAAM,iBACJ,QAAQ,IAAI,4BAA4B,SACxC,YAAY;AACd,MAAM,gBAAgB,kBAAkB;AACxC,MAAM,kBAAkB,QAAQ,IAAI,+BAA+B;AAEnE,MAAM,sBAAsB;AAAA,EAC1B,QAAQ,IAAI;AACd;AACA,MAAM,eACJ,OAAO,SAAS,mBAAmB,KAAK,sBAAsB,IAC1D,sBACA,QAAQ,IAAI,KACV,IACA;AAER,MAAM,mBAAmB;AAAA,EACvB,QAAQ,IAAI;AACd;AACA,MAAM,YACJ,QAAQ,IAAI,MAAM,OAAO,SAAS,gBAAgB,KAAK,mBAAmB,IACtE,mBACA;AAEN,MAAM,gBAAgB,QAAQ,IAAI;AAClC,MAAM,mBAAmB,MAAM;AAC7B,QAAM,WAAW,KAAK;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,MAAI,GAAG,WAAW,QAAQ,EAAG,QAAO;AACpC,SAAO,KAAK;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF,GAAG;AACH,MAAM,WAAkC,gBACpC;AAAA,EACE,CAAC,eAAe;AAAA,EAChB,CAAC,eAAe;AAAA,EAChB,CAAC,SAAS,EAAE,YAAY,eAAe,0BAA0B,KAAK,CAAC;AACzE,IACA,CAAC,CAAC,eAAe,GAAG,CAAC,eAAe,CAAC;AAEzC,IAAO,+BAAQ,aAAa;AAAA,EAC1B;AAAA,EACA,SAAS;AAAA,EACT,QAAQ,EAAE,SAAS,IAAO;AAAA,EAC1B,SAAS,QAAQ,IAAI,KAAK,IAAI;AAAA,EAC9B,SAAS,gBAAgB,YAAY;AAAA,EACrC,eAAe;AAAA,EACf,UAAU;AAAA,IACR;AAAA,MACE,MAAM,gBAAgB,WAAW;AAAA,IACnC;AAAA,EACF;AAAA,EACA;AAAA,EACA,KAAK;AAAA;AAAA,IAEH,UAAU;AAAA,EACZ;AACF,CAAC;",
4
+ "sourcesContent": ["import { defineConfig } from \"@playwright/test\";\nimport { fileURLToPath } from \"node:url\";\n\nconst testDir = fileURLToPath(new URL(\".\", import.meta.url));\n\nconst browserTarget = (\n process.env.STAGEHAND_BROWSER_TARGET ?? \"local\"\n).toLowerCase();\nconst isBrowserbase = browserTarget === \"browserbase\";\nconst consoleReporter = process.env.PLAYWRIGHT_CONSOLE_REPORTER ?? \"list\";\n\nconst localWorkerOverride = Number(\n process.env.LOCAL_SESSION_LIMIT_PER_E2E_TEST,\n);\nconst localWorkers =\n Number.isFinite(localWorkerOverride) && localWorkerOverride > 0\n ? localWorkerOverride\n : process.env.CI\n ? 3\n : 5;\n\nconst ciWorkerOverride = Number(\n process.env.BROWSERBASE_SESSION_LIMIT_PER_E2E_TEST,\n);\nconst bbWorkers =\n process.env.CI && Number.isFinite(ciWorkerOverride) && ciWorkerOverride > 0\n ? ciWorkerOverride\n : 3;\n\nconst ctrfJunitPath = process.env.CTRF_JUNIT_PATH;\nconst reporter = ctrfJunitPath\n ? [\n [consoleReporter],\n [\"junit\", { outputFile: ctrfJunitPath, includeProjectInTestName: true }],\n ]\n : [[consoleReporter]];\n\nexport default defineConfig({\n testDir,\n timeout: 90_000,\n expect: { timeout: 10_000 },\n retries: process.env.CI ? 1 : 0,\n workers: isBrowserbase ? bbWorkers : localWorkers,\n fullyParallel: true,\n projects: [\n {\n name: isBrowserbase ? \"e2e-bb\" : \"e2e-local\",\n },\n ],\n reporter,\n use: {\n // we're not launching Playwright browsers in these tests; we connect via Puppeteer/CDP to V3.\n headless: false,\n },\n});\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAE9B,MAAM,UAAU,cAAc,IAAI,IAAI,KAAK,YAAY,GAAG,CAAC;AAE3D,MAAM,iBACJ,QAAQ,IAAI,4BAA4B,SACxC,YAAY;AACd,MAAM,gBAAgB,kBAAkB;AACxC,MAAM,kBAAkB,QAAQ,IAAI,+BAA+B;AAEnE,MAAM,sBAAsB;AAAA,EAC1B,QAAQ,IAAI;AACd;AACA,MAAM,eACJ,OAAO,SAAS,mBAAmB,KAAK,sBAAsB,IAC1D,sBACA,QAAQ,IAAI,KACV,IACA;AAER,MAAM,mBAAmB;AAAA,EACvB,QAAQ,IAAI;AACd;AACA,MAAM,YACJ,QAAQ,IAAI,MAAM,OAAO,SAAS,gBAAgB,KAAK,mBAAmB,IACtE,mBACA;AAEN,MAAM,gBAAgB,QAAQ,IAAI;AAClC,MAAM,WAAW,gBACb;AAAA,EACE,CAAC,eAAe;AAAA,EAChB,CAAC,SAAS,EAAE,YAAY,eAAe,0BAA0B,KAAK,CAAC;AACzE,IACA,CAAC,CAAC,eAAe,CAAC;AAEtB,IAAO,+BAAQ,aAAa;AAAA,EAC1B;AAAA,EACA,SAAS;AAAA,EACT,QAAQ,EAAE,SAAS,IAAO;AAAA,EAC1B,SAAS,QAAQ,IAAI,KAAK,IAAI;AAAA,EAC9B,SAAS,gBAAgB,YAAY;AAAA,EACrC,eAAe;AAAA,EACf,UAAU;AAAA,IACR;AAAA,MACE,MAAM,gBAAgB,WAAW;AAAA,IACnC;AAAA,EACF;AAAA,EACA;AAAA,EACA,KAAK;AAAA;AAAA,IAEH,UAAU;AAAA,EACZ;AACF,CAAC;",
6
6
  "names": []
7
7
  }
@@ -3,29 +3,17 @@
3
3
  */
4
4
  export type ShutdownSupervisorConfig = {
5
5
  kind: "LOCAL";
6
- keepAlive: boolean;
7
6
  pid: number;
8
7
  userDataDir?: string;
9
8
  createdTempProfile?: boolean;
10
9
  preserveUserDataDir?: boolean;
11
10
  } | {
12
11
  kind: "STAGEHAND_API";
13
- keepAlive: boolean;
14
12
  sessionId: string;
15
13
  apiKey: string;
16
14
  projectId: string;
17
15
  };
18
- export type ShutdownSupervisorMessage = {
19
- type: "config";
20
- config: ShutdownSupervisorConfig;
21
- } | {
22
- type: "exit";
23
- } | {
24
- type: "ready";
25
- };
26
16
  export interface ShutdownSupervisorHandle {
27
- /** Best-effort signal to stop the supervisor without running cleanup. */
17
+ /** Best-effort signal to stop the supervisor process. */
28
18
  stop: () => void;
29
- /** Resolves once the supervisor acknowledges config or times out. */
30
- ready: Promise<void>;
31
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/private/shutdown.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Internal-only types for the shutdown supervisor process.\n */\n\nexport type ShutdownSupervisorConfig =\n | {\n kind: \"LOCAL\";\n keepAlive: boolean;\n pid: number;\n userDataDir?: string;\n createdTempProfile?: boolean;\n preserveUserDataDir?: boolean;\n }\n | {\n kind: \"STAGEHAND_API\";\n keepAlive: boolean;\n sessionId: string;\n apiKey: string;\n projectId: string;\n };\n\nexport type ShutdownSupervisorMessage =\n | { type: \"config\"; config: ShutdownSupervisorConfig }\n | { type: \"exit\" }\n | { type: \"ready\" };\n\nexport interface ShutdownSupervisorHandle {\n /** Best-effort signal to stop the supervisor without running cleanup. */\n stop: () => void;\n /** Resolves once the supervisor acknowledges config or times out. */\n ready: Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../../../../../lib/v3/types/private/shutdown.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Internal-only types for the shutdown supervisor process.\n */\n\nexport type ShutdownSupervisorConfig =\n | {\n kind: \"LOCAL\";\n pid: number;\n userDataDir?: string;\n createdTempProfile?: boolean;\n preserveUserDataDir?: boolean;\n }\n | {\n kind: \"STAGEHAND_API\";\n sessionId: string;\n apiKey: string;\n projectId: string;\n };\n\nexport interface ShutdownSupervisorHandle {\n /** Best-effort signal to stop the supervisor process. */\n stop: () => void;\n}\n"]}
@@ -7,6 +7,15 @@ import { executionContexts } from "./executionContextRegistry.js";
7
7
  import { normalizeInitScriptSource } from "./initScripts.js";
8
8
  import { TimeoutError, PageNotFoundError } from "../types/public/sdkErrors.js";
9
9
  import { getEnvTimeoutMs, withTimeout } from "../timeoutConfig.js";
10
+ const DEFAULT_FIRST_TOP_LEVEL_PAGE_TIMEOUT_MS = 5000;
11
+ const CI_FIRST_TOP_LEVEL_PAGE_TIMEOUT_MS = 30000;
12
+ const FIRST_TOP_LEVEL_PAGE_TIMEOUT_ENV = "STAGEHAND_FIRST_TOP_LEVEL_PAGE_TIMEOUT_MS";
13
+ function getFirstTopLevelPageTimeoutMs() {
14
+ return (getEnvTimeoutMs(FIRST_TOP_LEVEL_PAGE_TIMEOUT_ENV) ??
15
+ (process.env.CI
16
+ ? CI_FIRST_TOP_LEVEL_PAGE_TIMEOUT_MS
17
+ : DEFAULT_FIRST_TOP_LEVEL_PAGE_TIMEOUT_MS));
18
+ }
10
19
  function isTopLevelPage(info) {
11
20
  const ti = info;
12
21
  return info.type === "page" && ti.subtype !== "iframe";
@@ -73,7 +82,7 @@ export class V3Context {
73
82
  const conn = await CdpConnection.connect(wsUrl);
74
83
  const ctx = new V3Context(conn, opts?.env ?? "LOCAL", opts?.apiClient ?? null, opts?.localBrowserLaunchOptions ?? null);
75
84
  await ctx.bootstrap();
76
- await ctx.waitForFirstTopLevelPage(5000);
85
+ await ctx.waitForFirstTopLevelPage(getFirstTopLevelPageTimeoutMs());
77
86
  return ctx;
78
87
  };
79
88
  const cdpTimeoutMs = opts?.env === "BROWSERBASE"