@browserbasehq/orca 3.1.0-patch.4 → 3.2.0-middleware.2

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 (495) hide show
  1. package/dist/cjs/lib/inference.d.ts +3 -1
  2. package/dist/cjs/lib/inference.js +4 -7
  3. package/dist/cjs/lib/inference.js.map +1 -1
  4. package/dist/cjs/lib/prompt.d.ts +1 -1
  5. package/dist/cjs/lib/prompt.js +24 -18
  6. package/dist/cjs/lib/prompt.js.map +1 -1
  7. package/dist/cjs/lib/utils.d.ts +1 -0
  8. package/dist/cjs/lib/utils.js +4 -0
  9. package/dist/cjs/lib/utils.js.map +1 -1
  10. package/dist/cjs/lib/v3/agent/AgentClient.d.ts +8 -0
  11. package/dist/cjs/lib/v3/agent/AgentClient.js +13 -0
  12. package/dist/cjs/lib/v3/agent/AgentClient.js.map +1 -1
  13. package/dist/cjs/lib/v3/agent/AgentProvider.js +0 -1
  14. package/dist/cjs/lib/v3/agent/AgentProvider.js.map +1 -1
  15. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js +6 -7
  16. package/dist/cjs/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  17. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js +6 -7
  18. package/dist/cjs/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  19. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  20. package/dist/cjs/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  21. package/dist/cjs/lib/v3/agent/OpenAICUAClient.d.ts +10 -6
  22. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js +107 -18
  23. package/dist/cjs/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  24. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.d.ts +4 -2
  25. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js +11 -12
  26. package/dist/cjs/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  27. package/dist/cjs/lib/v3/agent/tools/act.d.ts +1 -1
  28. package/dist/cjs/lib/v3/agent/tools/act.js +11 -4
  29. package/dist/cjs/lib/v3/agent/tools/act.js.map +1 -1
  30. package/dist/cjs/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  31. package/dist/cjs/lib/v3/agent/tools/ariaTree.js +49 -22
  32. package/dist/cjs/lib/v3/agent/tools/ariaTree.js.map +1 -1
  33. package/dist/cjs/lib/v3/agent/tools/{search.js → braveSearch.js} +1 -1
  34. package/dist/cjs/lib/v3/agent/tools/braveSearch.js.map +1 -0
  35. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.d.ts +13 -0
  36. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js +70 -0
  37. package/dist/cjs/lib/v3/agent/tools/browserbaseSearch.js.map +1 -0
  38. package/dist/cjs/lib/v3/agent/tools/click.js +23 -31
  39. package/dist/cjs/lib/v3/agent/tools/click.js.map +1 -1
  40. package/dist/cjs/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  41. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js +22 -30
  42. package/dist/cjs/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  43. package/dist/cjs/lib/v3/agent/tools/extract.d.ts +2 -2
  44. package/dist/cjs/lib/v3/agent/tools/extract.js +7 -3
  45. package/dist/cjs/lib/v3/agent/tools/extract.js.map +1 -1
  46. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js +30 -30
  47. package/dist/cjs/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  48. package/dist/cjs/lib/v3/agent/tools/fillform.d.ts +7 -2
  49. package/dist/cjs/lib/v3/agent/tools/fillform.js +56 -45
  50. package/dist/cjs/lib/v3/agent/tools/fillform.js.map +1 -1
  51. package/dist/cjs/lib/v3/agent/tools/index.d.ts +19 -3
  52. package/dist/cjs/lib/v3/agent/tools/index.js +63 -11
  53. package/dist/cjs/lib/v3/agent/tools/index.js.map +1 -1
  54. package/dist/cjs/lib/v3/agent/tools/keys.d.ts +1 -1
  55. package/dist/cjs/lib/v3/agent/tools/keys.js.map +1 -1
  56. package/dist/cjs/lib/v3/agent/tools/screenshot.d.ts +8 -0
  57. package/dist/cjs/lib/v3/agent/tools/screenshot.js +32 -15
  58. package/dist/cjs/lib/v3/agent/tools/screenshot.js.map +1 -1
  59. package/dist/cjs/lib/v3/agent/tools/scroll.js +12 -0
  60. package/dist/cjs/lib/v3/agent/tools/scroll.js.map +1 -1
  61. package/dist/cjs/lib/v3/agent/tools/type.js +23 -31
  62. package/dist/cjs/lib/v3/agent/tools/type.js.map +1 -1
  63. package/dist/cjs/lib/v3/agent/tools/wait.js +6 -0
  64. package/dist/cjs/lib/v3/agent/tools/wait.js.map +1 -1
  65. package/dist/cjs/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  66. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js +175 -0
  67. package/dist/cjs/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  68. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  69. package/dist/cjs/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  70. package/dist/cjs/lib/v3/agent/utils/variables.d.ts +5 -0
  71. package/dist/cjs/lib/v3/agent/utils/variables.js +9 -0
  72. package/dist/cjs/lib/v3/agent/utils/variables.js.map +1 -1
  73. package/dist/cjs/lib/v3/api.d.ts +2 -2
  74. package/dist/cjs/lib/v3/api.js +1 -1
  75. package/dist/cjs/lib/v3/api.js.map +1 -1
  76. package/dist/cjs/lib/v3/cache/ActCache.d.ts +0 -1
  77. package/dist/cjs/lib/v3/cache/ActCache.js +2 -18
  78. package/dist/cjs/lib/v3/cache/ActCache.js.map +1 -1
  79. package/dist/cjs/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  80. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js +30 -0
  81. package/dist/cjs/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  82. package/dist/cjs/lib/v3/flowlogger/EventSink.d.ts +44 -0
  83. package/dist/cjs/lib/v3/flowlogger/EventSink.js +217 -0
  84. package/dist/cjs/lib/v3/flowlogger/EventSink.js.map +1 -0
  85. package/dist/cjs/lib/v3/flowlogger/EventStore.d.ts +26 -0
  86. package/dist/cjs/lib/v3/flowlogger/EventStore.js +135 -0
  87. package/dist/cjs/lib/v3/flowlogger/EventStore.js.map +1 -0
  88. package/dist/cjs/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  89. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js +591 -0
  90. package/dist/cjs/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  91. package/dist/cjs/lib/v3/flowlogger/prettify.d.ts +6 -0
  92. package/dist/cjs/lib/v3/flowlogger/prettify.js +395 -0
  93. package/dist/cjs/lib/v3/flowlogger/prettify.js.map +1 -0
  94. package/dist/cjs/lib/v3/handlers/actHandler.js +1 -2
  95. package/dist/cjs/lib/v3/handlers/actHandler.js.map +1 -1
  96. package/dist/cjs/lib/v3/handlers/extractHandler.js +2 -2
  97. package/dist/cjs/lib/v3/handlers/extractHandler.js.map +1 -1
  98. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  99. package/dist/cjs/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  100. package/dist/cjs/lib/v3/handlers/observeHandler.js +3 -3
  101. package/dist/cjs/lib/v3/handlers/observeHandler.js.map +1 -1
  102. package/dist/cjs/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  103. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js +130 -91
  104. package/dist/cjs/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  105. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  106. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  107. package/dist/cjs/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  108. package/dist/cjs/lib/v3/index.d.ts +2 -1
  109. package/dist/cjs/lib/v3/launch/browserbase.d.ts +1 -1
  110. package/dist/cjs/lib/v3/launch/browserbase.js +4 -9
  111. package/dist/cjs/lib/v3/launch/browserbase.js.map +1 -1
  112. package/dist/cjs/lib/v3/llm/LLMProvider.d.ts +5 -2
  113. package/dist/cjs/lib/v3/llm/LLMProvider.js +14 -11
  114. package/dist/cjs/lib/v3/llm/LLMProvider.js.map +1 -1
  115. package/dist/cjs/lib/v3/llm/aisdk.d.ts +3 -1
  116. package/dist/cjs/lib/v3/llm/aisdk.js +24 -28
  117. package/dist/cjs/lib/v3/llm/aisdk.js.map +1 -1
  118. package/dist/cjs/lib/v3/runtimePaths.js +2 -1
  119. package/dist/cjs/lib/v3/runtimePaths.js.map +1 -1
  120. package/dist/cjs/lib/v3/shutdown/supervisor.js +2 -2
  121. package/dist/cjs/lib/v3/shutdown/supervisor.js.map +1 -1
  122. package/dist/cjs/lib/v3/timeoutConfig.d.ts +1 -1
  123. package/dist/cjs/lib/v3/timeoutConfig.js +5 -0
  124. package/dist/cjs/lib/v3/timeoutConfig.js.map +1 -1
  125. package/dist/cjs/lib/v3/types/private/cache.d.ts +0 -1
  126. package/dist/cjs/lib/v3/types/private/cache.js.map +1 -1
  127. package/dist/cjs/lib/v3/types/private/handlers.d.ts +1 -0
  128. package/dist/cjs/lib/v3/types/private/handlers.js.map +1 -1
  129. package/dist/cjs/lib/v3/types/private/shutdown.d.ts +1 -1
  130. package/dist/cjs/lib/v3/types/private/shutdown.js.map +1 -1
  131. package/dist/cjs/lib/v3/types/public/agent.d.ts +28 -3
  132. package/dist/cjs/lib/v3/types/public/agent.js +0 -1
  133. package/dist/cjs/lib/v3/types/public/agent.js.map +1 -1
  134. package/dist/cjs/lib/v3/types/public/api.d.ts +27 -7
  135. package/dist/cjs/lib/v3/types/public/api.js +42 -14
  136. package/dist/cjs/lib/v3/types/public/api.js.map +1 -1
  137. package/dist/cjs/lib/v3/types/public/methods.d.ts +1 -0
  138. package/dist/cjs/lib/v3/types/public/methods.js.map +1 -1
  139. package/dist/cjs/lib/v3/types/public/model.d.ts +14 -3
  140. package/dist/cjs/lib/v3/types/public/model.js.map +1 -1
  141. package/dist/cjs/lib/v3/types/public/options.d.ts +8 -0
  142. package/dist/cjs/lib/v3/types/public/options.js.map +1 -1
  143. package/dist/cjs/lib/v3/types/public/variables.d.ts +7 -0
  144. package/dist/cjs/lib/v3/types/public/variables.js +22 -0
  145. package/dist/cjs/lib/v3/types/public/variables.js.map +1 -0
  146. package/dist/cjs/lib/v3/understudy/cdp.d.ts +8 -13
  147. package/dist/cjs/lib/v3/understudy/cdp.js +180 -20
  148. package/dist/cjs/lib/v3/understudy/cdp.js.map +1 -1
  149. package/dist/cjs/lib/v3/understudy/context.d.ts +1 -0
  150. package/dist/cjs/lib/v3/understudy/context.js +148 -62
  151. package/dist/cjs/lib/v3/understudy/context.js.map +1 -1
  152. package/dist/cjs/lib/v3/understudy/frame.js +23 -6
  153. package/dist/cjs/lib/v3/understudy/frame.js.map +1 -1
  154. package/dist/cjs/lib/v3/understudy/page.d.ts +13 -0
  155. package/dist/cjs/lib/v3/understudy/page.js +85 -22
  156. package/dist/cjs/lib/v3/understudy/page.js.map +1 -1
  157. package/dist/cjs/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  158. package/dist/cjs/lib/v3/understudy/screenshotUtils.js +0 -18
  159. package/dist/cjs/lib/v3/understudy/screenshotUtils.js.map +1 -1
  160. package/dist/cjs/lib/v3/v3.d.ts +26 -3
  161. package/dist/cjs/lib/v3/v3.js +250 -180
  162. package/dist/cjs/lib/v3/v3.js.map +1 -1
  163. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js +56 -0
  164. package/dist/cjs/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  165. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js +6 -6
  166. package/dist/cjs/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  167. package/dist/cjs/tests/integration/cdp-session-detached.spec.js +1 -1
  168. package/dist/cjs/tests/integration/cdp-session-detached.spec.js.map +1 -1
  169. package/dist/cjs/tests/integration/chrome-newtab-page-tracking.spec.js +56 -0
  170. package/dist/cjs/tests/integration/chrome-newtab-page-tracking.spec.js.map +1 -0
  171. package/dist/cjs/tests/integration/context-addInitScript.spec.js +104 -11
  172. package/dist/cjs/tests/integration/context-addInitScript.spec.js.map +1 -1
  173. package/dist/cjs/tests/integration/flowLogger.spec.d.ts +1 -0
  174. package/dist/cjs/tests/integration/flowLogger.spec.js +714 -0
  175. package/dist/cjs/tests/integration/flowLogger.spec.js.map +1 -0
  176. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  177. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js +219 -0
  178. package/dist/cjs/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  179. package/dist/cjs/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  180. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js +85 -0
  181. package/dist/cjs/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  182. package/dist/cjs/tests/integration/page-screenshot.spec.js +1 -1
  183. package/dist/cjs/tests/integration/page-screenshot.spec.js.map +1 -1
  184. package/dist/cjs/tests/integration/testUtils.d.ts +33 -0
  185. package/dist/cjs/tests/integration/testUtils.js +144 -0
  186. package/dist/cjs/tests/integration/testUtils.js.map +1 -1
  187. package/dist/cjs/tests/integration/timeouts.spec.js +278 -0
  188. package/dist/cjs/tests/integration/timeouts.spec.js.map +1 -1
  189. package/dist/cjs/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  190. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js +285 -0
  191. package/dist/cjs/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  192. package/dist/cjs/tests/unit/agent-execution-model.test.js +25 -3
  193. package/dist/cjs/tests/unit/agent-execution-model.test.js.map +1 -1
  194. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
  195. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js +23 -0
  196. package/dist/cjs/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
  197. package/dist/cjs/tests/unit/aisdk-reasoning-effort.test.d.ts +1 -0
  198. package/dist/cjs/tests/unit/aisdk-reasoning-effort.test.js +153 -0
  199. package/dist/cjs/tests/unit/aisdk-reasoning-effort.test.js.map +1 -0
  200. package/dist/cjs/tests/unit/api-client-observe-variables.test.d.ts +1 -0
  201. package/dist/cjs/tests/unit/api-client-observe-variables.test.js +86 -0
  202. package/dist/cjs/tests/unit/api-client-observe-variables.test.js.map +1 -0
  203. package/dist/cjs/tests/unit/api-variables-schema.test.d.ts +1 -0
  204. package/dist/cjs/tests/unit/api-variables-schema.test.js +37 -0
  205. package/dist/cjs/tests/unit/api-variables-schema.test.js.map +1 -0
  206. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js +20 -0
  207. package/dist/cjs/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  208. package/dist/cjs/tests/unit/captcha-solver.test.d.ts +1 -0
  209. package/dist/cjs/tests/unit/captcha-solver.test.js +154 -0
  210. package/dist/cjs/tests/unit/captcha-solver.test.js.map +1 -0
  211. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  212. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js +95 -0
  213. package/dist/cjs/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  214. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  215. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js +43 -0
  216. package/dist/cjs/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  217. package/dist/cjs/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  218. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js +250 -0
  219. package/dist/cjs/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  220. package/dist/cjs/tests/unit/llm-middleware.test.d.ts +1 -0
  221. package/dist/cjs/tests/unit/llm-middleware.test.js +495 -0
  222. package/dist/cjs/tests/unit/llm-middleware.test.js.map +1 -0
  223. package/dist/cjs/tests/unit/model-deprecation.test.js +5 -8
  224. package/dist/cjs/tests/unit/model-deprecation.test.js.map +1 -1
  225. package/dist/cjs/tests/unit/openai-cua-client.test.d.ts +1 -0
  226. package/dist/cjs/tests/unit/openai-cua-client.test.js +71 -0
  227. package/dist/cjs/tests/unit/openai-cua-client.test.js.map +1 -0
  228. package/dist/cjs/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  229. package/dist/cjs/tests/unit/page-extra-http-headers.test.js +92 -0
  230. package/dist/cjs/tests/unit/page-extra-http-headers.test.js.map +1 -0
  231. package/dist/cjs/tests/unit/prompt-observe-variables.test.d.ts +1 -0
  232. package/dist/cjs/tests/unit/prompt-observe-variables.test.js +19 -0
  233. package/dist/cjs/tests/unit/prompt-observe-variables.test.js.map +1 -0
  234. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js +13 -1
  235. package/dist/cjs/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  236. package/dist/cjs/tests/unit/public-api/public-types.test.js.map +1 -1
  237. package/dist/cjs/tests/unit/timeout-handlers.test.js +50 -0
  238. package/dist/cjs/tests/unit/timeout-handlers.test.js.map +1 -1
  239. package/dist/esm/lib/inference.d.ts +3 -1
  240. package/dist/esm/lib/inference.js +4 -7
  241. package/dist/esm/lib/inference.js.map +1 -1
  242. package/dist/esm/lib/prompt.d.ts +1 -1
  243. package/dist/esm/lib/prompt.js +24 -18
  244. package/dist/esm/lib/prompt.js.map +1 -1
  245. package/dist/esm/lib/utils.d.ts +1 -0
  246. package/dist/esm/lib/utils.js +3 -0
  247. package/dist/esm/lib/utils.js.map +1 -1
  248. package/dist/esm/lib/v3/agent/AgentClient.d.ts +8 -0
  249. package/dist/esm/lib/v3/agent/AgentClient.js +13 -0
  250. package/dist/esm/lib/v3/agent/AgentClient.js.map +1 -1
  251. package/dist/esm/lib/v3/agent/AgentProvider.js +0 -1
  252. package/dist/esm/lib/v3/agent/AgentProvider.js.map +1 -1
  253. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js +6 -7
  254. package/dist/esm/lib/v3/agent/AnthropicCUAClient.js.map +1 -1
  255. package/dist/esm/lib/v3/agent/GoogleCUAClient.js +6 -7
  256. package/dist/esm/lib/v3/agent/GoogleCUAClient.js.map +1 -1
  257. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js +1 -0
  258. package/dist/esm/lib/v3/agent/MicrosoftCUAClient.js.map +1 -1
  259. package/dist/esm/lib/v3/agent/OpenAICUAClient.d.ts +10 -6
  260. package/dist/esm/lib/v3/agent/OpenAICUAClient.js +107 -18
  261. package/dist/esm/lib/v3/agent/OpenAICUAClient.js.map +1 -1
  262. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.d.ts +4 -2
  263. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js +11 -12
  264. package/dist/esm/lib/v3/agent/prompts/agentSystemPrompt.js.map +1 -1
  265. package/dist/esm/lib/v3/agent/tools/act.d.ts +1 -1
  266. package/dist/esm/lib/v3/agent/tools/act.js +11 -4
  267. package/dist/esm/lib/v3/agent/tools/act.js.map +1 -1
  268. package/dist/esm/lib/v3/agent/tools/ariaTree.d.ts +8 -1
  269. package/dist/esm/lib/v3/agent/tools/ariaTree.js +49 -22
  270. package/dist/esm/lib/v3/agent/tools/ariaTree.js.map +1 -1
  271. package/dist/esm/lib/v3/agent/tools/{search.js → braveSearch.js} +1 -1
  272. package/dist/esm/lib/v3/agent/tools/braveSearch.js.map +1 -0
  273. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.d.ts +13 -0
  274. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js +66 -0
  275. package/dist/esm/lib/v3/agent/tools/browserbaseSearch.js.map +1 -0
  276. package/dist/esm/lib/v3/agent/tools/click.js +23 -31
  277. package/dist/esm/lib/v3/agent/tools/click.js.map +1 -1
  278. package/dist/esm/lib/v3/agent/tools/clickAndHold.js.map +1 -1
  279. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js +22 -30
  280. package/dist/esm/lib/v3/agent/tools/dragAndDrop.js.map +1 -1
  281. package/dist/esm/lib/v3/agent/tools/extract.d.ts +2 -2
  282. package/dist/esm/lib/v3/agent/tools/extract.js +7 -3
  283. package/dist/esm/lib/v3/agent/tools/extract.js.map +1 -1
  284. package/dist/esm/lib/v3/agent/tools/fillFormVision.js +30 -30
  285. package/dist/esm/lib/v3/agent/tools/fillFormVision.js.map +1 -1
  286. package/dist/esm/lib/v3/agent/tools/fillform.d.ts +7 -2
  287. package/dist/esm/lib/v3/agent/tools/fillform.js +56 -45
  288. package/dist/esm/lib/v3/agent/tools/fillform.js.map +1 -1
  289. package/dist/esm/lib/v3/agent/tools/index.d.ts +19 -3
  290. package/dist/esm/lib/v3/agent/tools/index.js +63 -11
  291. package/dist/esm/lib/v3/agent/tools/index.js.map +1 -1
  292. package/dist/esm/lib/v3/agent/tools/keys.d.ts +1 -1
  293. package/dist/esm/lib/v3/agent/tools/keys.js.map +1 -1
  294. package/dist/esm/lib/v3/agent/tools/screenshot.d.ts +8 -0
  295. package/dist/esm/lib/v3/agent/tools/screenshot.js +32 -15
  296. package/dist/esm/lib/v3/agent/tools/screenshot.js.map +1 -1
  297. package/dist/esm/lib/v3/agent/tools/scroll.js +12 -0
  298. package/dist/esm/lib/v3/agent/tools/scroll.js.map +1 -1
  299. package/dist/esm/lib/v3/agent/tools/type.js +23 -31
  300. package/dist/esm/lib/v3/agent/tools/type.js.map +1 -1
  301. package/dist/esm/lib/v3/agent/tools/wait.js +6 -0
  302. package/dist/esm/lib/v3/agent/tools/wait.js.map +1 -1
  303. package/dist/esm/lib/v3/agent/utils/captchaSolver.d.ts +76 -0
  304. package/dist/esm/lib/v3/agent/utils/captchaSolver.js +171 -0
  305. package/dist/esm/lib/v3/agent/utils/captchaSolver.js.map +1 -0
  306. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js +4 -0
  307. package/dist/esm/lib/v3/agent/utils/handleDoneToolCall.js.map +1 -1
  308. package/dist/esm/lib/v3/agent/utils/variables.d.ts +5 -0
  309. package/dist/esm/lib/v3/agent/utils/variables.js +8 -0
  310. package/dist/esm/lib/v3/agent/utils/variables.js.map +1 -1
  311. package/dist/esm/lib/v3/api.d.ts +2 -2
  312. package/dist/esm/lib/v3/api.js +1 -1
  313. package/dist/esm/lib/v3/api.js.map +1 -1
  314. package/dist/esm/lib/v3/cache/ActCache.d.ts +0 -1
  315. package/dist/esm/lib/v3/cache/ActCache.js +2 -18
  316. package/dist/esm/lib/v3/cache/ActCache.js.map +1 -1
  317. package/dist/esm/lib/v3/flowlogger/EventEmitter.d.ts +7 -0
  318. package/dist/esm/lib/v3/flowlogger/EventEmitter.js +26 -0
  319. package/dist/esm/lib/v3/flowlogger/EventEmitter.js.map +1 -0
  320. package/dist/esm/lib/v3/flowlogger/EventSink.d.ts +44 -0
  321. package/dist/esm/lib/v3/flowlogger/EventSink.js +206 -0
  322. package/dist/esm/lib/v3/flowlogger/EventSink.js.map +1 -0
  323. package/dist/esm/lib/v3/flowlogger/EventStore.d.ts +26 -0
  324. package/dist/esm/lib/v3/flowlogger/EventStore.js +127 -0
  325. package/dist/esm/lib/v3/flowlogger/EventStore.js.map +1 -0
  326. package/dist/esm/lib/v3/flowlogger/FlowLogger.d.ts +99 -0
  327. package/dist/esm/lib/v3/flowlogger/FlowLogger.js +583 -0
  328. package/dist/esm/lib/v3/flowlogger/FlowLogger.js.map +1 -0
  329. package/dist/esm/lib/v3/flowlogger/prettify.d.ts +6 -0
  330. package/dist/esm/lib/v3/flowlogger/prettify.js +389 -0
  331. package/dist/esm/lib/v3/flowlogger/prettify.js.map +1 -0
  332. package/dist/esm/lib/v3/handlers/actHandler.js +1 -2
  333. package/dist/esm/lib/v3/handlers/actHandler.js.map +1 -1
  334. package/dist/esm/lib/v3/handlers/extractHandler.js +2 -2
  335. package/dist/esm/lib/v3/handlers/extractHandler.js.map +1 -1
  336. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js +43 -57
  337. package/dist/esm/lib/v3/handlers/handlerUtils/actHandlerUtils.js.map +1 -1
  338. package/dist/esm/lib/v3/handlers/observeHandler.js +3 -3
  339. package/dist/esm/lib/v3/handlers/observeHandler.js.map +1 -1
  340. package/dist/esm/lib/v3/handlers/v3AgentHandler.d.ts +2 -5
  341. package/dist/esm/lib/v3/handlers/v3AgentHandler.js +131 -92
  342. package/dist/esm/lib/v3/handlers/v3AgentHandler.js.map +1 -1
  343. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.d.ts +5 -0
  344. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js +134 -14
  345. package/dist/esm/lib/v3/handlers/v3CuaAgentHandler.js.map +1 -1
  346. package/dist/esm/lib/v3/index.d.ts +2 -1
  347. package/dist/esm/lib/v3/launch/browserbase.d.ts +1 -1
  348. package/dist/esm/lib/v3/launch/browserbase.js +4 -9
  349. package/dist/esm/lib/v3/launch/browserbase.js.map +1 -1
  350. package/dist/esm/lib/v3/llm/LLMProvider.d.ts +5 -2
  351. package/dist/esm/lib/v3/llm/LLMProvider.js +15 -12
  352. package/dist/esm/lib/v3/llm/LLMProvider.js.map +1 -1
  353. package/dist/esm/lib/v3/llm/aisdk.d.ts +3 -1
  354. package/dist/esm/lib/v3/llm/aisdk.js +24 -28
  355. package/dist/esm/lib/v3/llm/aisdk.js.map +1 -1
  356. package/dist/esm/lib/v3/runtimePaths.js +2 -1
  357. package/dist/esm/lib/v3/runtimePaths.js.map +1 -1
  358. package/dist/esm/lib/v3/shutdown/supervisor.js +2 -2
  359. package/dist/esm/lib/v3/shutdown/supervisor.js.map +1 -1
  360. package/dist/esm/lib/v3/timeoutConfig.d.ts +1 -1
  361. package/dist/esm/lib/v3/timeoutConfig.js +5 -0
  362. package/dist/esm/lib/v3/timeoutConfig.js.map +1 -1
  363. package/dist/esm/lib/v3/types/private/cache.d.ts +0 -1
  364. package/dist/esm/lib/v3/types/private/cache.js.map +1 -1
  365. package/dist/esm/lib/v3/types/private/handlers.d.ts +1 -0
  366. package/dist/esm/lib/v3/types/private/handlers.js.map +1 -1
  367. package/dist/esm/lib/v3/types/private/shutdown.d.ts +1 -1
  368. package/dist/esm/lib/v3/types/private/shutdown.js.map +1 -1
  369. package/dist/esm/lib/v3/types/public/agent.d.ts +28 -3
  370. package/dist/esm/lib/v3/types/public/agent.js +0 -1
  371. package/dist/esm/lib/v3/types/public/agent.js.map +1 -1
  372. package/dist/esm/lib/v3/types/public/api.d.ts +27 -7
  373. package/dist/esm/lib/v3/types/public/api.js +37 -12
  374. package/dist/esm/lib/v3/types/public/api.js.map +1 -1
  375. package/dist/esm/lib/v3/types/public/methods.d.ts +1 -0
  376. package/dist/esm/lib/v3/types/public/methods.js.map +1 -1
  377. package/dist/esm/lib/v3/types/public/model.d.ts +14 -3
  378. package/dist/esm/lib/v3/types/public/model.js.map +1 -1
  379. package/dist/esm/lib/v3/types/public/options.d.ts +8 -0
  380. package/dist/esm/lib/v3/types/public/options.js.map +1 -1
  381. package/dist/esm/lib/v3/types/public/variables.d.ts +7 -0
  382. package/dist/esm/lib/v3/types/public/variables.js +19 -0
  383. package/dist/esm/lib/v3/types/public/variables.js.map +1 -0
  384. package/dist/esm/lib/v3/understudy/cdp.d.ts +8 -13
  385. package/dist/esm/lib/v3/understudy/cdp.js +181 -21
  386. package/dist/esm/lib/v3/understudy/cdp.js.map +1 -1
  387. package/dist/esm/lib/v3/understudy/context.d.ts +1 -0
  388. package/dist/esm/lib/v3/understudy/context.js +148 -62
  389. package/dist/esm/lib/v3/understudy/context.js.map +1 -1
  390. package/dist/esm/lib/v3/understudy/frame.js +23 -6
  391. package/dist/esm/lib/v3/understudy/frame.js.map +1 -1
  392. package/dist/esm/lib/v3/understudy/page.d.ts +13 -0
  393. package/dist/esm/lib/v3/understudy/page.js +87 -24
  394. package/dist/esm/lib/v3/understudy/page.js.map +1 -1
  395. package/dist/esm/lib/v3/understudy/screenshotUtils.d.ts +0 -1
  396. package/dist/esm/lib/v3/understudy/screenshotUtils.js +0 -17
  397. package/dist/esm/lib/v3/understudy/screenshotUtils.js.map +1 -1
  398. package/dist/esm/lib/v3/v3.d.ts +26 -3
  399. package/dist/esm/lib/v3/v3.js +250 -181
  400. package/dist/esm/lib/v3/v3.js.map +1 -1
  401. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.d.ts +1 -0
  402. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js +54 -0
  403. package/dist/esm/tests/integration/agent-captcha-autosolve.spec.js.map +1 -0
  404. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js +6 -6
  405. package/dist/esm/tests/integration/agent-hybrid-mode.spec.js.map +1 -1
  406. package/dist/esm/tests/integration/cdp-session-detached.spec.js +1 -1
  407. package/dist/esm/tests/integration/cdp-session-detached.spec.js.map +1 -1
  408. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.d.ts +1 -0
  409. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.js +54 -0
  410. package/dist/esm/tests/integration/chrome-newtab-page-tracking.spec.js.map +1 -0
  411. package/dist/esm/tests/integration/context-addInitScript.spec.js +104 -11
  412. package/dist/esm/tests/integration/context-addInitScript.spec.js.map +1 -1
  413. package/dist/esm/tests/integration/flowLogger.spec.d.ts +1 -0
  414. package/dist/esm/tests/integration/flowLogger.spec.js +712 -0
  415. package/dist/esm/tests/integration/flowLogger.spec.js.map +1 -0
  416. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.d.ts +1 -0
  417. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js +217 -0
  418. package/dist/esm/tests/integration/iframe-ctx-addInitScript-race.spec.js.map +1 -0
  419. package/dist/esm/tests/integration/page-extra-http-headers.spec.d.ts +1 -0
  420. package/dist/esm/tests/integration/page-extra-http-headers.spec.js +83 -0
  421. package/dist/esm/tests/integration/page-extra-http-headers.spec.js.map +1 -0
  422. package/dist/esm/tests/integration/page-screenshot.spec.js +1 -1
  423. package/dist/esm/tests/integration/page-screenshot.spec.js.map +1 -1
  424. package/dist/esm/tests/integration/testUtils.d.ts +33 -0
  425. package/dist/esm/tests/integration/testUtils.js +138 -0
  426. package/dist/esm/tests/integration/testUtils.js.map +1 -1
  427. package/dist/esm/tests/integration/timeouts.spec.js +278 -0
  428. package/dist/esm/tests/integration/timeouts.spec.js.map +1 -1
  429. package/dist/esm/tests/unit/agent-captcha-hooks.test.d.ts +1 -0
  430. package/dist/esm/tests/unit/agent-captcha-hooks.test.js +283 -0
  431. package/dist/esm/tests/unit/agent-captcha-hooks.test.js.map +1 -0
  432. package/dist/esm/tests/unit/agent-execution-model.test.js +25 -3
  433. package/dist/esm/tests/unit/agent-execution-model.test.js.map +1 -1
  434. package/dist/esm/tests/unit/agent-system-prompt-variables.test.d.ts +1 -0
  435. package/dist/esm/tests/unit/agent-system-prompt-variables.test.js +21 -0
  436. package/dist/esm/tests/unit/agent-system-prompt-variables.test.js.map +1 -0
  437. package/dist/esm/tests/unit/aisdk-reasoning-effort.test.d.ts +1 -0
  438. package/dist/esm/tests/unit/aisdk-reasoning-effort.test.js +118 -0
  439. package/dist/esm/tests/unit/aisdk-reasoning-effort.test.js.map +1 -0
  440. package/dist/esm/tests/unit/api-client-observe-variables.test.d.ts +1 -0
  441. package/dist/esm/tests/unit/api-client-observe-variables.test.js +84 -0
  442. package/dist/esm/tests/unit/api-client-observe-variables.test.js.map +1 -0
  443. package/dist/esm/tests/unit/api-variables-schema.test.d.ts +1 -0
  444. package/dist/esm/tests/unit/api-variables-schema.test.js +35 -0
  445. package/dist/esm/tests/unit/api-variables-schema.test.js.map +1 -0
  446. package/dist/esm/tests/unit/browserbase-session-accessors.test.js +20 -0
  447. package/dist/esm/tests/unit/browserbase-session-accessors.test.js.map +1 -1
  448. package/dist/esm/tests/unit/captcha-solver.test.d.ts +1 -0
  449. package/dist/esm/tests/unit/captcha-solver.test.js +152 -0
  450. package/dist/esm/tests/unit/captcha-solver.test.js.map +1 -0
  451. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.d.ts +1 -0
  452. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js +93 -0
  453. package/dist/esm/tests/unit/flowlogger-capturing-cdp.test.js.map +1 -0
  454. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.d.ts +1 -0
  455. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js +41 -0
  456. package/dist/esm/tests/unit/flowlogger-capturing-llm.test.js.map +1 -0
  457. package/dist/esm/tests/unit/flowlogger-eventstore.test.d.ts +1 -0
  458. package/dist/esm/tests/unit/flowlogger-eventstore.test.js +248 -0
  459. package/dist/esm/tests/unit/flowlogger-eventstore.test.js.map +1 -0
  460. package/dist/esm/tests/unit/llm-middleware.test.d.ts +1 -0
  461. package/dist/esm/tests/unit/llm-middleware.test.js +460 -0
  462. package/dist/esm/tests/unit/llm-middleware.test.js.map +1 -0
  463. package/dist/esm/tests/unit/model-deprecation.test.js +5 -8
  464. package/dist/esm/tests/unit/model-deprecation.test.js.map +1 -1
  465. package/dist/esm/tests/unit/openai-cua-client.test.d.ts +1 -0
  466. package/dist/esm/tests/unit/openai-cua-client.test.js +69 -0
  467. package/dist/esm/tests/unit/openai-cua-client.test.js.map +1 -0
  468. package/dist/esm/tests/unit/page-extra-http-headers.test.d.ts +1 -0
  469. package/dist/esm/tests/unit/page-extra-http-headers.test.js +90 -0
  470. package/dist/esm/tests/unit/page-extra-http-headers.test.js.map +1 -0
  471. package/dist/esm/tests/unit/prompt-observe-variables.test.d.ts +1 -0
  472. package/dist/esm/tests/unit/prompt-observe-variables.test.js +17 -0
  473. package/dist/esm/tests/unit/prompt-observe-variables.test.js.map +1 -0
  474. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js +13 -1
  475. package/dist/esm/tests/unit/public-api/llm-and-agents.test.js.map +1 -1
  476. package/dist/esm/tests/unit/public-api/public-types.test.js.map +1 -1
  477. package/dist/esm/tests/unit/timeout-handlers.test.js +50 -0
  478. package/dist/esm/tests/unit/timeout-handlers.test.js.map +1 -1
  479. package/package.json +6 -4
  480. package/dist/cjs/lib/v3/agent/tools/search.js.map +0 -1
  481. package/dist/cjs/lib/v3/flowLogger.d.ts +0 -139
  482. package/dist/cjs/lib/v3/flowLogger.js +0 -881
  483. package/dist/cjs/lib/v3/flowLogger.js.map +0 -1
  484. package/dist/cjs/tests/unit/rerender-missing-shadows.test.js +0 -209
  485. package/dist/cjs/tests/unit/rerender-missing-shadows.test.js.map +0 -1
  486. package/dist/esm/lib/v3/agent/tools/search.js.map +0 -1
  487. package/dist/esm/lib/v3/flowLogger.d.ts +0 -139
  488. package/dist/esm/lib/v3/flowLogger.js +0 -868
  489. package/dist/esm/lib/v3/flowLogger.js.map +0 -1
  490. package/dist/esm/tests/unit/rerender-missing-shadows.test.js +0 -207
  491. package/dist/esm/tests/unit/rerender-missing-shadows.test.js.map +0 -1
  492. /package/dist/cjs/lib/v3/agent/tools/{search.d.ts → braveSearch.d.ts} +0 -0
  493. /package/dist/cjs/tests/{unit/rerender-missing-shadows.test.d.ts → integration/agent-captcha-autosolve.spec.d.ts} +0 -0
  494. /package/dist/{esm/tests/unit/rerender-missing-shadows.test.d.ts → cjs/tests/integration/chrome-newtab-page-tracking.spec.d.ts} +0 -0
  495. /package/dist/esm/lib/v3/agent/tools/{search.d.ts → braveSearch.d.ts} +0 -0
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
4
+ const v3_js_1 = require("../../lib/v3/v3.js");
5
+ const v3_config_js_1 = require("./v3.config.js");
6
+ const isBrowserbase = (process.env.STAGEHAND_BROWSER_TARGET ?? "local").toLowerCase() ===
7
+ "browserbase";
8
+ test_1.test.describe("Agent captcha auto-solve on Browserbase", () => {
9
+ test_1.test.skip(!isBrowserbase, "Requires Browserbase environment");
10
+ let v3;
11
+ let logs;
12
+ test_1.test.beforeEach(async () => {
13
+ logs = [];
14
+ v3 = new v3_js_1.V3((0, v3_config_js_1.getV3TestConfig)({
15
+ env: "BROWSERBASE",
16
+ verbose: 2,
17
+ logger: (line) => {
18
+ logs.push(line);
19
+ console.log(`[${line.category}] ${line.message}`);
20
+ },
21
+ browserbaseSessionCreateParams: {
22
+ browserSettings: {
23
+ solveCaptchas: true,
24
+ },
25
+ },
26
+ }));
27
+ await v3.init();
28
+ console.log("BB session URL:", v3.browserbaseSessionURL);
29
+ });
30
+ test_1.test.afterEach(async () => {
31
+ await v3?.close?.().catch(() => { });
32
+ });
33
+ (0, test_1.test)("reCAPTCHA v2 auto-solve (Google demo)", async () => {
34
+ test_1.test.setTimeout(180_000);
35
+ const page = v3.context.pages()[0];
36
+ // Google's official reCAPTCHA v2 demo — same URL the stealth team tests.
37
+ // Use domcontentloaded since BB's route interception can delay full load.
38
+ await page.goto("https://www.google.com/recaptcha/api2/demo", {
39
+ waitUntil: "domcontentloaded",
40
+ });
41
+ // Give BB time to intercept the anchor request and solve the captcha
42
+ await new Promise((r) => setTimeout(r, 30_000));
43
+ const agent = v3.agent({
44
+ mode: "dom",
45
+ model: "anthropic/claude-haiku-4-5-20251001",
46
+ });
47
+ const result = await agent.execute({
48
+ instruction: 'Click the "Submit" button and report the exact text shown on the result page.',
49
+ maxSteps: 15,
50
+ });
51
+ console.log("reCAPTCHA v2 result:", result.message);
52
+ (0, test_1.expect)(result.completed).toBe(true);
53
+ (0, test_1.expect)(result.message.toLowerCase()).toContain("success");
54
+ });
55
+ });
56
+ //# 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,2CAAgD;AAChD,8CAAwC;AACxC,iDAAiD;AAGjD,MAAM,aAAa,GACjB,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE;IAC/D,aAAa,CAAC;AAEhB,WAAI,CAAC,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IAC5D,WAAI,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;IAE9D,IAAI,EAAM,CAAC;IACX,IAAI,IAAe,CAAC;IAEpB,WAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,IAAI,GAAG,EAAE,CAAC;QACV,EAAE,GAAG,IAAI,UAAE,CACT,IAAA,8BAAe,EAAC;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,WAAI,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,IAAA,WAAI,EAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACvD,WAAI,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,IAAA,aAAM,EAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAA,aAAM,EAAC,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"]}
@@ -110,24 +110,24 @@ test_1.test.describe("Stagehand agent hybrid mode", () => {
110
110
  (0, test_1.expect)(prompt).toContain("customInstructions");
111
111
  (0, test_1.expect)(prompt).toContain(customInstructions);
112
112
  });
113
- (0, test_1.test)("System prompt includes Browserbase captcha message when isBrowserbase is true", () => {
113
+ (0, test_1.test)("System prompt includes captcha instructions when captchasAutoSolve is true", () => {
114
114
  const prompt = (0, agentSystemPrompt_js_1.buildAgentSystemPrompt)({
115
115
  url: "https://example.com",
116
116
  executionInstruction: "Test instruction",
117
117
  mode: "dom",
118
- isBrowserbase: true,
118
+ captchasAutoSolve: true,
119
119
  });
120
120
  (0, test_1.expect)(prompt).toContain("captcha");
121
- (0, test_1.expect)(prompt).toContain("automatically be solved");
121
+ (0, test_1.expect)(prompt).toContain("automatically detected and solved");
122
122
  });
123
- (0, test_1.test)("System prompt does not include captcha message when isBrowserbase is false", () => {
123
+ (0, test_1.test)("System prompt does not include captcha instructions when captchasAutoSolve is false", () => {
124
124
  const prompt = (0, agentSystemPrompt_js_1.buildAgentSystemPrompt)({
125
125
  url: "https://example.com",
126
126
  executionInstruction: "Test instruction",
127
127
  mode: "dom",
128
- isBrowserbase: false,
128
+ captchasAutoSolve: false,
129
129
  });
130
- (0, test_1.expect)(prompt).not.toContain("automatically be solved");
130
+ (0, test_1.expect)(prompt).not.toContain("automatically detected and solved");
131
131
  });
132
132
  });
133
133
  test_1.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"]}
@@ -32,7 +32,7 @@ test_1.test.describe("CDP session detach handling", () => {
32
32
  returnByValue: true,
33
33
  });
34
34
  await pwPage.close();
35
- await (0, test_1.expect)(pending).rejects.toThrow(/CDP session detached/);
35
+ await (0, test_1.expect)(pending).rejects.toThrow(/No Page found for target closed before CDP response/);
36
36
  await new Promise((r) => setTimeout(r, 50));
37
37
  (0, test_1.expect)(unhandled).toHaveLength(0);
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cdp-session-detached.spec.js","sourceRoot":"","sources":["../../../../tests/integration/cdp-session-detached.spec.ts"],"names":[],"mappings":";;AAAA,2CAAgD;AAChD,2CAA4D;AAC5D,8CAAwC;AACxC,iDAA8C;AAE9C,WAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAChD,IAAI,EAAM,CAAC;IAEX,WAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,EAAE,GAAG,IAAI,UAAE,CAAC,2BAAY,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,WAAI,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,IAAA,WAAI,EAAC,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,qBAAkB,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,IAAA,aAAM,EAAC,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,IAAA,aAAM,EAAC,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,2CAAgD;AAChD,2CAA4D;AAC5D,8CAAwC;AACxC,iDAA8C;AAE9C,WAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAChD,IAAI,EAAM,CAAC;IAEX,WAAI,CAAC,UAAU,CAAC,KAAK,IAAI,EAAE;QACzB,EAAE,GAAG,IAAI,UAAE,CAAC,2BAAY,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,WAAI,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,IAAA,WAAI,EAAC,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,qBAAkB,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,IAAA,aAAM,EAAC,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,IAAA,aAAM,EAAC,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"]}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
4
+ const v3_js_1 = require("../../lib/v3/v3.js");
5
+ const v3_dynamic_config_js_1 = require("./v3.dynamic.config.js");
6
+ const testUtils_js_1 = require("./testUtils.js");
7
+ test_1.test.describe("V3 chrome:// new-tab page tracking", () => {
8
+ let v3;
9
+ test_1.test.beforeEach(async () => {
10
+ v3 = new v3_js_1.V3(v3_dynamic_config_js_1.v3DynamicTestConfig);
11
+ await v3.init();
12
+ });
13
+ test_1.test.afterEach(async () => {
14
+ await (0, testUtils_js_1.closeV3)(v3);
15
+ });
16
+ (0, test_1.test)("pages() includes a tab opened via chrome://newtab/", async () => {
17
+ const ctx = v3.context;
18
+ const initialPages = ctx.pages();
19
+ (0, test_1.expect)(initialPages.length).toBe(1);
20
+ // Simulate a manually-opened tab by creating a target at chrome://newtab/.
21
+ // This is the same CDP path the browser takes when the user presses Ctrl+T.
22
+ const { targetId } = await ctx.conn.send("Target.createTarget", { url: "chrome://newtab/" });
23
+ // Wait for the page to be registered (onAttachedToTarget is async).
24
+ const deadline = Date.now() + 5000;
25
+ while (Date.now() < deadline) {
26
+ if (ctx.pages().length >= 2)
27
+ break;
28
+ await new Promise((r) => setTimeout(r, 50));
29
+ }
30
+ const pages = ctx.pages();
31
+ (0, test_1.expect)(pages.length).toBe(2);
32
+ // The new page's target should match the one we created.
33
+ const newPage = pages.find((p) => p.targetId() === targetId);
34
+ (0, test_1.expect)(newPage).toBeTruthy();
35
+ });
36
+ (0, test_1.test)("chrome://newtab/ tab becomes usable after navigating to a web URL", async () => {
37
+ const ctx = v3.context;
38
+ // Create a tab at chrome://newtab/ (same as user pressing Ctrl+T).
39
+ const { targetId } = await ctx.conn.send("Target.createTarget", { url: "chrome://newtab/" });
40
+ // Wait for registration.
41
+ const deadline = Date.now() + 5000;
42
+ while (Date.now() < deadline) {
43
+ if (ctx.pages().some((p) => p.targetId() === targetId))
44
+ break;
45
+ await new Promise((r) => setTimeout(r, 50));
46
+ }
47
+ const newPage = ctx.pages().find((p) => p.targetId() === targetId);
48
+ (0, test_1.expect)(newPage).toBeTruthy();
49
+ // Navigate the new tab to a real web page.
50
+ await newPage.goto("https://example.com/", {
51
+ waitUntil: "domcontentloaded",
52
+ });
53
+ (0, test_1.expect)(newPage.url()).toContain("example.com");
54
+ });
55
+ });
56
+ //# sourceMappingURL=chrome-newtab-page-tracking.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chrome-newtab-page-tracking.spec.js","sourceRoot":"","sources":["../../../../tests/integration/chrome-newtab-page-tracking.spec.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"@playwright/test\";\nimport { V3 } from \"../../lib/v3/v3.js\";\nimport { v3DynamicTestConfig } from \"./v3.dynamic.config.js\";\nimport { closeV3 } from \"./testUtils.js\";\n\ntest.describe(\"V3 chrome:// new-tab page tracking\", () => {\n let v3: V3;\n\n test.beforeEach(async () => {\n v3 = new V3(v3DynamicTestConfig);\n await v3.init();\n });\n\n test.afterEach(async () => {\n await closeV3(v3);\n });\n\n test(\"pages() includes a tab opened via chrome://newtab/\", async () => {\n const ctx = v3.context;\n const initialPages = ctx.pages();\n expect(initialPages.length).toBe(1);\n\n // Simulate a manually-opened tab by creating a target at chrome://newtab/.\n // This is the same CDP path the browser takes when the user presses Ctrl+T.\n const { targetId } = await ctx.conn.send<{ targetId: string }>(\n \"Target.createTarget\",\n { url: \"chrome://newtab/\" },\n );\n\n // Wait for the page to be registered (onAttachedToTarget is async).\n const deadline = Date.now() + 5000;\n while (Date.now() < deadline) {\n if (ctx.pages().length >= 2) break;\n await new Promise((r) => setTimeout(r, 50));\n }\n\n const pages = ctx.pages();\n expect(pages.length).toBe(2);\n\n // The new page's target should match the one we created.\n const newPage = pages.find((p) => p.targetId() === targetId);\n expect(newPage).toBeTruthy();\n });\n\n test(\"chrome://newtab/ tab becomes usable after navigating to a web URL\", async () => {\n const ctx = v3.context;\n\n // Create a tab at chrome://newtab/ (same as user pressing Ctrl+T).\n const { targetId } = await ctx.conn.send<{ targetId: string }>(\n \"Target.createTarget\",\n { url: \"chrome://newtab/\" },\n );\n\n // Wait for registration.\n const deadline = Date.now() + 5000;\n while (Date.now() < deadline) {\n if (ctx.pages().some((p) => p.targetId() === targetId)) break;\n await new Promise((r) => setTimeout(r, 50));\n }\n\n const newPage = ctx.pages().find((p) => p.targetId() === targetId);\n expect(newPage).toBeTruthy();\n\n // Navigate the new tab to a real web page.\n await newPage!.goto(\"https://example.com/\", {\n waitUntil: \"domcontentloaded\",\n });\n\n expect(newPage!.url()).toContain(\"example.com\");\n });\n});\n"]}
@@ -3,7 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const test_1 = require("@playwright/test");
4
4
  const v3_js_1 = require("../../lib/v3/v3.js");
5
5
  const v3_config_js_1 = require("./v3.config.js");
6
+ const POPUP_TIMEOUT_MS = 20_000;
6
7
  const toDataUrl = (html) => `data:text/html,${encodeURIComponent(html)}`;
8
+ const waitForPopupPage = async (ctx, knownTargetIds, timeoutMs = POPUP_TIMEOUT_MS) => {
9
+ const deadline = Date.now() + timeoutMs;
10
+ while (Date.now() < deadline) {
11
+ const popup = ctx
12
+ .pages()
13
+ .find((page) => !knownTargetIds.has(page.targetId()));
14
+ if (popup)
15
+ return popup;
16
+ try {
17
+ const active = await ctx.awaitActivePage(500);
18
+ if (!knownTargetIds.has(active.targetId()))
19
+ return active;
20
+ }
21
+ catch {
22
+ // keep polling
23
+ }
24
+ await new Promise((resolve) => setTimeout(resolve, 50));
25
+ }
26
+ throw new Error("Popup page was not created");
27
+ };
7
28
  test_1.test.describe("context.addInitScript", () => {
8
29
  let v3;
9
30
  let ctx;
@@ -145,7 +166,7 @@ test_1.test.describe("context.addInitScript", () => {
145
166
  setPayload();
146
167
  }
147
168
  }, payload);
148
- const popupUrl = toDataUrl("<html><body>popup</body></html>");
169
+ const popupUrl = "https://example.com/";
149
170
  const openerHtml = "<!DOCTYPE html>" +
150
171
  "<html><body>" +
151
172
  '<a id="open" target="_blank" href="' +
@@ -154,23 +175,95 @@ test_1.test.describe("context.addInitScript", () => {
154
175
  "</body></html>";
155
176
  const opener = await ctx.awaitActivePage();
156
177
  await opener.goto(toDataUrl(openerHtml), { waitUntil: "load" });
178
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
157
179
  await opener.locator("#open").click();
158
- const openerId = opener.targetId();
159
- const deadline = Date.now() + 2000;
160
- let popup = ctx.pages().find((p) => p.targetId() !== openerId);
161
- while (!popup && Date.now() < deadline) {
162
- await opener.waitForTimeout(25);
163
- popup = ctx.pages().find((p) => p.targetId() !== openerId);
164
- }
165
- if (!popup) {
166
- throw new Error("Popup page was not created");
167
- }
180
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
168
181
  await popup.waitForLoadState("load");
169
182
  const observed = await popup.evaluate(() => {
170
183
  const raw = document.documentElement.dataset.initPayload;
171
184
  return raw ? JSON.parse(raw) : undefined;
172
185
  });
173
186
  (0, test_1.expect)(observed).toEqual(payload);
187
+ await popup.reload({ waitUntil: "load" });
188
+ const observedAfterReload = await popup.evaluate(() => {
189
+ const raw = document.documentElement.dataset.initPayload;
190
+ return raw ? JSON.parse(raw) : undefined;
191
+ });
192
+ (0, test_1.expect)(observedAfterReload).toEqual(payload);
193
+ });
194
+ (0, test_1.test)("applies script to in-process popup", async () => {
195
+ await ctx.addInitScript(() => {
196
+ window.__injected = 123;
197
+ });
198
+ const opener = await ctx.awaitActivePage();
199
+ const openerHtml = "<!DOCTYPE html>" +
200
+ "<html><body>" +
201
+ '<a id="open" target="_blank" href="about:blank">open</a>' +
202
+ "</body></html>";
203
+ await opener.goto(toDataUrl(openerHtml), { waitUntil: "load" });
204
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
205
+ await opener.locator("#open").click();
206
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
207
+ await popup.waitForLoadState("load");
208
+ const injected = await popup.evaluate(() => {
209
+ return window.__injected;
210
+ });
211
+ (0, test_1.expect)(injected).toBe(123);
212
+ });
213
+ (0, test_1.test)("applies script to cross-process popup and survives reload", async () => {
214
+ await ctx.addInitScript(() => {
215
+ window.__injected = 123;
216
+ });
217
+ const opener = await ctx.awaitActivePage();
218
+ const openerHtml = "<!DOCTYPE html>" +
219
+ "<html><body>" +
220
+ '<a id="open" target="_blank" href="https://example.com/">open</a>' +
221
+ "</body></html>";
222
+ await opener.goto(toDataUrl(openerHtml), {
223
+ waitUntil: "load",
224
+ });
225
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
226
+ await opener.locator("#open").click();
227
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
228
+ await popup.waitForLoadState("load");
229
+ const injected = await popup.evaluate(() => {
230
+ return window.__injected;
231
+ });
232
+ (0, test_1.expect)(injected).toBe(123);
233
+ await popup.reload({ waitUntil: "load" });
234
+ const injectedAfterReload = await popup.evaluate(() => {
235
+ return window.__injected;
236
+ });
237
+ (0, test_1.expect)(injectedAfterReload).toBe(123);
238
+ });
239
+ (0, test_1.test)("applies script to cross-process popup opened via window.open and survives reload", async () => {
240
+ await ctx.addInitScript(() => {
241
+ window.__injected = 789;
242
+ });
243
+ const opener = await ctx.awaitActivePage();
244
+ await opener.goto("about:blank", { waitUntil: "load" });
245
+ await opener.mainFrame().evaluate(() => {
246
+ const button = document.createElement("button");
247
+ button.id = "open-via-window-open";
248
+ button.textContent = "open popup";
249
+ button.addEventListener("click", () => {
250
+ window.open("https://example.com/", "_blank");
251
+ });
252
+ document.body.appendChild(button);
253
+ });
254
+ const knownTargetIds = new Set(ctx.pages().map((p) => p.targetId()));
255
+ await opener.locator("#open-via-window-open").click();
256
+ const popup = await waitForPopupPage(ctx, knownTargetIds);
257
+ await popup.waitForLoadState("load");
258
+ const injected = await popup.evaluate(() => {
259
+ return window.__injected;
260
+ });
261
+ (0, test_1.expect)(injected).toBe(789);
262
+ await popup.reload({ waitUntil: "load" });
263
+ const injectedAfterReload = await popup.evaluate(() => {
264
+ return window.__injected;
265
+ });
266
+ (0, test_1.expect)(injectedAfterReload).toBe(789);
174
267
  });
175
268
  (0, test_1.test)("context.addInitScript installs a function callable from page.evaluate", async () => {
176
269
  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 {};