@browserbasehq/orca 3.1.0-patch.4 → 3.2.0-middleware.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 (431) hide show
  1. package/dist/cjs/lib/inference.js +1 -4
  2. package/dist/cjs/lib/inference.js.map +1 -1
  3. package/dist/cjs/lib/utils.d.ts +1 -0
  4. package/dist/cjs/lib/utils.js +4 -0
  5. package/dist/cjs/lib/utils.js.map +1 -1
  6. package/dist/cjs/lib/v3/agent/AgentClient.d.ts +8 -0
  7. package/dist/cjs/lib/v3/agent/AgentClient.js +13 -0
  8. package/dist/cjs/lib/v3/agent/AgentClient.js.map +1 -1
  9. package/dist/cjs/lib/v3/agent/AgentProvider.js +0 -1
  10. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  11. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +6 -7
  12. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +6 -7
  14. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  16. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  17. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
  18. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +67 -8
  19. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  20. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.d.ts +4 -2
  21. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js +7 -7
  22. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  23. package/dist/cjs/lib/v3/agent/tools/act.d.ts +1 -1
  24. package/dist/cjs/lib/v3/agent/tools/act.js +11 -4
  25. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  26. package/dist/cjs/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  27. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +49 -22
  28. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  29. package/dist/cjs/lib/v3/agent/tools/{search.js → braveSearch.js} +1 -1
  30. package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -0
  31. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.d.ts +13 -0
  32. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js +70 -0
  33. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -0
  34. package/dist/cjs/lib/v3/agent/tools/click.js +23 -31
  35. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  36. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  37. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js +22 -30
  38. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  39. package/dist/cjs/lib/v3/agent/tools/extract.d.ts +2 -2
  40. package/dist/cjs/lib/v3/agent/tools/extract.js +7 -3
  41. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  42. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +30 -30
  43. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  44. package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +7 -2
  45. package/dist/cjs/lib/v3/agent/tools/fillform.js +56 -45
  46. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  47. package/dist/cjs/lib/v3/agent/tools/index.d.ts +19 -3
  48. package/dist/cjs/lib/v3/agent/tools/index.js +63 -11
  49. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  50. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
  51. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  52. package/dist/cjs/lib/v3/agent/tools/screenshot.d.ts +8 -0
  53. package/dist/cjs/lib/v3/agent/tools/screenshot.js +32 -15
  54. package/dist/cjs/lib/v3/agent/tools/screenshot.js.map +1 -1
  55. package/dist/cjs/lib/v3/agent/tools/scroll.js +12 -0
  56. package/dist/cjs/lib/v3/agent/tools/scroll.js.map +1 -1
  57. package/dist/cjs/lib/v3/agent/tools/type.js +23 -31
  58. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  59. package/dist/cjs/lib/v3/agent/tools/wait.js +6 -0
  60. package/dist/cjs/lib/v3/agent/tools/wait.js.map +1 -1
  61. package/dist/cjs/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  62. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js +175 -0
  63. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  64. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  65. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  66. package/dist/cjs/lib/v3/api.d.ts +2 -2
  67. package/dist/cjs/lib/v3/api.js +1 -1
  68. package/dist/cjs/lib/v3/api.js.map +1 -1
  69. package/dist/cjs/lib/v3/cache/ActCache.d.ts +0 -1
  70. package/dist/cjs/lib/v3/cache/ActCache.js +2 -18
  71. package/dist/cjs/lib/v3/cache/ActCache.js.map +1 -1
  72. package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  73. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
  74. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  75. package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
  76. package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
  77. package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
  78. package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
  79. package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
  80. package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
  81. package/dist/cjs/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  82. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
  83. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  84. package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
  85. package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
  86. package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
  87. package/dist/cjs/lib/v3/handlers/actHandler.js +1 -2
  88. package/dist/cjs/lib/v3/handlers/actHandler.js.map +1 -1
  89. package/dist/cjs/lib/v3/handlers/extractHandler.js +2 -2
  90. package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
  91. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  92. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  93. package/dist/cjs/lib/v3/handlers/observeHandler.js +1 -2
  94. package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
  95. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  96. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +130 -91
  97. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  98. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  99. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  100. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  101. package/dist/cjs/lib/v3/index.d.ts +2 -1
  102. package/dist/cjs/lib/v3/launch/browserbase.d.ts +1 -1
  103. package/dist/cjs/lib/v3/launch/browserbase.js +4 -9
  104. package/dist/cjs/lib/v3/launch/browserbase.js.map +1 -1
  105. package/dist/cjs/lib/v3/llm/LLMProvider.d.ts +5 -2
  106. package/dist/cjs/lib/v3/llm/LLMProvider.js +13 -11
  107. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  108. package/dist/cjs/lib/v3/llm/aisdk.js +11 -17
  109. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  110. package/dist/cjs/lib/v3/runtimePaths.js +2 -1
  111. package/dist/cjs/lib/v3/runtimePaths.js.map +1 -1
  112. package/dist/cjs/lib/v3/shutdown/supervisor.js +2 -2
  113. package/dist/cjs/lib/v3/shutdown/supervisor.js.map +1 -1
  114. package/dist/cjs/lib/v3/timeoutConfig.d.ts +1 -1
  115. package/dist/cjs/lib/v3/timeoutConfig.js +5 -0
  116. package/dist/cjs/lib/v3/timeoutConfig.js.map +1 -1
  117. package/dist/cjs/lib/v3/types/private/cache.d.ts +0 -1
  118. package/dist/cjs/lib/v3/types/private/cache.js.map +1 -1
  119. package/dist/cjs/lib/v3/types/private/shutdown.d.ts +1 -1
  120. package/dist/cjs/lib/v3/types/private/shutdown.js.map +1 -1
  121. package/dist/cjs/lib/v3/types/public/agent.d.ts +28 -3
  122. package/dist/cjs/lib/v3/types/public/agent.js +0 -1
  123. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  124. package/dist/cjs/lib/v3/types/public/api.d.ts +7 -0
  125. package/dist/cjs/lib/v3/types/public/api.js +9 -0
  126. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  127. package/dist/cjs/lib/v3/types/public/model.d.ts +12 -3
  128. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  129. package/dist/cjs/lib/v3/types/public/options.d.ts +8 -0
  130. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  131. package/dist/cjs/lib/v3/understudy/cdp.d.ts +8 -13
  132. package/dist/cjs/lib/v3/understudy/cdp.js +180 -20
  133. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  134. package/dist/cjs/lib/v3/understudy/context.d.ts +1 -0
  135. package/dist/cjs/lib/v3/understudy/context.js +142 -60
  136. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  137. package/dist/cjs/lib/v3/understudy/frame.js +23 -6
  138. package/dist/cjs/lib/v3/understudy/frame.js.map +1 -1
  139. package/dist/cjs/lib/v3/understudy/page.d.ts +13 -0
  140. package/dist/cjs/lib/v3/understudy/page.js +84 -21
  141. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  142. package/dist/cjs/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  143. package/dist/cjs/lib/v3/understudy/screenshotUtils.js +0 -18
  144. package/dist/cjs/lib/v3/understudy/screenshotUtils.js.map +1 -1
  145. package/dist/cjs/lib/v3/v3.d.ts +26 -3
  146. package/dist/cjs/lib/v3/v3.js +242 -180
  147. package/dist/cjs/lib/v3/v3.js.map +1 -1
  148. package/dist/cjs/lib/version.d.ts +1 -1
  149. package/dist/cjs/lib/version.js +1 -1
  150. package/dist/cjs/lib/version.js.map +1 -1
  151. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +56 -0
  152. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  153. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js +6 -6
  154. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  155. package/dist/cjs/tests/integration/cdp-session-detached.spec.js +1 -1
  156. package/dist/cjs/tests/integration/cdp-session-detached.spec.js.map +1 -1
  157. package/dist/cjs/tests/integration/context-addInitScript.spec.js +104 -11
  158. package/dist/cjs/tests/integration/context-addInitScript.spec.js.map +1 -1
  159. package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
  160. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
  161. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  162. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js +219 -0
  163. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  164. package/dist/cjs/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  165. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js +85 -0
  166. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  167. package/dist/cjs/tests/integration/page-screenshot.spec.js +1 -1
  168. package/dist/cjs/tests/integration/page-screenshot.spec.js.map +1 -1
  169. package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
  170. package/dist/cjs/tests/integration/testUtils.js +144 -0
  171. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  172. package/dist/cjs/tests/integration/timeouts.spec.js +278 -0
  173. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  174. package/dist/cjs/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  175. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js +285 -0
  176. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  177. package/dist/cjs/tests/unit/agent-execution-model.test.js +1 -1
  178. package/dist/cjs/tests/unit/agent-execution-model.test.js.map +1 -1
  179. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js +20 -0
  180. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  181. package/dist/cjs/tests/unit/captcha-solver.test.d.ts +1 -0
  182. package/dist/cjs/tests/unit/captcha-solver.test.js +154 -0
  183. package/dist/cjs/tests/unit/captcha-solver.test.js.map +1 -0
  184. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  185. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
  186. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  187. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  188. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
  189. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  190. package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  191. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
  192. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  193. package/dist/cjs/tests/unit/llm-middleware.test.d.ts +1 -0
  194. package/dist/cjs/tests/unit/llm-middleware.test.js +495 -0
  195. package/dist/cjs/tests/unit/llm-middleware.test.js.map +1 -0
  196. package/dist/cjs/tests/unit/model-deprecation.test.js +5 -8
  197. package/dist/cjs/tests/unit/model-deprecation.test.js.map +1 -1
  198. package/dist/cjs/tests/unit/openai-cua-client.test.d.ts +1 -0
  199. package/dist/cjs/tests/unit/openai-cua-client.test.js +71 -0
  200. package/dist/cjs/tests/unit/openai-cua-client.test.js.map +1 -0
  201. package/dist/cjs/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  202. package/dist/cjs/tests/unit/page-extra-http-headers.test.js +92 -0
  203. package/dist/cjs/tests/unit/page-extra-http-headers.test.js.map +1 -0
  204. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +13 -1
  205. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  206. package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
  207. package/dist/esm/lib/inference.js +1 -4
  208. package/dist/esm/lib/inference.js.map +1 -1
  209. package/dist/esm/lib/utils.d.ts +1 -0
  210. package/dist/esm/lib/utils.js +3 -0
  211. package/dist/esm/lib/utils.js.map +1 -1
  212. package/dist/esm/lib/v3/agent/AgentClient.d.ts +8 -0
  213. package/dist/esm/lib/v3/agent/AgentClient.js +13 -0
  214. package/dist/esm/lib/v3/agent/AgentClient.js.map +1 -1
  215. package/dist/esm/lib/v3/agent/AgentProvider.js +0 -1
  216. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  217. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +6 -7
  218. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  219. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +6 -7
  220. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  221. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  222. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  223. package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +4 -4
  224. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +67 -8
  225. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  226. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.d.ts +4 -2
  227. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js +7 -7
  228. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  229. package/dist/esm/lib/v3/agent/tools/act.d.ts +1 -1
  230. package/dist/esm/lib/v3/agent/tools/act.js +11 -4
  231. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  232. package/dist/esm/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  233. package/dist/esm/lib/v3/agent/tools/ariaTree.js +49 -22
  234. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  235. package/dist/esm/lib/v3/agent/tools/{search.js → braveSearch.js} +1 -1
  236. package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -0
  237. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.d.ts +13 -0
  238. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js +66 -0
  239. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -0
  240. package/dist/esm/lib/v3/agent/tools/click.js +23 -31
  241. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  242. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  243. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js +22 -30
  244. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  245. package/dist/esm/lib/v3/agent/tools/extract.d.ts +2 -2
  246. package/dist/esm/lib/v3/agent/tools/extract.js +7 -3
  247. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  248. package/dist/esm/lib/v3/agent/tools/fillFormVision.js +30 -30
  249. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  250. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +7 -2
  251. package/dist/esm/lib/v3/agent/tools/fillform.js +56 -45
  252. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  253. package/dist/esm/lib/v3/agent/tools/index.d.ts +19 -3
  254. package/dist/esm/lib/v3/agent/tools/index.js +63 -11
  255. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  256. package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
  257. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  258. package/dist/esm/lib/v3/agent/tools/screenshot.d.ts +8 -0
  259. package/dist/esm/lib/v3/agent/tools/screenshot.js +32 -15
  260. package/dist/esm/lib/v3/agent/tools/screenshot.js.map +1 -1
  261. package/dist/esm/lib/v3/agent/tools/scroll.js +12 -0
  262. package/dist/esm/lib/v3/agent/tools/scroll.js.map +1 -1
  263. package/dist/esm/lib/v3/agent/tools/type.js +23 -31
  264. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  265. package/dist/esm/lib/v3/agent/tools/wait.js +6 -0
  266. package/dist/esm/lib/v3/agent/tools/wait.js.map +1 -1
  267. package/dist/esm/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  268. package/dist/esm/lib/v3/agent/utils/captchaSolver.js +171 -0
  269. package/dist/esm/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  270. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  271. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  272. package/dist/esm/lib/v3/api.d.ts +2 -2
  273. package/dist/esm/lib/v3/api.js +1 -1
  274. package/dist/esm/lib/v3/api.js.map +1 -1
  275. package/dist/esm/lib/v3/cache/ActCache.d.ts +0 -1
  276. package/dist/esm/lib/v3/cache/ActCache.js +2 -18
  277. package/dist/esm/lib/v3/cache/ActCache.js.map +1 -1
  278. package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  279. package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
  280. package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  281. package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
  282. package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
  283. package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
  284. package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
  285. package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
  286. package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
  287. package/dist/esm/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  288. package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
  289. package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  290. package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
  291. package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
  292. package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
  293. package/dist/esm/lib/v3/handlers/actHandler.js +1 -2
  294. package/dist/esm/lib/v3/handlers/actHandler.js.map +1 -1
  295. package/dist/esm/lib/v3/handlers/extractHandler.js +2 -2
  296. package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
  297. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  298. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  299. package/dist/esm/lib/v3/handlers/observeHandler.js +1 -2
  300. package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
  301. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  302. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +131 -92
  303. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  304. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  305. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  306. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  307. package/dist/esm/lib/v3/index.d.ts +2 -1
  308. package/dist/esm/lib/v3/launch/browserbase.d.ts +1 -1
  309. package/dist/esm/lib/v3/launch/browserbase.js +4 -9
  310. package/dist/esm/lib/v3/launch/browserbase.js.map +1 -1
  311. package/dist/esm/lib/v3/llm/LLMProvider.d.ts +5 -2
  312. package/dist/esm/lib/v3/llm/LLMProvider.js +14 -12
  313. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  314. package/dist/esm/lib/v3/llm/aisdk.js +11 -17
  315. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  316. package/dist/esm/lib/v3/runtimePaths.js +2 -1
  317. package/dist/esm/lib/v3/runtimePaths.js.map +1 -1
  318. package/dist/esm/lib/v3/shutdown/supervisor.js +2 -2
  319. package/dist/esm/lib/v3/shutdown/supervisor.js.map +1 -1
  320. package/dist/esm/lib/v3/timeoutConfig.d.ts +1 -1
  321. package/dist/esm/lib/v3/timeoutConfig.js +5 -0
  322. package/dist/esm/lib/v3/timeoutConfig.js.map +1 -1
  323. package/dist/esm/lib/v3/types/private/cache.d.ts +0 -1
  324. package/dist/esm/lib/v3/types/private/cache.js.map +1 -1
  325. package/dist/esm/lib/v3/types/private/shutdown.d.ts +1 -1
  326. package/dist/esm/lib/v3/types/private/shutdown.js.map +1 -1
  327. package/dist/esm/lib/v3/types/public/agent.d.ts +28 -3
  328. package/dist/esm/lib/v3/types/public/agent.js +0 -1
  329. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  330. package/dist/esm/lib/v3/types/public/api.d.ts +7 -0
  331. package/dist/esm/lib/v3/types/public/api.js +9 -0
  332. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  333. package/dist/esm/lib/v3/types/public/model.d.ts +12 -3
  334. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  335. package/dist/esm/lib/v3/types/public/options.d.ts +8 -0
  336. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  337. package/dist/esm/lib/v3/understudy/cdp.d.ts +8 -13
  338. package/dist/esm/lib/v3/understudy/cdp.js +181 -21
  339. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  340. package/dist/esm/lib/v3/understudy/context.d.ts +1 -0
  341. package/dist/esm/lib/v3/understudy/context.js +142 -60
  342. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  343. package/dist/esm/lib/v3/understudy/frame.js +23 -6
  344. package/dist/esm/lib/v3/understudy/frame.js.map +1 -1
  345. package/dist/esm/lib/v3/understudy/page.d.ts +13 -0
  346. package/dist/esm/lib/v3/understudy/page.js +86 -23
  347. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  348. package/dist/esm/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  349. package/dist/esm/lib/v3/understudy/screenshotUtils.js +0 -17
  350. package/dist/esm/lib/v3/understudy/screenshotUtils.js.map +1 -1
  351. package/dist/esm/lib/v3/v3.d.ts +26 -3
  352. package/dist/esm/lib/v3/v3.js +242 -181
  353. package/dist/esm/lib/v3/v3.js.map +1 -1
  354. package/dist/esm/lib/version.d.ts +1 -1
  355. package/dist/esm/lib/version.js +1 -1
  356. package/dist/esm/lib/version.js.map +1 -1
  357. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
  358. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +54 -0
  359. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  360. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js +6 -6
  361. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  362. package/dist/esm/tests/integration/cdp-session-detached.spec.js +1 -1
  363. package/dist/esm/tests/integration/cdp-session-detached.spec.js.map +1 -1
  364. package/dist/esm/tests/integration/context-addInitScript.spec.js +104 -11
  365. package/dist/esm/tests/integration/context-addInitScript.spec.js.map +1 -1
  366. package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
  367. package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
  368. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
  369. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  370. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js +217 -0
  371. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  372. package/dist/esm/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  373. package/dist/esm/tests/integration/page-extra-http-headers.spec.js +83 -0
  374. package/dist/esm/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  375. package/dist/esm/tests/integration/page-screenshot.spec.js +1 -1
  376. package/dist/esm/tests/integration/page-screenshot.spec.js.map +1 -1
  377. package/dist/esm/tests/integration/testUtils.d.ts +33 -0
  378. package/dist/esm/tests/integration/testUtils.js +138 -0
  379. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  380. package/dist/esm/tests/integration/timeouts.spec.js +278 -0
  381. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  382. package/dist/esm/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  383. package/dist/esm/tests/unit/agent-captcha-hooks.test.js +283 -0
  384. package/dist/esm/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  385. package/dist/esm/tests/unit/agent-execution-model.test.js +1 -1
  386. package/dist/esm/tests/unit/agent-execution-model.test.js.map +1 -1
  387. package/dist/esm/tests/unit/browserbase-session-accessors.test.js +20 -0
  388. package/dist/esm/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  389. package/dist/esm/tests/unit/captcha-solver.test.d.ts +1 -0
  390. package/dist/esm/tests/unit/captcha-solver.test.js +152 -0
  391. package/dist/esm/tests/unit/captcha-solver.test.js.map +1 -0
  392. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  393. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
  394. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  395. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  396. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
  397. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  398. package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  399. package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
  400. package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  401. package/dist/esm/tests/unit/llm-middleware.test.d.ts +1 -0
  402. package/dist/esm/tests/unit/llm-middleware.test.js +460 -0
  403. package/dist/esm/tests/unit/llm-middleware.test.js.map +1 -0
  404. package/dist/esm/tests/unit/model-deprecation.test.js +5 -8
  405. package/dist/esm/tests/unit/model-deprecation.test.js.map +1 -1
  406. package/dist/esm/tests/unit/openai-cua-client.test.d.ts +1 -0
  407. package/dist/esm/tests/unit/openai-cua-client.test.js +69 -0
  408. package/dist/esm/tests/unit/openai-cua-client.test.js.map +1 -0
  409. package/dist/esm/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  410. package/dist/esm/tests/unit/page-extra-http-headers.test.js +90 -0
  411. package/dist/esm/tests/unit/page-extra-http-headers.test.js.map +1 -0
  412. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +13 -1
  413. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  414. package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
  415. package/package.json +5 -3
  416. package/dist/cjs/lib/v3/agent/tools/search.js.map +0 -1
  417. package/dist/cjs/lib/v3/flowLogger.d.ts +0 -139
  418. package/dist/cjs/lib/v3/flowLogger.js +0 -881
  419. package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
  420. package/dist/cjs/tests/unit/rerender-missing-shadows.test.js +0 -209
  421. package/dist/cjs/tests/unit/rerender-missing-shadows.test.js.map +0 -1
  422. package/dist/esm/lib/v3/agent/tools/search.js.map +0 -1
  423. package/dist/esm/lib/v3/flowLogger.d.ts +0 -139
  424. package/dist/esm/lib/v3/flowLogger.js +0 -868
  425. package/dist/esm/lib/v3/flowLogger.js.map +0 -1
  426. package/dist/esm/tests/unit/rerender-missing-shadows.test.js +0 -207
  427. package/dist/esm/tests/unit/rerender-missing-shadows.test.js.map +0 -1
  428. /package/dist/cjs/lib/v3/agent/tools/{search.d.ts → braveSearch.d.ts} +0 -0
  429. /package/dist/cjs/tests/{unit/rerender-missing-shadows.test.d.ts → integration/agent-captcha-autosolve.spec.d.ts} +0 -0
  430. /package/dist/{esm/tests/unit/rerender-missing-shadows.test.d.ts → cjs/tests/integration/flowLogger.spec.d.ts} +0 -0
  431. /package/dist/esm/lib/v3/agent/tools/{search.d.ts → braveSearch.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.1.0\" as const;\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../lib/version.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAgB,CAAC","sourcesContent":["/**\n * AUTO-GENERATED — DO NOT EDIT BY HAND\n * Run `pnpm run gen-version` to refresh.\n */\nexport const STAGEHAND_VERSION = \"3.2.0\" as const;\n"]}
@@ -0,0 +1,54 @@
1
+ import { test, expect } from "@playwright/test";
2
+ import { V3 } from "../../lib/v3/v3.js";
3
+ import { getV3TestConfig } from "./v3.config.js";
4
+ const isBrowserbase = (process.env.STAGEHAND_BROWSER_TARGET ?? "local").toLowerCase() ===
5
+ "browserbase";
6
+ test.describe("Agent captcha auto-solve on Browserbase", () => {
7
+ test.skip(!isBrowserbase, "Requires Browserbase environment");
8
+ let v3;
9
+ let logs;
10
+ test.beforeEach(async () => {
11
+ logs = [];
12
+ v3 = new V3(getV3TestConfig({
13
+ env: "BROWSERBASE",
14
+ verbose: 2,
15
+ logger: (line) => {
16
+ logs.push(line);
17
+ console.log(`[${line.category}] ${line.message}`);
18
+ },
19
+ browserbaseSessionCreateParams: {
20
+ browserSettings: {
21
+ solveCaptchas: true,
22
+ },
23
+ },
24
+ }));
25
+ await v3.init();
26
+ console.log("BB session URL:", v3.browserbaseSessionURL);
27
+ });
28
+ test.afterEach(async () => {
29
+ await v3?.close?.().catch(() => { });
30
+ });
31
+ test("reCAPTCHA v2 auto-solve (Google demo)", async () => {
32
+ test.setTimeout(180_000);
33
+ const page = v3.context.pages()[0];
34
+ // Google's official reCAPTCHA v2 demo — same URL the stealth team tests.
35
+ // Use domcontentloaded since BB's route interception can delay full load.
36
+ await page.goto("https://www.google.com/recaptcha/api2/demo", {
37
+ waitUntil: "domcontentloaded",
38
+ });
39
+ // Give BB time to intercept the anchor request and solve the captcha
40
+ await new Promise((r) => setTimeout(r, 30_000));
41
+ const agent = v3.agent({
42
+ mode: "dom",
43
+ model: "anthropic/claude-haiku-4-5-20251001",
44
+ });
45
+ const result = await agent.execute({
46
+ instruction: 'Click the "Submit" button and report the exact text shown on the result page.',
47
+ maxSteps: 15,
48
+ });
49
+ console.log("reCAPTCHA v2 result:", result.message);
50
+ expect(result.completed).toBe(true);
51
+ expect(result.message.toLowerCase()).toContain("success");
52
+ });
53
+ });
54
+ //# sourceMappingURL=agent-captcha-autosolve.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-captcha-autosolve.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-captcha-autosolve.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,MAAM,aAAa,GACjB,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE;IAC/D,aAAa,CAAC;AAEhB,IAAI,CAAC,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IAC5D,IAAI,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;IAE9D,IAAI,EAAM,CAAC;IACX,IAAI,IAAe,CAAC;IAEpB,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,IAAI,GAAG,EAAE,CAAC;QACV,EAAE,GAAG,IAAI,EAAE,CACT,eAAe,CAAC;YACd,GAAG,EAAE,aAAa;YAClB,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,CAAC,IAAa,EAAE,EAAE;gBACxB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,8BAA8B,EAAE;gBAC9B,eAAe,EAAE;oBACf,aAAa,EAAE,IAAI;iBACpB;aACF;SACF,CAAC,CACH,CAAC;QACF,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,EAAE,CAAC,qBAAqB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACvD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACnC,yEAAyE;QACzE,0EAA0E;QAC1E,MAAM,IAAI,CAAC,IAAI,CAAC,4CAA4C,EAAE;YAC5D,SAAS,EAAE,kBAAkB;SAC9B,CAAC,CAAC;QAEH,qEAAqE;QACrE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAEhD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC;YACrB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,qCAAqC;SAC7C,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;YACjC,WAAW,EACT,+EAA+E;YACjF,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QAEpD,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { getV3TestConfig } from \"./v3.config.js\";\nimport type { LogLine } from \"../../lib/v3/types/public/logs.js\";\n\nconst isBrowserbase =\n (process.env.STAGEHAND_BROWSER_TARGET ?? \"local\").toLowerCase() ===\n \"browserbase\";\n\ntest.describe(\"Agent captcha auto-solve on Browserbase\", () => {\n test.skip(!isBrowserbase, \"Requires Browserbase environment\");\n\n let v3: V3;\n let logs: LogLine[];\n\n test.beforeEach(async () => {\n logs = [];\n v3 = new V3(\n getV3TestConfig({\n env: \"BROWSERBASE\",\n verbose: 2,\n logger: (line: LogLine) => {\n logs.push(line);\n console.log(`[${line.category}] ${line.message}`);\n },\n browserbaseSessionCreateParams: {\n browserSettings: {\n solveCaptchas: true,\n },\n },\n }),\n );\n await v3.init();\n console.log(\"BB session URL:\", v3.browserbaseSessionURL);\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"reCAPTCHA v2 auto-solve (Google demo)\", async () => {\n test.setTimeout(180_000);\n const page = v3.context.pages()[0];\n // Google's official reCAPTCHA v2 demo — same URL the stealth team tests.\n // Use domcontentloaded since BB's route interception can delay full load.\n await page.goto(\"https://www.google.com/recaptcha/api2/demo\", {\n waitUntil: \"domcontentloaded\",\n });\n\n // Give BB time to intercept the anchor request and solve the captcha\n await new Promise((r) => setTimeout(r, 30_000));\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const result = await agent.execute({\n instruction:\n 'Click the \"Submit\" button and report the exact text shown on the result page.',\n maxSteps: 15,\n });\n\n console.log(\"reCAPTCHA v2 result:\", result.message);\n\n expect(result.completed).toBe(true);\n expect(result.message.toLowerCase()).toContain(\"success\");\n });\n});\n"]}
@@ -108,24 +108,24 @@ test.describe("Stagehand agent hybrid mode", () => {
108
108
  expect(prompt).toContain("customInstructions");
109
109
  expect(prompt).toContain(customInstructions);
110
110
  });
111
- test("System prompt includes Browserbase captcha message when isBrowserbase is true", () => {
111
+ test("System prompt includes captcha instructions when captchasAutoSolve is true", () => {
112
112
  const prompt = buildAgentSystemPrompt({
113
113
  url: "https://example.com",
114
114
  executionInstruction: "Test instruction",
115
115
  mode: "dom",
116
- isBrowserbase: true,
116
+ captchasAutoSolve: true,
117
117
  });
118
118
  expect(prompt).toContain("captcha");
119
- expect(prompt).toContain("automatically be solved");
119
+ expect(prompt).toContain("automatically detected and solved");
120
120
  });
121
- test("System prompt does not include captcha message when isBrowserbase is false", () => {
121
+ test("System prompt does not include captcha instructions when captchasAutoSolve is false", () => {
122
122
  const prompt = buildAgentSystemPrompt({
123
123
  url: "https://example.com",
124
124
  executionInstruction: "Test instruction",
125
125
  mode: "dom",
126
- isBrowserbase: false,
126
+ captchasAutoSolve: false,
127
127
  });
128
- expect(prompt).not.toContain("automatically be solved");
128
+ expect(prompt).not.toContain("automatically detected and solved");
129
129
  });
130
130
  });
131
131
  test.describe("Agent creation with mode", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-hybrid-mode.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-hybrid-mode.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { createAgentTools } from \"../../lib/v3/agent/tools/index.js\";\nimport { buildAgentSystemPrompt } from \"../../lib/v3/agent/prompts/agentSystemPrompt.js\";\nimport type { StepResult, ToolSet } from \"ai\";\n\ntest.describe(\"Stagehand agent hybrid mode\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3({\n ...v3TestConfig,\n experimental: true,\n });\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"Tool filtering by mode\", () => {\n test(\"DOM mode includes DOM-based tools and excludes coordinate-based tools\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n // DOM mode should have these tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // DOM mode should NOT have coordinate-based tools\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n expect(tools).not.toHaveProperty(\"dragAndDrop\");\n expect(tools).not.toHaveProperty(\"clickAndHold\");\n expect(tools).not.toHaveProperty(\"fillFormVision\");\n });\n\n test(\"Hybrid mode includes coordinate-based tools and excludes DOM fillForm\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n // Hybrid mode should have coordinate-based tools\n expect(tools).toHaveProperty(\"click\");\n expect(tools).toHaveProperty(\"type\");\n expect(tools).toHaveProperty(\"dragAndDrop\");\n expect(tools).toHaveProperty(\"clickAndHold\");\n expect(tools).toHaveProperty(\"fillFormVision\");\n\n // Hybrid mode should also have common tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // Hybrid mode should NOT have DOM-based fillForm\n expect(tools).not.toHaveProperty(\"fillForm\");\n });\n\n test(\"Default mode is DOM when not specified\", () => {\n const tools = createAgentTools(v3, {});\n\n // Should behave like DOM mode\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n });\n });\n\n test.describe(\"System prompt generation\", () => {\n test(\"DOM mode system prompt emphasizes ariaTree and act tool\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n });\n\n // DOM mode should prioritize ariaTree\n expect(prompt).toContain(\"ariaTree\");\n expect(prompt).toContain(\"act\");\n expect(prompt).toContain(\"fillForm\");\n\n // Should have DOM-specific strategy\n expect(prompt).toContain(\"Use act tool for all clicking and typing\");\n expect(prompt).toContain(\"Always check ariaTree first\");\n });\n\n test(\"Hybrid mode system prompt emphasizes screenshot and coordinate tools\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"hybrid\",\n });\n\n // Hybrid mode should have coordinate-based tools mentioned\n expect(prompt).toContain(\"click\");\n expect(prompt).toContain(\"type\");\n expect(prompt).toContain(\"fillFormVision\");\n expect(prompt).toContain(\"dragAndDrop\");\n\n // Should have hybrid-specific strategy\n expect(prompt).toContain(\n \"Use specific tools (click, type) when elements are visible\",\n );\n expect(prompt).toContain(\"Always use screenshot\");\n });\n\n test(\"System prompt includes custom instructions when provided\", () => {\n const customInstructions = \"Always be polite and thorough\";\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n systemInstructions: customInstructions,\n });\n\n expect(prompt).toContain(\"customInstructions\");\n expect(prompt).toContain(customInstructions);\n });\n\n test(\"System prompt includes Browserbase captcha message when isBrowserbase is true\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n isBrowserbase: true,\n });\n\n expect(prompt).toContain(\"captcha\");\n expect(prompt).toContain(\"automatically be solved\");\n });\n\n test(\"System prompt does not include captcha message when isBrowserbase is false\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n isBrowserbase: false,\n });\n\n expect(prompt).not.toContain(\"automatically be solved\");\n });\n });\n\n test.describe(\"Agent creation with mode\", () => {\n test(\"agent({ mode: 'dom' }) creates DOM-mode agent\", () => {\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent({ mode: 'hybrid' }) creates hybrid-mode agent\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent without mode defaults to DOM mode\", () => {\n const agent = v3.agent({\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"hybrid mode can be combined with streaming\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n stream: true,\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n });\n\n test.describe(\"Hybrid mode execution\", () => {\n test(\"hybrid mode agent uses coordinate-based tools when available\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Take a screenshot to see the page, then describe what you see briefly and mark the task as complete.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n const toolNames = toolCalls.map((tc) => tc.toolName);\n // Should include screenshot (hybrid mode emphasizes visual)\n expect(toolNames).toContain(\"screenshot\");\n });\n\n test(\"DOM mode agent uses DOM-based tools\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Use the ariaTree to understand the page, then provide the final requested output or a summary of the page.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n // Should include ariaTree (DOM mode emphasizes aria-based interaction)\n const toolNames = toolCalls.map((tc) => tc.toolName);\n expect(toolNames).toContain(\"ariaTree\");\n });\n });\n\n test.describe(\"Scroll tool variants by mode\", () => {\n test(\"DOM mode uses simple scroll tool without coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The DOM scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n\n test(\"Hybrid mode uses vision scroll tool with optional coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The hybrid scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n });\n\n test.describe(\"Keys tool availability in both modes\", () => {\n test(\"Keys tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n\n test(\"Keys tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n });\n\n test.describe(\"Think tool availability\", () => {\n test(\"Think tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"think\");\n });\n\n test(\"Think tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"think\");\n });\n });\n});\n"]}
1
+ {"version":3,"file":"agent-hybrid-mode.spec.js","sourceRoot":"","sources":["../../../../tests/integration/agent-hybrid-mode.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { createAgentTools } from \"../../lib/v3/agent/tools/index.js\";\nimport { buildAgentSystemPrompt } from \"../../lib/v3/agent/prompts/agentSystemPrompt.js\";\nimport type { StepResult, ToolSet } from \"ai\";\n\ntest.describe(\"Stagehand agent hybrid mode\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3({\n ...v3TestConfig,\n experimental: true,\n });\n await v3.init();\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test.describe(\"Tool filtering by mode\", () => {\n test(\"DOM mode includes DOM-based tools and excludes coordinate-based tools\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n // DOM mode should have these tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // DOM mode should NOT have coordinate-based tools\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n expect(tools).not.toHaveProperty(\"dragAndDrop\");\n expect(tools).not.toHaveProperty(\"clickAndHold\");\n expect(tools).not.toHaveProperty(\"fillFormVision\");\n });\n\n test(\"Hybrid mode includes coordinate-based tools and excludes DOM fillForm\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n // Hybrid mode should have coordinate-based tools\n expect(tools).toHaveProperty(\"click\");\n expect(tools).toHaveProperty(\"type\");\n expect(tools).toHaveProperty(\"dragAndDrop\");\n expect(tools).toHaveProperty(\"clickAndHold\");\n expect(tools).toHaveProperty(\"fillFormVision\");\n\n // Hybrid mode should also have common tools\n expect(tools).toHaveProperty(\"act\");\n expect(tools).toHaveProperty(\"ariaTree\");\n expect(tools).toHaveProperty(\"screenshot\");\n expect(tools).toHaveProperty(\"extract\");\n expect(tools).toHaveProperty(\"goto\");\n expect(tools).toHaveProperty(\"scroll\");\n expect(tools).toHaveProperty(\"wait\");\n expect(tools).toHaveProperty(\"navback\");\n expect(tools).toHaveProperty(\"keys\");\n expect(tools).toHaveProperty(\"think\");\n\n // Hybrid mode should NOT have DOM-based fillForm\n expect(tools).not.toHaveProperty(\"fillForm\");\n });\n\n test(\"Default mode is DOM when not specified\", () => {\n const tools = createAgentTools(v3, {});\n\n // Should behave like DOM mode\n expect(tools).toHaveProperty(\"fillForm\");\n expect(tools).not.toHaveProperty(\"click\");\n expect(tools).not.toHaveProperty(\"type\");\n });\n });\n\n test.describe(\"System prompt generation\", () => {\n test(\"DOM mode system prompt emphasizes ariaTree and act tool\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n });\n\n // DOM mode should prioritize ariaTree\n expect(prompt).toContain(\"ariaTree\");\n expect(prompt).toContain(\"act\");\n expect(prompt).toContain(\"fillForm\");\n\n // Should have DOM-specific strategy\n expect(prompt).toContain(\"Use act tool for all clicking and typing\");\n expect(prompt).toContain(\"Always check ariaTree first\");\n });\n\n test(\"Hybrid mode system prompt emphasizes screenshot and coordinate tools\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"hybrid\",\n });\n\n // Hybrid mode should have coordinate-based tools mentioned\n expect(prompt).toContain(\"click\");\n expect(prompt).toContain(\"type\");\n expect(prompt).toContain(\"fillFormVision\");\n expect(prompt).toContain(\"dragAndDrop\");\n\n // Should have hybrid-specific strategy\n expect(prompt).toContain(\n \"Use specific tools (click, type) when elements are visible\",\n );\n expect(prompt).toContain(\"Always use screenshot\");\n });\n\n test(\"System prompt includes custom instructions when provided\", () => {\n const customInstructions = \"Always be polite and thorough\";\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n systemInstructions: customInstructions,\n });\n\n expect(prompt).toContain(\"customInstructions\");\n expect(prompt).toContain(customInstructions);\n });\n\n test(\"System prompt includes captcha instructions when captchasAutoSolve is true\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n captchasAutoSolve: true,\n });\n\n expect(prompt).toContain(\"captcha\");\n expect(prompt).toContain(\"automatically detected and solved\");\n });\n\n test(\"System prompt does not include captcha instructions when captchasAutoSolve is false\", () => {\n const prompt = buildAgentSystemPrompt({\n url: \"https://example.com\",\n executionInstruction: \"Test instruction\",\n mode: \"dom\",\n captchasAutoSolve: false,\n });\n\n expect(prompt).not.toContain(\"automatically detected and solved\");\n });\n });\n\n test.describe(\"Agent creation with mode\", () => {\n test(\"agent({ mode: 'dom' }) creates DOM-mode agent\", () => {\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent({ mode: 'hybrid' }) creates hybrid-mode agent\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"agent without mode defaults to DOM mode\", () => {\n const agent = v3.agent({\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n\n test(\"hybrid mode can be combined with streaming\", () => {\n const agent = v3.agent({\n mode: \"hybrid\",\n stream: true,\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n expect(agent).toHaveProperty(\"execute\");\n });\n });\n\n test.describe(\"Hybrid mode execution\", () => {\n test(\"hybrid mode agent uses coordinate-based tools when available\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"hybrid\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Take a screenshot to see the page, then describe what you see briefly and mark the task as complete.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n const toolNames = toolCalls.map((tc) => tc.toolName);\n // Should include screenshot (hybrid mode emphasizes visual)\n expect(toolNames).toContain(\"screenshot\");\n });\n\n test(\"DOM mode agent uses DOM-based tools\", async () => {\n test.setTimeout(90000);\n\n const toolCalls: Array<{ toolName: string; input: unknown }> = [];\n\n const agent = v3.agent({\n mode: \"dom\",\n model: \"anthropic/claude-haiku-4-5-20251001\",\n });\n\n const page = v3.context.pages()[0];\n await page.goto(\"https://example.com\");\n\n await agent.execute({\n instruction:\n \"Use the ariaTree to understand the page, then provide the final requested output or a summary of the page.\",\n maxSteps: 5,\n callbacks: {\n onStepFinish: async (event: StepResult<ToolSet>) => {\n if (event.toolCalls) {\n for (const tc of event.toolCalls) {\n toolCalls.push({\n toolName: tc.toolName,\n input: tc.input,\n });\n }\n }\n },\n },\n });\n\n // Should have captured tool calls\n expect(toolCalls.length).toBeGreaterThan(0);\n\n // Should include ariaTree (DOM mode emphasizes aria-based interaction)\n const toolNames = toolCalls.map((tc) => tc.toolName);\n expect(toolNames).toContain(\"ariaTree\");\n });\n });\n\n test.describe(\"Scroll tool variants by mode\", () => {\n test(\"DOM mode uses simple scroll tool without coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The DOM scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n\n test(\"Hybrid mode uses vision scroll tool with optional coordinates\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n\n expect(tools).toHaveProperty(\"scroll\");\n // The hybrid scroll tool should exist\n expect(typeof tools.scroll).toBe(\"object\");\n });\n });\n\n test.describe(\"Keys tool availability in both modes\", () => {\n test(\"Keys tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n\n test(\"Keys tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"keys\");\n });\n });\n\n test.describe(\"Think tool availability\", () => {\n test(\"Think tool is available in DOM mode\", () => {\n const tools = createAgentTools(v3, { mode: \"dom\" });\n expect(tools).toHaveProperty(\"think\");\n });\n\n test(\"Think tool is available in hybrid mode\", () => {\n const tools = createAgentTools(v3, { mode: \"hybrid\" });\n expect(tools).toHaveProperty(\"think\");\n });\n });\n});\n"]}
@@ -30,7 +30,7 @@ test.describe("CDP session detach handling", () => {
30
30
  returnByValue: true,
31
31
  });
32
32
  await pwPage.close();
33
- await expect(pending).rejects.toThrow(/CDP session detached/);
33
+ await expect(pending).rejects.toThrow(/No Page found for target closed before CDP response/);
34
34
  await new Promise((r) => setTimeout(r, 50));
35
35
  expect(unhandled).toHaveLength(0);
36
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cdp-session-detached.spec.js","sourceRoot":"","sources":["../../../../tests/integration/cdp-session-detached.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,IAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAChD,IAAI,EAAM,CAAC;IAEX,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,EAAE,GAAG,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,CAAC,MAAe,EAAE,EAAE;YACtC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAE9C,IAAI,SAAS,GAEF,IAAI,CAAC;QAEhB,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAElE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBACjD,UAAU,EAAE,qDAAqD;gBACjE,YAAY,EAAE,IAAI;gBAClB,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YAErB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YAE9D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;YAC/C,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { chromium as playwrightChromium } from \"playwright\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\n\ntest.describe(\"CDP session detach handling\", () => {\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(\"rejects inflight CDP calls when a target is closed\", async () => {\n const unhandled: unknown[] = [];\n const onUnhandled = (reason: unknown) => {\n unhandled.push(reason);\n };\n\n process.on(\"unhandledRejection\", onUnhandled);\n\n let pwBrowser: Awaited<\n ReturnType<typeof playwrightChromium.connectOverCDP>\n > | null = null;\n\n try {\n pwBrowser = await playwrightChromium.connectOverCDP(v3.connectURL());\n const pwContext = pwBrowser.contexts()[0];\n const pwPage = pwContext.pages()[0];\n\n const v3Page = v3.context.pages()[0];\n await v3Page.goto(\"data:text/html,<html><body>cdp</body></html>\");\n\n const pending = v3Page.sendCDP(\"Runtime.evaluate\", {\n expression: \"new Promise(r => setTimeout(() => r('done'), 5000))\",\n awaitPromise: true,\n returnByValue: true,\n });\n\n await pwPage.close();\n\n await expect(pending).rejects.toThrow(/CDP session detached/);\n\n await new Promise((r) => setTimeout(r, 50));\n expect(unhandled).toHaveLength(0);\n } finally {\n process.off(\"unhandledRejection\", onUnhandled);\n await pwBrowser?.close().catch(() => {});\n }\n });\n});\n"]}
1
+ {"version":3,"file":"cdp-session-detached.spec.js","sourceRoot":"","sources":["../../../../tests/integration/cdp-session-detached.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,IAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAChD,IAAI,EAAM,CAAC;IAEX,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,EAAE,GAAG,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;QACxB,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,SAAS,GAAc,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,CAAC,MAAe,EAAE,EAAE;YACtC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CAAC;QAEF,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;QAE9C,IAAI,SAAS,GAEF,IAAI,CAAC;QAEhB,IAAI,CAAC;YACH,SAAS,GAAG,MAAM,kBAAkB,CAAC,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YAEpC,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;YAElE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBACjD,UAAU,EAAE,qDAAqD;gBACjE,YAAY,EAAE,IAAI;gBAClB,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;YAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YAErB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CACnC,qDAAqD,CACtD,CAAC;YAEF,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;YAC/C,MAAM,SAAS,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { chromium as playwrightChromium } from \"playwright\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\n\ntest.describe(\"CDP session detach handling\", () => {\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(\"rejects inflight CDP calls when a target is closed\", async () => {\n const unhandled: unknown[] = [];\n const onUnhandled = (reason: unknown) => {\n unhandled.push(reason);\n };\n\n process.on(\"unhandledRejection\", onUnhandled);\n\n let pwBrowser: Awaited<\n ReturnType<typeof playwrightChromium.connectOverCDP>\n > | null = null;\n\n try {\n pwBrowser = await playwrightChromium.connectOverCDP(v3.connectURL());\n const pwContext = pwBrowser.contexts()[0];\n const pwPage = pwContext.pages()[0];\n\n const v3Page = v3.context.pages()[0];\n await v3Page.goto(\"data:text/html,<html><body>cdp</body></html>\");\n\n const pending = v3Page.sendCDP(\"Runtime.evaluate\", {\n expression: \"new Promise(r => setTimeout(() => r('done'), 5000))\",\n awaitPromise: true,\n returnByValue: true,\n });\n\n await pwPage.close();\n\n await expect(pending).rejects.toThrow(\n /No Page found for target closed before CDP response/,\n );\n\n await new Promise((r) => setTimeout(r, 50));\n expect(unhandled).toHaveLength(0);\n } finally {\n process.off(\"unhandledRejection\", onUnhandled);\n await pwBrowser?.close().catch(() => {});\n }\n });\n});\n"]}
@@ -1,7 +1,28 @@
1
1
  import { test, expect } from "@playwright/test";
2
2
  import { V3 } from "../../lib/v3/v3.js";
3
3
  import { v3TestConfig } from "./v3.config.js";
4
+ const POPUP_TIMEOUT_MS = 20_000;
4
5
  const toDataUrl = (html) => `data:text/html,${encodeURIComponent(html)}`;
6
+ const waitForPopupPage = async (ctx, knownTargetIds, timeoutMs = POPUP_TIMEOUT_MS) => {
7
+ const deadline = Date.now() + timeoutMs;
8
+ while (Date.now() < deadline) {
9
+ const popup = ctx
10
+ .pages()
11
+ .find((page) => !knownTargetIds.has(page.targetId()));
12
+ if (popup)
13
+ return popup;
14
+ try {
15
+ const active = await ctx.awaitActivePage(500);
16
+ if (!knownTargetIds.has(active.targetId()))
17
+ return active;
18
+ }
19
+ catch {
20
+ // keep polling
21
+ }
22
+ await new Promise((resolve) => setTimeout(resolve, 50));
23
+ }
24
+ throw new Error("Popup page was not created");
25
+ };
5
26
  test.describe("context.addInitScript", () => {
6
27
  let v3;
7
28
  let ctx;
@@ -143,7 +164,7 @@ test.describe("context.addInitScript", () => {
143
164
  setPayload();
144
165
  }
145
166
  }, payload);
146
- const popupUrl = toDataUrl("<html><body>popup</body></html>");
167
+ const popupUrl = "https://example.com/";
147
168
  const openerHtml = "<!DOCTYPE html>" +
148
169
  "<html><body>" +
149
170
  '<a id="open" target="_blank" href="' +
@@ -152,23 +173,95 @@ test.describe("context.addInitScript", () => {
152
173
  "</body></html>";
153
174
  const opener = await ctx.awaitActivePage();
154
175
  await opener.goto(toDataUrl(openerHtml), { waitUntil: "load" });
176
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
155
177
  await opener.locator("#open").click();
156
- const openerId = opener.targetId();
157
- const deadline = Date.now() + 2000;
158
- let popup = ctx.pages().find((p) => p.targetId() !== openerId);
159
- while (!popup && Date.now() < deadline) {
160
- await opener.waitForTimeout(25);
161
- popup = ctx.pages().find((p) => p.targetId() !== openerId);
162
- }
163
- if (!popup) {
164
- throw new Error("Popup page was not created");
165
- }
178
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
166
179
  await popup.waitForLoadState("load");
167
180
  const observed = await popup.evaluate(() => {
168
181
  const raw = document.documentElement.dataset.initPayload;
169
182
  return raw ? JSON.parse(raw) : undefined;
170
183
  });
171
184
  expect(observed).toEqual(payload);
185
+ await popup.reload({ waitUntil: "load" });
186
+ const observedAfterReload = await popup.evaluate(() => {
187
+ const raw = document.documentElement.dataset.initPayload;
188
+ return raw ? JSON.parse(raw) : undefined;
189
+ });
190
+ expect(observedAfterReload).toEqual(payload);
191
+ });
192
+ test("applies script to in-process popup", async () => {
193
+ await ctx.addInitScript(() => {
194
+ window.__injected = 123;
195
+ });
196
+ const opener = await ctx.awaitActivePage();
197
+ const openerHtml = "<!DOCTYPE html>" +
198
+ "<html><body>" +
199
+ '<a id="open" target="_blank" href="about:blank">open</a>' +
200
+ "</body></html>";
201
+ await opener.goto(toDataUrl(openerHtml), { waitUntil: "load" });
202
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
203
+ await opener.locator("#open").click();
204
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
205
+ await popup.waitForLoadState("load");
206
+ const injected = await popup.evaluate(() => {
207
+ return window.__injected;
208
+ });
209
+ expect(injected).toBe(123);
210
+ });
211
+ test("applies script to cross-process popup and survives reload", async () => {
212
+ await ctx.addInitScript(() => {
213
+ window.__injected = 123;
214
+ });
215
+ const opener = await ctx.awaitActivePage();
216
+ const openerHtml = "<!DOCTYPE html>" +
217
+ "<html><body>" +
218
+ '<a id="open" target="_blank" href="https://example.com/">open</a>' +
219
+ "</body></html>";
220
+ await opener.goto(toDataUrl(openerHtml), {
221
+ waitUntil: "load",
222
+ });
223
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
224
+ await opener.locator("#open").click();
225
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
226
+ await popup.waitForLoadState("load");
227
+ const injected = await popup.evaluate(() => {
228
+ return window.__injected;
229
+ });
230
+ expect(injected).toBe(123);
231
+ await popup.reload({ waitUntil: "load" });
232
+ const injectedAfterReload = await popup.evaluate(() => {
233
+ return window.__injected;
234
+ });
235
+ expect(injectedAfterReload).toBe(123);
236
+ });
237
+ test("applies script to cross-process popup opened via window.open and survives reload", async () => {
238
+ await ctx.addInitScript(() => {
239
+ window.__injected = 789;
240
+ });
241
+ const opener = await ctx.awaitActivePage();
242
+ await opener.goto("about:blank", { waitUntil: "load" });
243
+ await opener.mainFrame().evaluate(() => {
244
+ const button = document.createElement("button");
245
+ button.id = "open-via-window-open";
246
+ button.textContent = "open popup";
247
+ button.addEventListener("click", () => {
248
+ window.open("https://example.com/", "_blank");
249
+ });
250
+ document.body.appendChild(button);
251
+ });
252
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
253
+ await opener.locator("#open-via-window-open").click();
254
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
255
+ await popup.waitForLoadState("load");
256
+ const injected = await popup.evaluate(() => {
257
+ return window.__injected;
258
+ });
259
+ expect(injected).toBe(789);
260
+ await popup.reload({ waitUntil: "load" });
261
+ const injectedAfterReload = await popup.evaluate(() => {
262
+ return window.__injected;
263
+ });
264
+ expect(injectedAfterReload).toBe(789);
172
265
  });
173
266
  test("context.addInitScript installs a function callable from page.evaluate", async () => {
174
267
  const page = await ctx.awaitActivePage();
@@ -1 +1 @@
1
- {"version":3,"file":"context-addInitScript.spec.js","sourceRoot":"","sources":["../../../../tests/integration/context-addInitScript.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { V3Context } from \"../../lib/v3/understudy/context.js\";\n\nconst toDataUrl = (html: string): string =>\n `data:text/html,${encodeURIComponent(html)}`;\n\ntest.describe(\"context.addInitScript\", () => {\n let v3: V3;\n let ctx: V3Context;\n\n test.beforeEach(async () => {\n v3 = new V3(v3TestConfig);\n await v3.init();\n ctx = v3.context;\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"runs before inline document scripts on navigation\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(() => {\n (window as unknown as { __fromContextInit?: string }).__fromContextInit =\n \"injected-value\";\n });\n\n const html = `<!DOCTYPE html>\n <html>\n <body>\n <script>\n var value = (window && window.__fromContextInit) || 'missing';\n document.body.dataset.initWitness = value;\n </script>\n </body>\n </html>`;\n\n await page.goto(toDataUrl(html), { waitUntil: \"load\" });\n\n const observed = await page.evaluate(() => {\n return document.body.dataset.initWitness;\n });\n expect(observed).toBe(\"injected-value\");\n });\n\n test(\"re-applies the script on every navigation for the same page\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(`\n (function () {\n function markVisit() {\n var root = document.documentElement;\n if (!root) return;\n var current = Number(window.name || \"0\");\n var next = current + 1;\n window.name = String(next);\n root.dataset.visitCount = String(next);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", markVisit, {\n once: true,\n });\n } else {\n markVisit();\n }\n })();\n `);\n\n await page.goto(toDataUrl(\"<html><body>first</body></html>\"), {\n waitUntil: \"load\",\n });\n const first = await page.evaluate(() => {\n return Number(document.documentElement.dataset.visitCount ?? \"0\");\n });\n expect(first).toBe(1);\n\n await page.goto(toDataUrl(\"<html><body>second</body></html>\"), {\n waitUntil: \"load\",\n });\n const second = await page.evaluate(() => {\n return Number(document.documentElement.dataset.visitCount ?? \"0\");\n });\n expect(second).toBe(2);\n });\n\n test(\"applies script (with args) to newly created pages\", async () => {\n const payload = { greeting: \"hi\", nested: { count: 2 } };\n\n const initPayload = ((arg) => {\n function setPayload() {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }) as (arg: typeof payload) => void;\n await ctx.addInitScript(initPayload, payload);\n\n const newPage = await ctx.newPage();\n await newPage.goto(toDataUrl(\"<html><body>child</body></html>\"), {\n waitUntil: \"load\",\n });\n\n const observed = await newPage.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n });\n\n test(\"applies script to newPage(url) on initial document\", async () => {\n const payload = { marker: \"newPageUrl\" };\n\n await ctx.addInitScript((arg) => {\n function setPayload(): void {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }, payload);\n\n const newPage = await ctx.newPage(\n toDataUrl(\"<html><body>new page</body></html>\"),\n );\n await newPage.waitForLoadState(\"load\");\n\n const observed = await newPage.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n });\n\n test(\"applies script to pages opened via link clicks\", async () => {\n const payload = { marker: \"linkClick\" };\n\n await ctx.addInitScript((arg) => {\n function setPayload(): void {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }, payload);\n\n const popupUrl = toDataUrl(\"<html><body>popup</body></html>\");\n const openerHtml =\n \"<!DOCTYPE html>\" +\n \"<html><body>\" +\n '<a id=\"open\" target=\"_blank\" href=\"' +\n popupUrl +\n '\">open</a>' +\n \"</body></html>\";\n\n const opener = await ctx.awaitActivePage();\n await opener.goto(toDataUrl(openerHtml), { waitUntil: \"load\" });\n await opener.locator(\"#open\").click();\n\n const openerId = opener.targetId();\n const deadline = Date.now() + 2000;\n let popup = ctx.pages().find((p) => p.targetId() !== openerId);\n while (!popup && Date.now() < deadline) {\n await opener.waitForTimeout(25);\n popup = ctx.pages().find((p) => p.targetId() !== openerId);\n }\n if (!popup) {\n throw new Error(\"Popup page was not created\");\n }\n\n await popup.waitForLoadState(\"load\");\n\n const observed = await popup.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n });\n\n test(\"context.addInitScript installs a function callable from page.evaluate\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(() => {\n // installed before any navigation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n window.sayHelloFromStagehand = () => \"hello from stagehand\";\n });\n\n await page.goto(\"https://example.com\", { waitUntil: \"domcontentloaded\" });\n\n const result = await page.evaluate(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return window.sayHelloFromStagehand();\n });\n\n expect(result).toBe(\"hello from stagehand\");\n });\n});\n"]}
1
+ {"version":3,"file":"context-addInitScript.spec.js","sourceRoot":"","sources":["../../../../tests/integration/context-addInitScript.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3TestConfig } from \"./v3.config.js\";\nimport { V3Context } from \"../../lib/v3/understudy/context.js\";\nimport type { Page as V3Page } from \"../../lib/v3/understudy/page.js\";\n\nconst POPUP_TIMEOUT_MS = 20_000;\n\nconst toDataUrl = (html: string): string =>\n `data:text/html,${encodeURIComponent(html)}`;\n\nconst waitForPopupPage = async (\n ctx: V3Context,\n knownTargetIds: Set<string>,\n timeoutMs = POPUP_TIMEOUT_MS,\n): Promise<V3Page> => {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const popup = ctx\n .pages()\n .find((page) => !knownTargetIds.has(page.targetId()));\n if (popup) return popup;\n try {\n const active = await ctx.awaitActivePage(500);\n if (!knownTargetIds.has(active.targetId())) return active;\n } catch {\n // keep polling\n }\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n throw new Error(\"Popup page was not created\");\n};\n\ntest.describe(\"context.addInitScript\", () => {\n let v3: V3;\n let ctx: V3Context;\n\n test.beforeEach(async () => {\n v3 = new V3(v3TestConfig);\n await v3.init();\n ctx = v3.context;\n });\n\n test.afterEach(async () => {\n await v3?.close?.().catch(() => {});\n });\n\n test(\"runs before inline document scripts on navigation\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(() => {\n (window as unknown as { __fromContextInit?: string }).__fromContextInit =\n \"injected-value\";\n });\n\n const html = `<!DOCTYPE html>\n <html>\n <body>\n <script>\n var value = (window && window.__fromContextInit) || 'missing';\n document.body.dataset.initWitness = value;\n </script>\n </body>\n </html>`;\n\n await page.goto(toDataUrl(html), { waitUntil: \"load\" });\n\n const observed = await page.evaluate(() => {\n return document.body.dataset.initWitness;\n });\n expect(observed).toBe(\"injected-value\");\n });\n\n test(\"re-applies the script on every navigation for the same page\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(`\n (function () {\n function markVisit() {\n var root = document.documentElement;\n if (!root) return;\n var current = Number(window.name || \"0\");\n var next = current + 1;\n window.name = String(next);\n root.dataset.visitCount = String(next);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", markVisit, {\n once: true,\n });\n } else {\n markVisit();\n }\n })();\n `);\n\n await page.goto(toDataUrl(\"<html><body>first</body></html>\"), {\n waitUntil: \"load\",\n });\n const first = await page.evaluate(() => {\n return Number(document.documentElement.dataset.visitCount ?? \"0\");\n });\n expect(first).toBe(1);\n\n await page.goto(toDataUrl(\"<html><body>second</body></html>\"), {\n waitUntil: \"load\",\n });\n const second = await page.evaluate(() => {\n return Number(document.documentElement.dataset.visitCount ?? \"0\");\n });\n expect(second).toBe(2);\n });\n\n test(\"applies script (with args) to newly created pages\", async () => {\n const payload = { greeting: \"hi\", nested: { count: 2 } };\n\n const initPayload = ((arg) => {\n function setPayload() {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }) as (arg: typeof payload) => void;\n await ctx.addInitScript(initPayload, payload);\n\n const newPage = await ctx.newPage();\n await newPage.goto(toDataUrl(\"<html><body>child</body></html>\"), {\n waitUntil: \"load\",\n });\n\n const observed = await newPage.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n });\n\n test(\"applies script to newPage(url) on initial document\", async () => {\n const payload = { marker: \"newPageUrl\" };\n\n await ctx.addInitScript((arg) => {\n function setPayload(): void {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }, payload);\n\n const newPage = await ctx.newPage(\n toDataUrl(\"<html><body>new page</body></html>\"),\n );\n await newPage.waitForLoadState(\"load\");\n\n const observed = await newPage.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n });\n\n test(\"applies script to pages opened via link clicks\", async () => {\n const payload = { marker: \"linkClick\" };\n\n await ctx.addInitScript((arg) => {\n function setPayload(): void {\n const root = document.documentElement;\n if (!root) return;\n root.dataset.initPayload = JSON.stringify(arg);\n }\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setPayload, {\n once: true,\n });\n } else {\n setPayload();\n }\n }, payload);\n\n const popupUrl = \"https://example.com/\";\n const openerHtml =\n \"<!DOCTYPE html>\" +\n \"<html><body>\" +\n '<a id=\"open\" target=\"_blank\" href=\"' +\n popupUrl +\n '\">open</a>' +\n \"</body></html>\";\n\n const opener = await ctx.awaitActivePage();\n await opener.goto(toDataUrl(openerHtml), { waitUntil: \"load\" });\n const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));\n await opener.locator(\"#open\").click();\n\n const popup = await waitForPopupPage(ctx, knownTargetIds);\n\n await popup.waitForLoadState(\"load\");\n\n const observed = await popup.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observed).toEqual(payload);\n\n await popup.reload({ waitUntil: \"load\" });\n const observedAfterReload = await popup.evaluate(() => {\n const raw = document.documentElement.dataset.initPayload;\n return raw ? JSON.parse(raw) : undefined;\n });\n expect(observedAfterReload).toEqual(payload);\n });\n\n test(\"applies script to in-process popup\", async () => {\n await ctx.addInitScript(() => {\n (window as unknown as { __injected?: number }).__injected = 123;\n });\n\n const opener = await ctx.awaitActivePage();\n const openerHtml =\n \"<!DOCTYPE html>\" +\n \"<html><body>\" +\n '<a id=\"open\" target=\"_blank\" href=\"about:blank\">open</a>' +\n \"</body></html>\";\n await opener.goto(toDataUrl(openerHtml), { waitUntil: \"load\" });\n const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));\n await opener.locator(\"#open\").click();\n\n const popup = await waitForPopupPage(ctx, knownTargetIds);\n await popup.waitForLoadState(\"load\");\n const injected = await popup.evaluate(() => {\n return (window as unknown as { __injected?: number }).__injected;\n });\n expect(injected).toBe(123);\n });\n\n test(\"applies script to cross-process popup and survives reload\", async () => {\n await ctx.addInitScript(() => {\n (window as unknown as { __injected?: number }).__injected = 123;\n });\n\n const opener = await ctx.awaitActivePage();\n const openerHtml =\n \"<!DOCTYPE html>\" +\n \"<html><body>\" +\n '<a id=\"open\" target=\"_blank\" href=\"https://example.com/\">open</a>' +\n \"</body></html>\";\n await opener.goto(toDataUrl(openerHtml), {\n waitUntil: \"load\",\n });\n const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));\n await opener.locator(\"#open\").click();\n\n const popup = await waitForPopupPage(ctx, knownTargetIds);\n await popup.waitForLoadState(\"load\");\n\n const injected = await popup.evaluate(() => {\n return (window as unknown as { __injected?: number }).__injected;\n });\n expect(injected).toBe(123);\n\n await popup.reload({ waitUntil: \"load\" });\n const injectedAfterReload = await popup.evaluate(() => {\n return (window as unknown as { __injected?: number }).__injected;\n });\n expect(injectedAfterReload).toBe(123);\n });\n\n test(\"applies script to cross-process popup opened via window.open and survives reload\", async () => {\n await ctx.addInitScript(() => {\n (window as unknown as { __injected?: number }).__injected = 789;\n });\n\n const opener = await ctx.awaitActivePage();\n await opener.goto(\"about:blank\", { waitUntil: \"load\" });\n await opener.mainFrame().evaluate(() => {\n const button = document.createElement(\"button\");\n button.id = \"open-via-window-open\";\n button.textContent = \"open popup\";\n button.addEventListener(\"click\", () => {\n window.open(\"https://example.com/\", \"_blank\");\n });\n document.body.appendChild(button);\n });\n\n const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));\n await opener.locator(\"#open-via-window-open\").click();\n\n const popup = await waitForPopupPage(ctx, knownTargetIds);\n await popup.waitForLoadState(\"load\");\n\n const injected = await popup.evaluate(() => {\n return (window as unknown as { __injected?: number }).__injected;\n });\n expect(injected).toBe(789);\n\n await popup.reload({ waitUntil: \"load\" });\n const injectedAfterReload = await popup.evaluate(() => {\n return (window as unknown as { __injected?: number }).__injected;\n });\n expect(injectedAfterReload).toBe(789);\n });\n\n test(\"context.addInitScript installs a function callable from page.evaluate\", async () => {\n const page = await ctx.awaitActivePage();\n\n await ctx.addInitScript(() => {\n // installed before any navigation\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n window.sayHelloFromStagehand = () => \"hello from stagehand\";\n });\n\n await page.goto(\"https://example.com\", { waitUntil: \"domcontentloaded\" });\n\n const result = await page.evaluate(() => {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n return window.sayHelloFromStagehand();\n });\n\n expect(result).toBe(\"hello from stagehand\");\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};