browxai 0.7.0

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 (520) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/THIRD_PARTY_NOTICES.md +45 -0
  4. package/dist/cli/chrome.d.ts +1 -0
  5. package/dist/cli/chrome.js +130 -0
  6. package/dist/cli/command-registry.d.ts +15 -0
  7. package/dist/cli/command-registry.js +35 -0
  8. package/dist/cli/doctor-plugins.d.ts +18 -0
  9. package/dist/cli/doctor-plugins.js +338 -0
  10. package/dist/cli/doctor.d.ts +9 -0
  11. package/dist/cli/doctor.js +407 -0
  12. package/dist/cli/init.d.ts +1 -0
  13. package/dist/cli/init.js +200 -0
  14. package/dist/cli/register-commands.d.ts +1 -0
  15. package/dist/cli/register-commands.js +22 -0
  16. package/dist/cli/serve.d.ts +14 -0
  17. package/dist/cli/serve.js +151 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.js +129 -0
  20. package/dist/engine/adapters/adb.d.ts +72 -0
  21. package/dist/engine/adapters/adb.js +200 -0
  22. package/dist/engine/adapters/android-cdp.d.ts +54 -0
  23. package/dist/engine/adapters/android-cdp.js +110 -0
  24. package/dist/engine/adapters/android.engine.d.ts +1 -0
  25. package/dist/engine/adapters/android.engine.js +31 -0
  26. package/dist/engine/adapters/chromium.engine.d.ts +1 -0
  27. package/dist/engine/adapters/chromium.engine.js +44 -0
  28. package/dist/engine/adapters/firefox.engine.d.ts +1 -0
  29. package/dist/engine/adapters/firefox.engine.js +43 -0
  30. package/dist/engine/adapters/playwright-chromium.d.ts +43 -0
  31. package/dist/engine/adapters/playwright-chromium.js +56 -0
  32. package/dist/engine/adapters/playwright-firefox.d.ts +52 -0
  33. package/dist/engine/adapters/playwright-firefox.js +97 -0
  34. package/dist/engine/adapters/playwright-webkit.d.ts +40 -0
  35. package/dist/engine/adapters/playwright-webkit.js +79 -0
  36. package/dist/engine/adapters/safari/bidi-client.d.ts +46 -0
  37. package/dist/engine/adapters/safari/bidi-client.js +130 -0
  38. package/dist/engine/adapters/safari/launch.d.ts +56 -0
  39. package/dist/engine/adapters/safari/launch.js +104 -0
  40. package/dist/engine/adapters/safari/webdriver-client.d.ts +102 -0
  41. package/dist/engine/adapters/safari/webdriver-client.js +175 -0
  42. package/dist/engine/adapters/safari.engine.d.ts +1 -0
  43. package/dist/engine/adapters/safari.engine.js +52 -0
  44. package/dist/engine/adapters/safaridriver-hybrid.d.ts +56 -0
  45. package/dist/engine/adapters/safaridriver-hybrid.js +127 -0
  46. package/dist/engine/adapters/webkit.engine.d.ts +1 -0
  47. package/dist/engine/adapters/webkit.engine.js +47 -0
  48. package/dist/engine/capabilities.d.ts +53 -0
  49. package/dist/engine/capabilities.js +122 -0
  50. package/dist/engine/capability-registry.d.ts +9 -0
  51. package/dist/engine/capability-registry.js +20 -0
  52. package/dist/engine/index.d.ts +18 -0
  53. package/dist/engine/index.js +14 -0
  54. package/dist/engine/register-engines.d.ts +5 -0
  55. package/dist/engine/register-engines.js +16 -0
  56. package/dist/engine/registry.d.ts +145 -0
  57. package/dist/engine/registry.js +67 -0
  58. package/dist/engine/select.d.ts +48 -0
  59. package/dist/engine/select.js +128 -0
  60. package/dist/engine/session-cdp.d.ts +13 -0
  61. package/dist/engine/session-cdp.js +22 -0
  62. package/dist/engine/tool-gate.d.ts +19 -0
  63. package/dist/engine/tool-gate.js +226 -0
  64. package/dist/engine/types.d.ts +71 -0
  65. package/dist/engine/types.js +16 -0
  66. package/dist/helper/bridge.d.ts +48 -0
  67. package/dist/helper/bridge.js +200 -0
  68. package/dist/helper/browx-page.d.ts +1 -0
  69. package/dist/helper/browx-page.js +47 -0
  70. package/dist/helper/overlay-hide.d.ts +9 -0
  71. package/dist/helper/overlay-hide.js +49 -0
  72. package/dist/helper/stealth.d.ts +10 -0
  73. package/dist/helper/stealth.js +88 -0
  74. package/dist/index.d.ts +7 -0
  75. package/dist/index.js +15 -0
  76. package/dist/page/a11y.d.ts +81 -0
  77. package/dist/page/a11y.js +219 -0
  78. package/dist/page/action-substrate.d.ts +64 -0
  79. package/dist/page/action-substrate.js +118 -0
  80. package/dist/page/actionresult-blocks.d.ts +99 -0
  81. package/dist/page/actionresult-blocks.js +144 -0
  82. package/dist/page/actionresult-shape.d.ts +48 -0
  83. package/dist/page/actionresult-shape.js +155 -0
  84. package/dist/page/actionresult-types.d.ts +368 -0
  85. package/dist/page/actionresult-types.js +4 -0
  86. package/dist/page/actionresult.d.ts +4 -0
  87. package/dist/page/actionresult.js +299 -0
  88. package/dist/page/actions-probe.d.ts +32 -0
  89. package/dist/page/actions-probe.js +294 -0
  90. package/dist/page/actions-scroll.d.ts +40 -0
  91. package/dist/page/actions-scroll.js +53 -0
  92. package/dist/page/actions.d.ts +132 -0
  93. package/dist/page/actions.js +453 -0
  94. package/dist/page/archive-assets.d.ts +39 -0
  95. package/dist/page/archive-assets.js +187 -0
  96. package/dist/page/archive.d.ts +47 -0
  97. package/dist/page/archive.js +349 -0
  98. package/dist/page/asset-export.d.ts +122 -0
  99. package/dist/page/asset-export.js +376 -0
  100. package/dist/page/await_network.d.ts +16 -0
  101. package/dist/page/await_network.js +23 -0
  102. package/dist/page/bbox.d.ts +37 -0
  103. package/dist/page/bbox.js +115 -0
  104. package/dist/page/canvas-capture.d.ts +82 -0
  105. package/dist/page/canvas-capture.js +257 -0
  106. package/dist/page/canvas-diff.d.ts +51 -0
  107. package/dist/page/canvas-diff.js +131 -0
  108. package/dist/page/canvas-gesture.d.ts +53 -0
  109. package/dist/page/canvas-gesture.js +167 -0
  110. package/dist/page/canvas-transform.d.ts +96 -0
  111. package/dist/page/canvas-transform.js +150 -0
  112. package/dist/page/canvas.d.ts +8 -0
  113. package/dist/page/canvas.js +50 -0
  114. package/dist/page/capture-substrate.d.ts +111 -0
  115. package/dist/page/capture-substrate.js +139 -0
  116. package/dist/page/clipboard.d.ts +25 -0
  117. package/dist/page/clipboard.js +50 -0
  118. package/dist/page/clock.d.ts +36 -0
  119. package/dist/page/clock.js +167 -0
  120. package/dist/page/compose.d.ts +55 -0
  121. package/dist/page/compose.js +169 -0
  122. package/dist/page/console.d.ts +39 -0
  123. package/dist/page/console.js +73 -0
  124. package/dist/page/coverage.d.ts +97 -0
  125. package/dist/page/coverage.js +280 -0
  126. package/dist/page/dom-export.d.ts +41 -0
  127. package/dist/page/dom-export.js +193 -0
  128. package/dist/page/dom-walk.d.ts +91 -0
  129. package/dist/page/dom-walk.js +267 -0
  130. package/dist/page/dom_diff.d.ts +48 -0
  131. package/dist/page/dom_diff.js +121 -0
  132. package/dist/page/downloads.d.ts +80 -0
  133. package/dist/page/downloads.js +244 -0
  134. package/dist/page/drop-files.d.ts +78 -0
  135. package/dist/page/drop-files.js +310 -0
  136. package/dist/page/element-export-discovery.d.ts +64 -0
  137. package/dist/page/element-export-discovery.js +346 -0
  138. package/dist/page/element-export.d.ts +46 -0
  139. package/dist/page/element-export.js +251 -0
  140. package/dist/page/emulation-substrate.d.ts +53 -0
  141. package/dist/page/emulation-substrate.js +87 -0
  142. package/dist/page/emulation.d.ts +60 -0
  143. package/dist/page/emulation.js +162 -0
  144. package/dist/page/export-playwright-script.d.ts +47 -0
  145. package/dist/page/export-playwright-script.js +304 -0
  146. package/dist/page/extract-resolve.d.ts +22 -0
  147. package/dist/page/extract-resolve.js +341 -0
  148. package/dist/page/extract-schema.d.ts +20 -0
  149. package/dist/page/extract-schema.js +200 -0
  150. package/dist/page/extract-types.d.ts +127 -0
  151. package/dist/page/extract-types.js +8 -0
  152. package/dist/page/extract-warnings.d.ts +8 -0
  153. package/dist/page/extract-warnings.js +56 -0
  154. package/dist/page/extract.d.ts +9 -0
  155. package/dist/page/extract.js +174 -0
  156. package/dist/page/fill-form.d.ts +58 -0
  157. package/dist/page/fill-form.js +261 -0
  158. package/dist/page/find.d.ts +158 -0
  159. package/dist/page/find.js +470 -0
  160. package/dist/page/frames.d.ts +45 -0
  161. package/dist/page/frames.js +133 -0
  162. package/dist/page/generate-locator.d.ts +57 -0
  163. package/dist/page/generate-locator.js +136 -0
  164. package/dist/page/gestures.d.ts +128 -0
  165. package/dist/page/gestures.js +198 -0
  166. package/dist/page/har.d.ts +91 -0
  167. package/dist/page/har.js +174 -0
  168. package/dist/page/heap.d.ts +97 -0
  169. package/dist/page/heap.js +285 -0
  170. package/dist/page/inspect.d.ts +34 -0
  171. package/dist/page/inspect.js +75 -0
  172. package/dist/page/layout-thrash.d.ts +34 -0
  173. package/dist/page/layout-thrash.js +232 -0
  174. package/dist/page/learning.d.ts +21 -0
  175. package/dist/page/learning.js +84 -0
  176. package/dist/page/locator.d.ts +54 -0
  177. package/dist/page/locator.js +142 -0
  178. package/dist/page/memory-diff.d.ts +48 -0
  179. package/dist/page/memory-diff.js +105 -0
  180. package/dist/page/network-mask.d.ts +8 -0
  181. package/dist/page/network-mask.js +18 -0
  182. package/dist/page/network-playwright.d.ts +96 -0
  183. package/dist/page/network-playwright.js +353 -0
  184. package/dist/page/network-substrate-select.d.ts +18 -0
  185. package/dist/page/network-substrate-select.js +32 -0
  186. package/dist/page/network-substrate.d.ts +109 -0
  187. package/dist/page/network-substrate.js +161 -0
  188. package/dist/page/network-ws.d.ts +46 -0
  189. package/dist/page/network-ws.js +113 -0
  190. package/dist/page/network.d.ts +194 -0
  191. package/dist/page/network.js +415 -0
  192. package/dist/page/overflow-detect.d.ts +102 -0
  193. package/dist/page/overflow-detect.js +449 -0
  194. package/dist/page/pdf.d.ts +69 -0
  195. package/dist/page/pdf.js +109 -0
  196. package/dist/page/perf-audit-analysers.d.ts +40 -0
  197. package/dist/page/perf-audit-analysers.js +369 -0
  198. package/dist/page/perf-audit-runner.d.ts +20 -0
  199. package/dist/page/perf-audit-runner.js +195 -0
  200. package/dist/page/perf-audit-types.d.ts +41 -0
  201. package/dist/page/perf-audit-types.js +5 -0
  202. package/dist/page/perf-audit.d.ts +37 -0
  203. package/dist/page/perf-audit.js +377 -0
  204. package/dist/page/perf.d.ts +127 -0
  205. package/dist/page/perf.js +373 -0
  206. package/dist/page/plan.d.ts +192 -0
  207. package/dist/page/plan.js +308 -0
  208. package/dist/page/point_probe.d.ts +46 -0
  209. package/dist/page/point_probe.js +99 -0
  210. package/dist/page/recording.d.ts +67 -0
  211. package/dist/page/recording.js +172 -0
  212. package/dist/page/refs.d.ts +92 -0
  213. package/dist/page/refs.js +134 -0
  214. package/dist/page/regions.d.ts +23 -0
  215. package/dist/page/regions.js +32 -0
  216. package/dist/page/routes.d.ts +40 -0
  217. package/dist/page/routes.js +87 -0
  218. package/dist/page/safari-actions.d.ts +12 -0
  219. package/dist/page/safari-actions.js +144 -0
  220. package/dist/page/sample.d.ts +64 -0
  221. package/dist/page/sample.js +216 -0
  222. package/dist/page/screenshot-on.d.ts +51 -0
  223. package/dist/page/screenshot-on.js +150 -0
  224. package/dist/page/screenshot-save.d.ts +36 -0
  225. package/dist/page/screenshot-save.js +53 -0
  226. package/dist/page/screenshot-schedule.d.ts +50 -0
  227. package/dist/page/screenshot-schedule.js +155 -0
  228. package/dist/page/script-substrate.d.ts +32 -0
  229. package/dist/page/script-substrate.js +47 -0
  230. package/dist/page/seed-random.d.ts +45 -0
  231. package/dist/page/seed-random.js +144 -0
  232. package/dist/page/set-of-marks.d.ts +96 -0
  233. package/dist/page/set-of-marks.js +245 -0
  234. package/dist/page/shadow.d.ts +136 -0
  235. package/dist/page/shadow.js +400 -0
  236. package/dist/page/shortcut.d.ts +50 -0
  237. package/dist/page/shortcut.js +147 -0
  238. package/dist/page/snapshot-substrate-safari.d.ts +30 -0
  239. package/dist/page/snapshot-substrate-safari.js +84 -0
  240. package/dist/page/snapshot-substrate-select.d.ts +24 -0
  241. package/dist/page/snapshot-substrate-select.js +34 -0
  242. package/dist/page/snapshot-substrate.d.ts +58 -0
  243. package/dist/page/snapshot-substrate.js +135 -0
  244. package/dist/page/snapshot.d.ts +24 -0
  245. package/dist/page/snapshot.js +162 -0
  246. package/dist/page/solve-captcha.d.ts +76 -0
  247. package/dist/page/solve-captcha.js +286 -0
  248. package/dist/page/storage-substrate-types.d.ts +221 -0
  249. package/dist/page/storage-substrate-types.js +6 -0
  250. package/dist/page/storage-substrate.d.ts +215 -0
  251. package/dist/page/storage-substrate.js +280 -0
  252. package/dist/page/structural.d.ts +9 -0
  253. package/dist/page/structural.js +152 -0
  254. package/dist/page/substrate-bundle-safari.d.ts +8 -0
  255. package/dist/page/substrate-bundle-safari.js +42 -0
  256. package/dist/page/substrate-bundle.d.ts +6 -0
  257. package/dist/page/substrate-bundle.js +53 -0
  258. package/dist/page/text_search.d.ts +44 -0
  259. package/dist/page/text_search.js +90 -0
  260. package/dist/page/upload.d.ts +28 -0
  261. package/dist/page/upload.js +62 -0
  262. package/dist/page/verify.d.ts +63 -0
  263. package/dist/page/verify.js +451 -0
  264. package/dist/page/video.d.ts +115 -0
  265. package/dist/page/video.js +169 -0
  266. package/dist/page/visibility.d.ts +22 -0
  267. package/dist/page/visibility.js +94 -0
  268. package/dist/page/watch.d.ts +29 -0
  269. package/dist/page/watch.js +99 -0
  270. package/dist/page/workers.d.ts +126 -0
  271. package/dist/page/workers.js +490 -0
  272. package/dist/page/ws-interactive.d.ts +82 -0
  273. package/dist/page/ws-interactive.js +318 -0
  274. package/dist/plugin/cli.d.ts +45 -0
  275. package/dist/plugin/cli.js +496 -0
  276. package/dist/plugin/command-registry.d.ts +9 -0
  277. package/dist/plugin/command-registry.js +23 -0
  278. package/dist/plugin/depgraph.d.ts +37 -0
  279. package/dist/plugin/depgraph.js +186 -0
  280. package/dist/plugin/manifest.d.ts +182 -0
  281. package/dist/plugin/manifest.js +219 -0
  282. package/dist/plugin/package-manager.d.ts +22 -0
  283. package/dist/plugin/package-manager.js +40 -0
  284. package/dist/plugin/resolver.d.ts +85 -0
  285. package/dist/plugin/resolver.js +166 -0
  286. package/dist/plugin/runtime.d.ts +77 -0
  287. package/dist/plugin/runtime.js +402 -0
  288. package/dist/plugin/types.d.ts +113 -0
  289. package/dist/plugin/types.js +4 -0
  290. package/dist/policy/confirm.d.ts +76 -0
  291. package/dist/policy/confirm.js +162 -0
  292. package/dist/policy/origin.d.ts +17 -0
  293. package/dist/policy/origin.js +79 -0
  294. package/dist/sdk/client.d.ts +21 -0
  295. package/dist/sdk/client.js +174 -0
  296. package/dist/sdk/index.d.ts +32 -0
  297. package/dist/sdk/index.js +61 -0
  298. package/dist/sdk/plugin-types.d.ts +33 -0
  299. package/dist/sdk/plugin-types.js +22 -0
  300. package/dist/sdk/registry.d.ts +17 -0
  301. package/dist/sdk/registry.js +94 -0
  302. package/dist/sdk/socket-transport.d.ts +20 -0
  303. package/dist/sdk/socket-transport.js +90 -0
  304. package/dist/sdk/tool-types.d.ts +634 -0
  305. package/dist/sdk/tool-types.js +28 -0
  306. package/dist/sdk/transport-in-process.d.ts +21 -0
  307. package/dist/sdk/transport-in-process.js +44 -0
  308. package/dist/sdk/transport-registry.d.ts +19 -0
  309. package/dist/sdk/transport-registry.js +31 -0
  310. package/dist/sdk/transport-socket.d.ts +12 -0
  311. package/dist/sdk/transport-socket.js +77 -0
  312. package/dist/sdk/transport-stdio-child.d.ts +10 -0
  313. package/dist/sdk/transport-stdio-child.js +47 -0
  314. package/dist/sdk/transport.d.ts +10 -0
  315. package/dist/sdk/transport.js +35 -0
  316. package/dist/sdk/types.d.ts +176 -0
  317. package/dist/sdk/types.js +10 -0
  318. package/dist/server.d.ts +33 -0
  319. package/dist/server.js +327 -0
  320. package/dist/session/artifacts.d.ts +52 -0
  321. package/dist/session/artifacts.js +177 -0
  322. package/dist/session/byob-attach.d.ts +26 -0
  323. package/dist/session/byob-attach.js +187 -0
  324. package/dist/session/byob.d.ts +8 -0
  325. package/dist/session/byob.js +20 -0
  326. package/dist/session/cache-storage.d.ts +100 -0
  327. package/dist/session/cache-storage.js +166 -0
  328. package/dist/session/device-emu.d.ts +149 -0
  329. package/dist/session/device-emu.js +545 -0
  330. package/dist/session/device.d.ts +14 -0
  331. package/dist/session/device.js +44 -0
  332. package/dist/session/dialog.d.ts +62 -0
  333. package/dist/session/dialog.js +164 -0
  334. package/dist/session/emulation.d.ts +69 -0
  335. package/dist/session/emulation.js +168 -0
  336. package/dist/session/extensions.d.ts +113 -0
  337. package/dist/session/extensions.js +237 -0
  338. package/dist/session/fs-picker.d.ts +144 -0
  339. package/dist/session/fs-picker.js +666 -0
  340. package/dist/session/idb-storage.d.ts +86 -0
  341. package/dist/session/idb-storage.js +229 -0
  342. package/dist/session/incognito.d.ts +3 -0
  343. package/dist/session/incognito.js +20 -0
  344. package/dist/session/launch-options.d.ts +41 -0
  345. package/dist/session/launch-options.js +200 -0
  346. package/dist/session/managed.d.ts +3 -0
  347. package/dist/session/managed.js +16 -0
  348. package/dist/session/metrics.d.ts +45 -0
  349. package/dist/session/metrics.js +75 -0
  350. package/dist/session/notification.d.ts +122 -0
  351. package/dist/session/notification.js +426 -0
  352. package/dist/session/permission.d.ts +144 -0
  353. package/dist/session/permission.js +600 -0
  354. package/dist/session/playwright-post-wire.d.ts +8 -0
  355. package/dist/session/playwright-post-wire.js +148 -0
  356. package/dist/session/policy-buffer.d.ts +21 -0
  357. package/dist/session/policy-buffer.js +47 -0
  358. package/dist/session/profile-snapshot.d.ts +11 -0
  359. package/dist/session/profile-snapshot.js +53 -0
  360. package/dist/session/registry.d.ts +365 -0
  361. package/dist/session/registry.js +98 -0
  362. package/dist/session/safari-post-wire.d.ts +8 -0
  363. package/dist/session/safari-post-wire.js +28 -0
  364. package/dist/session/safari-session.d.ts +10 -0
  365. package/dist/session/safari-session.js +39 -0
  366. package/dist/session/storage.d.ts +148 -0
  367. package/dist/session/storage.js +350 -0
  368. package/dist/session/types.d.ts +113 -0
  369. package/dist/session/types.js +5 -0
  370. package/dist/session/wedge.d.ts +15 -0
  371. package/dist/session/wedge.js +41 -0
  372. package/dist/tools/action-core-tools.d.ts +13 -0
  373. package/dist/tools/action-core-tools.js +156 -0
  374. package/dist/tools/action-form-tools.d.ts +12 -0
  375. package/dist/tools/action-form-tools.js +179 -0
  376. package/dist/tools/action-gesture-tools.d.ts +9 -0
  377. package/dist/tools/action-gesture-tools.js +115 -0
  378. package/dist/tools/action-history-tools.d.ts +8 -0
  379. package/dist/tools/action-history-tools.js +67 -0
  380. package/dist/tools/action-tool.d.ts +42 -0
  381. package/dist/tools/action-tool.js +58 -0
  382. package/dist/tools/action-tools.d.ts +20 -0
  383. package/dist/tools/action-tools.js +28 -0
  384. package/dist/tools/batch-act-tools.d.ts +10 -0
  385. package/dist/tools/batch-act-tools.js +276 -0
  386. package/dist/tools/batch-human-tools.d.ts +8 -0
  387. package/dist/tools/batch-human-tools.js +148 -0
  388. package/dist/tools/canvas-tools.d.ts +40 -0
  389. package/dist/tools/canvas-tools.js +368 -0
  390. package/dist/tools/capture-report-diagnostics-tools.d.ts +7 -0
  391. package/dist/tools/capture-report-diagnostics-tools.js +318 -0
  392. package/dist/tools/capture-report-element-export-tools.d.ts +8 -0
  393. package/dist/tools/capture-report-element-export-tools.js +197 -0
  394. package/dist/tools/capture-report-export-tools.d.ts +8 -0
  395. package/dist/tools/capture-report-export-tools.js +246 -0
  396. package/dist/tools/capture-report-marks-tools.d.ts +9 -0
  397. package/dist/tools/capture-report-marks-tools.js +221 -0
  398. package/dist/tools/capture-report-upload-tools.d.ts +8 -0
  399. package/dist/tools/capture-report-upload-tools.js +277 -0
  400. package/dist/tools/config-approval-tools.d.ts +8 -0
  401. package/dist/tools/config-approval-tools.js +166 -0
  402. package/dist/tools/deep-coverage-tools.d.ts +8 -0
  403. package/dist/tools/deep-coverage-tools.js +325 -0
  404. package/dist/tools/deep-determinism-tools.d.ts +8 -0
  405. package/dist/tools/deep-determinism-tools.js +276 -0
  406. package/dist/tools/deep-perf-tools.d.ts +19 -0
  407. package/dist/tools/deep-perf-tools.js +324 -0
  408. package/dist/tools/device-emulation-tools.d.ts +9 -0
  409. package/dist/tools/device-emulation-tools.js +137 -0
  410. package/dist/tools/extensions-batch-tools.d.ts +18 -0
  411. package/dist/tools/extensions-batch-tools.js +24 -0
  412. package/dist/tools/extensions-rebuild.d.ts +22 -0
  413. package/dist/tools/extensions-rebuild.js +208 -0
  414. package/dist/tools/extensions-tools.d.ts +2 -0
  415. package/dist/tools/extensions-tools.js +331 -0
  416. package/dist/tools/forms-fill-tools.d.ts +8 -0
  417. package/dist/tools/forms-fill-tools.js +109 -0
  418. package/dist/tools/forms-plan-tools.d.ts +7 -0
  419. package/dist/tools/forms-plan-tools.js +159 -0
  420. package/dist/tools/forms-recording-mode-tools.d.ts +8 -0
  421. package/dist/tools/forms-recording-mode-tools.js +71 -0
  422. package/dist/tools/forms-recording-tools.d.ts +14 -0
  423. package/dist/tools/forms-recording-tools.js +22 -0
  424. package/dist/tools/forms-refs-tools.d.ts +8 -0
  425. package/dist/tools/forms-refs-tools.js +90 -0
  426. package/dist/tools/gesture-coord-tools.d.ts +8 -0
  427. package/dist/tools/gesture-coord-tools.js +168 -0
  428. package/dist/tools/gesture-emulation-tools.d.ts +8 -0
  429. package/dist/tools/gesture-emulation-tools.js +135 -0
  430. package/dist/tools/gesture-network-tools.d.ts +17 -0
  431. package/dist/tools/gesture-network-tools.js +27 -0
  432. package/dist/tools/gesture-route-tools.d.ts +8 -0
  433. package/dist/tools/gesture-route-tools.js +142 -0
  434. package/dist/tools/gesture-websocket-tools.d.ts +8 -0
  435. package/dist/tools/gesture-websocket-tools.js +122 -0
  436. package/dist/tools/gesture-worker-tools.d.ts +9 -0
  437. package/dist/tools/gesture-worker-tools.js +200 -0
  438. package/dist/tools/host-build.d.ts +76 -0
  439. package/dist/tools/host-build.js +516 -0
  440. package/dist/tools/host.d.ts +287 -0
  441. package/dist/tools/host.js +1 -0
  442. package/dist/tools/input-tools.d.ts +10 -0
  443. package/dist/tools/input-tools.js +176 -0
  444. package/dist/tools/live-emulation-tools.d.ts +9 -0
  445. package/dist/tools/live-emulation-tools.js +353 -0
  446. package/dist/tools/plugin-runtime.d.ts +36 -0
  447. package/dist/tools/plugin-runtime.js +274 -0
  448. package/dist/tools/read-observe-buffer-tools.d.ts +9 -0
  449. package/dist/tools/read-observe-buffer-tools.js +385 -0
  450. package/dist/tools/read-observe-capture-tools.d.ts +12 -0
  451. package/dist/tools/read-observe-capture-tools.js +376 -0
  452. package/dist/tools/read-observe-dom-tools.d.ts +8 -0
  453. package/dist/tools/read-observe-dom-tools.js +308 -0
  454. package/dist/tools/read-observe-extract-tools.d.ts +8 -0
  455. package/dist/tools/read-observe-extract-tools.js +232 -0
  456. package/dist/tools/read-observe-verify-tools.d.ts +8 -0
  457. package/dist/tools/read-observe-verify-tools.js +316 -0
  458. package/dist/tools/schemas.d.ts +29 -0
  459. package/dist/tools/schemas.js +58 -0
  460. package/dist/tools/secrets-captcha-tools.d.ts +9 -0
  461. package/dist/tools/secrets-captcha-tools.js +231 -0
  462. package/dist/tools/session-dialog-permission-tools.d.ts +9 -0
  463. package/dist/tools/session-dialog-permission-tools.js +287 -0
  464. package/dist/tools/session-lifecycle-tools.d.ts +8 -0
  465. package/dist/tools/session-lifecycle-tools.js +314 -0
  466. package/dist/tools/session-notification-device-tools.d.ts +9 -0
  467. package/dist/tools/session-notification-device-tools.js +156 -0
  468. package/dist/tools/session-policy-tools.d.ts +16 -0
  469. package/dist/tools/session-policy-tools.js +22 -0
  470. package/dist/tools/session-registry.d.ts +28 -0
  471. package/dist/tools/session-registry.js +427 -0
  472. package/dist/tools/storage-artifact-har-video-tools.d.ts +8 -0
  473. package/dist/tools/storage-artifact-har-video-tools.js +311 -0
  474. package/dist/tools/storage-cache-idb-tools.d.ts +8 -0
  475. package/dist/tools/storage-cache-idb-tools.js +347 -0
  476. package/dist/tools/storage-state-cookies-tools.d.ts +8 -0
  477. package/dist/tools/storage-state-cookies-tools.js +223 -0
  478. package/dist/tools/storage-tools.d.ts +17 -0
  479. package/dist/tools/storage-tools.js +25 -0
  480. package/dist/tools/storage-web-auth-tools.d.ts +10 -0
  481. package/dist/tools/storage-web-auth-tools.js +230 -0
  482. package/dist/tools/tool-metadata.d.ts +8 -0
  483. package/dist/tools/tool-metadata.js +185 -0
  484. package/dist/util/batch.d.ts +83 -0
  485. package/dist/util/batch.js +191 -0
  486. package/dist/util/capabilities.d.ts +504 -0
  487. package/dist/util/capabilities.js +254 -0
  488. package/dist/util/config-store.d.ts +103 -0
  489. package/dist/util/config-store.js +206 -0
  490. package/dist/util/config.d.ts +11 -0
  491. package/dist/util/config.js +28 -0
  492. package/dist/util/credentials.d.ts +136 -0
  493. package/dist/util/credentials.js +622 -0
  494. package/dist/util/deadline.d.ts +22 -0
  495. package/dist/util/deadline.js +62 -0
  496. package/dist/util/diagnostics.d.ts +161 -0
  497. package/dist/util/diagnostics.js +579 -0
  498. package/dist/util/egress-sanitiser.d.ts +29 -0
  499. package/dist/util/egress-sanitiser.js +52 -0
  500. package/dist/util/failure.d.ts +8 -0
  501. package/dist/util/failure.js +50 -0
  502. package/dist/util/flake-check.d.ts +109 -0
  503. package/dist/util/flake-check.js +342 -0
  504. package/dist/util/invariant.d.ts +25 -0
  505. package/dist/util/invariant.js +66 -0
  506. package/dist/util/logging.d.ts +6 -0
  507. package/dist/util/logging.js +12 -0
  508. package/dist/util/predicates.d.ts +62 -0
  509. package/dist/util/predicates.js +340 -0
  510. package/dist/util/secrets.d.ts +104 -0
  511. package/dist/util/secrets.js +219 -0
  512. package/dist/util/tokens.d.ts +6 -0
  513. package/dist/util/tokens.js +24 -0
  514. package/dist/util/url-sanitizer.d.ts +19 -0
  515. package/dist/util/url-sanitizer.js +70 -0
  516. package/dist/util/version.d.ts +2 -0
  517. package/dist/util/version.js +21 -0
  518. package/dist/util/workspace.d.ts +7 -0
  519. package/dist/util/workspace.js +22 -0
  520. package/package.json +120 -0
@@ -0,0 +1,169 @@
1
+ // Session video recording — Playwright's native `recordVideo` context option.
2
+ //
3
+ // Strategy. Playwright's video recorder is wired at context creation and
4
+ // finalized when the context closes — same constraint shape as the native
5
+ // `recordHar` path (see src/page/har.ts). There is NO public mid-session
6
+ // flush; the .webm on disk is written only when the page / context closes.
7
+ // We honour that:
8
+ //
9
+ // - `open_session({recordVideo: {path?, size?}})` resolves the user-facing
10
+ // target path (workspace-rooted; default
11
+ // `<workspace>/videos/<sessionId>-<ISO>.webm`), then wires Playwright's
12
+ // `recordVideo` against a staging directory under `videos/.staging/...`.
13
+ // Playwright auto-names the file in the dir (an opaque GUID) — on
14
+ // `close_session` we resolve that to the deterministic target path via
15
+ // `page.video().saveAs(target)`.
16
+ // - `stop_video({session?})` mirrors `stop_har` in the `nativeRecord:true`
17
+ // posture: Playwright doesn't expose a mid-context stop, so the tool
18
+ // surfaces the constraint instead of silently lying. The recorder state
19
+ // is marked `pendingFinalize:true` and the video will land at the target
20
+ // path when `close_session` runs.
21
+ // - `get_video({session?, format?})` reads the finalized file off disk:
22
+ // `format: "path"` (default) returns the absolute path; `format: "bytes"`
23
+ // inlines as base64 when under the inline cap, else returns the path
24
+ // with a `tooLargeToInline:true` hint. A get-before-stop call surfaces a
25
+ // structured error pointing at `close_session` (the file isn't on disk
26
+ // yet — Playwright constraint).
27
+ //
28
+ // Workspace-rooted by construction. Every path runs through
29
+ // `resolveWorkspacePath` (same helper as HAR / storage-state / pdf_save).
30
+ // Path traversal outside `$BROWX_WORKSPACE` is rejected.
31
+ //
32
+ // BYOB / attached. Mirror of HAR + pdf_save: the consumer's Chrome is
33
+ // not-owned and we don't wire context-creation primitives on it. The tool
34
+ // layer refuses cleanly with a structured error (see `assertVideoSupported`).
35
+ import { existsSync, mkdirSync, readFileSync, statSync } from "node:fs";
36
+ import { dirname } from "node:path";
37
+ import { resolveWorkspacePath } from "../session/storage.js";
38
+ /** Maximum size (in bytes) at which a finalized video is returned inline as
39
+ * base64 (`format:"bytes"`) rather than only by path. Conservative cap —
40
+ * video bytes balloon fast; agents that hit it should rely on the path. */
41
+ export const VIDEO_INLINE_CAP_BYTES = 1024 * 1024; // 1 MiB
42
+ export function newVideoRecorderState() {
43
+ return { active: false, finalized: false, pendingFinalize: false };
44
+ }
45
+ /** Refuse video on session modes Playwright's `recordVideo` doesn't support
46
+ * cleanly. BYOB (`attached`) is the only refusal: we don't wire
47
+ * context-creation primitives on the consumer's Chrome, mirroring the
48
+ * `pdf_save` / `recordHar` posture. Managed `persistent` and `incognito`
49
+ * sessions are both supported (headed and headless). */
50
+ export function assertVideoSupported(ctx) {
51
+ if (ctx.mode === "attached") {
52
+ return {
53
+ error: "video recording: not supported on attached / BYOB sessions — " +
54
+ "Playwright's `recordVideo` is a context-creation primitive and " +
55
+ "we don't mutate the consumer's Chrome (not-owned).",
56
+ hint: 'open a managed session (open_session({mode:"persistent"}) or ' +
57
+ '{mode:"incognito"}) with {recordVideo:{...}} and drive that.',
58
+ };
59
+ }
60
+ return null;
61
+ }
62
+ /** Default video filename for an auto-named recording. ISO timestamp with
63
+ * `:` / `.` mapped to `-` so the name is filesystem-safe on every platform. */
64
+ export function defaultVideoFilename(sessionId, now = new Date()) {
65
+ const iso = now.toISOString().replace(/[:.]/g, "-");
66
+ const safeId = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
67
+ return `${safeId}-${iso}.webm`;
68
+ }
69
+ /** Resolve an explicit user-supplied path (workspace-escape rejected) OR
70
+ * build the default `<workspace>/videos/<auto>.webm` path. Creates the
71
+ * parent dir on demand — still under the workspace root by construction. */
72
+ export function resolveVideoTargetPath(workspaceRoot, sessionId, userPath, tool) {
73
+ const resolved = userPath
74
+ ? resolveWorkspacePath(workspaceRoot, userPath, tool)
75
+ : resolveWorkspacePath(workspaceRoot, `videos/${defaultVideoFilename(sessionId)}`, tool);
76
+ // `resolved` is workspace-rooted by construction (resolveWorkspacePath
77
+ // rejects any escape from `workspaceRoot`); `dirname(resolved)` is
78
+ // workspace-rooted too — the mkdirSync below never touches cwd.
79
+ // BROWX_WORKSPACE-derived.
80
+ const parent = dirname(resolved);
81
+ if (parent && parent !== resolved && !existsSync(parent)) {
82
+ mkdirSync(parent, { recursive: true });
83
+ }
84
+ return resolved;
85
+ }
86
+ /** Resolve + create the staging directory Playwright writes its auto-named
87
+ * .webm into. One staging dir per session, under
88
+ * `<workspace>/videos/.staging/<sessionId>-<ISO>/`. Workspace-rooted by
89
+ * construction (resolveWorkspacePath rejects escape). */
90
+ export function resolveVideoStagingDir(workspaceRoot, sessionId, now = new Date()) {
91
+ const iso = now.toISOString().replace(/[:.]/g, "-");
92
+ const safeId = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
93
+ const stagingRel = `videos/.staging/${safeId}-${iso}`;
94
+ // resolveWorkspacePath rejects any escape from `workspaceRoot` — the
95
+ // resolved staging dir is BROWX_WORKSPACE-rooted by construction; the
96
+ // mkdirSync below never touches cwd.
97
+ const resolved = resolveWorkspacePath(workspaceRoot, stagingRel, "open_session");
98
+ if (!existsSync(resolved))
99
+ mkdirSync(resolved, { recursive: true });
100
+ return resolved;
101
+ }
102
+ /** Build the Playwright `recordVideo` option for `open_session({recordVideo})`.
103
+ * The caller passes this into `browser.newContext({recordVideo})` /
104
+ * `chromium.launchPersistentContext({recordVideo})`. Returns both the
105
+ * Playwright-shaped option AND the resolved target path + staging dir so the
106
+ * registry can persist them on `VideoRecorderState`. */
107
+ export function buildRecordVideoOption(workspaceRoot, sessionId, cfg) {
108
+ const targetPath = resolveVideoTargetPath(workspaceRoot, sessionId, cfg.path, "open_session");
109
+ const stagingDir = resolveVideoStagingDir(workspaceRoot, sessionId);
110
+ const recordVideo = {
111
+ dir: stagingDir,
112
+ };
113
+ if (cfg.size)
114
+ recordVideo.size = cfg.size;
115
+ return { targetPath, stagingDir, size: cfg.size, recordVideo };
116
+ }
117
+ /** Mark the recorder as `pendingFinalize` — the agent has signalled they
118
+ * want the recording stopped. The actual flush happens on `close_session`
119
+ * (Playwright finalizes the .webm only when the context closes). Mirrors
120
+ * the `stop_har` shape for the `nativeRecord:true` posture. */
121
+ export function stopVideo(state) {
122
+ if (!state.active) {
123
+ return { wasActive: false, pendingFinalize: false, finalized: state.finalized };
124
+ }
125
+ state.pendingFinalize = true;
126
+ return {
127
+ wasActive: true,
128
+ targetPath: state.targetPath,
129
+ pendingFinalize: true,
130
+ finalized: state.finalized,
131
+ };
132
+ }
133
+ /** Finalize the recording on session teardown. Calls `page.video().saveAs()`
134
+ * with the deterministic target path — Playwright waits for the page to
135
+ * close and the video to be fully written before resolving. Best-effort:
136
+ * errors here MUST NOT block session teardown (mirrors the `perf` /
137
+ * `artifacts` cleanup posture in the registry teardown). */
138
+ export async function finalizeVideoOnClose(page, state) {
139
+ if (!state.active || !state.targetPath)
140
+ return;
141
+ const video = page.video();
142
+ if (!video) {
143
+ // recordVideo was wired but the page reports no video — best-effort.
144
+ return;
145
+ }
146
+ try {
147
+ await video.saveAs(state.targetPath);
148
+ state.finalized = true;
149
+ }
150
+ catch {
151
+ /* best-effort — teardown never blocks on this */
152
+ }
153
+ }
154
+ /** Read a finalized video file. `format: "bytes"` inlines as base64 when
155
+ * under the cap; `format: "path"` (or over-cap) returns only the path. */
156
+ export function readVideoIfReady(path, format = "path", capBytes = VIDEO_INLINE_CAP_BYTES) {
157
+ if (!existsSync(path)) {
158
+ return { exists: false, path };
159
+ }
160
+ const st = statSync(path);
161
+ if (format === "path") {
162
+ return { exists: true, path, bytes: st.size };
163
+ }
164
+ if (st.size > capBytes) {
165
+ return { exists: true, path, bytes: st.size, tooLargeToInline: true };
166
+ }
167
+ const buf = readFileSync(path);
168
+ return { exists: true, path, bytes: st.size, inlineBase64: buf.toString("base64") };
169
+ }
@@ -0,0 +1,22 @@
1
+ import type { BrowserContext, Page } from "playwright-core";
2
+ export type VisibilityState = "background" | "foreground";
3
+ export interface VisibilityResult {
4
+ ok: boolean;
5
+ state: VisibilityState;
6
+ /** true when a real scratch-page background swap was applied (the driven
7
+ * page is genuinely not the front tab), false when only the synthetic
8
+ * visibility flip was possible. */
9
+ realBackgrounding: boolean;
10
+ /** present on a `background` call with `holdMs`: how long the page was held
11
+ * hidden before auto-foregrounding. */
12
+ heldMs?: number;
13
+ note?: string;
14
+ }
15
+ /**
16
+ * Drive the tab's visibility. `background` with `holdMs` is the headline
17
+ * primitive: background the page, hold it hidden for `holdMs` (real throttling
18
+ * in effect where the browser honours it), then auto-foreground — so the
19
+ * background→return transition that triggers the bug is reproducible in one
20
+ * call. `holdMs` is ignored for `foreground`.
21
+ */
22
+ export declare function setTabVisibility(page: Page, context: BrowserContext, state: VisibilityState, holdMs?: number): Promise<VisibilityResult>;
@@ -0,0 +1,94 @@
1
+ // Tab background / foreground control.
2
+ //
3
+ // A whole class of real bugs only reproduces when the tab is *backgrounded*
4
+ // during a transition: the browser throttles `setTimeout`, pauses
5
+ // `requestAnimationFrame` (framework enter/animation hooks never fire), and on
6
+ // return a `visibilitychange`/focus handler replays stale state. browxai
7
+ // otherwise keeps the driven tab foreground, so agentic QA scores these flows
8
+ // PASS while they are broken.
9
+ //
10
+ // Two levers, applied together:
11
+ // 1. Synthetic: server-injected *fixed* script (not agent JS — same posture
12
+ // as the sampler / overlay-hide) overrides `document.visibilityState` /
13
+ // `document.hidden` and dispatches `visibilitychange`. This deterministic
14
+ // across managed/incognito/attached/headless, and covers the large
15
+ // on-focus-refetch / visibilitychange-handler / realtime-replay subset.
16
+ // 2. Real best-effort: bring a blank scratch page in the same context to the
17
+ // front so Chromium actually treats the driven page as hidden (real
18
+ // timer/rAF throttling). Headless Chromium may not throttle even when
19
+ // backgrounded — so this is best-effort and reported as such, never
20
+ // silently assumed (cf. the documented headless gaps).
21
+ const SCRATCH_URL = "about:blank";
22
+ // Fixed in-page scripts. `configurable: true` so the two states can be
23
+ // re-applied across calls. No agent-supplied code path.
24
+ const HIDE = `(() => {
25
+ Object.defineProperty(document, 'visibilityState', { configurable: true, get: () => 'hidden' });
26
+ Object.defineProperty(document, 'hidden', { configurable: true, get: () => true });
27
+ document.dispatchEvent(new Event('visibilitychange'));
28
+ window.dispatchEvent(new Event('blur'));
29
+ })()`;
30
+ const SHOW = `(() => {
31
+ Object.defineProperty(document, 'visibilityState', { configurable: true, get: () => 'visible' });
32
+ Object.defineProperty(document, 'hidden', { configurable: true, get: () => false });
33
+ document.dispatchEvent(new Event('visibilitychange'));
34
+ window.dispatchEvent(new Event('focus'));
35
+ })()`;
36
+ /** Reuse-or-create a blank scratch page for this context (used to actually
37
+ * background the driven page by taking front focus away from it). */
38
+ async function scratchPage(context, driven) {
39
+ try {
40
+ const existing = context.pages().find((p) => p !== driven && p.url() === SCRATCH_URL);
41
+ if (existing)
42
+ return existing;
43
+ const p = await context.newPage();
44
+ await p.goto(SCRATCH_URL).catch(() => undefined);
45
+ return p;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ /**
52
+ * Drive the tab's visibility. `background` with `holdMs` is the headline
53
+ * primitive: background the page, hold it hidden for `holdMs` (real throttling
54
+ * in effect where the browser honours it), then auto-foreground — so the
55
+ * background→return transition that triggers the bug is reproducible in one
56
+ * call. `holdMs` is ignored for `foreground`.
57
+ */
58
+ export async function setTabVisibility(page, context, state, holdMs) {
59
+ if (state === "foreground") {
60
+ await page.evaluate(SHOW).catch(() => undefined);
61
+ await page.bringToFront().catch(() => undefined);
62
+ return { ok: true, state, realBackgrounding: false };
63
+ }
64
+ // background
65
+ const scratch = await scratchPage(context, page);
66
+ let realBackgrounding = false;
67
+ if (scratch) {
68
+ await scratch.bringToFront().catch(() => undefined);
69
+ realBackgrounding = true;
70
+ }
71
+ await page.evaluate(HIDE).catch(() => undefined);
72
+ if (holdMs !== undefined && holdMs > 0) {
73
+ await new Promise((r) => setTimeout(r, holdMs));
74
+ await page.evaluate(SHOW).catch(() => undefined);
75
+ await page.bringToFront().catch(() => undefined);
76
+ return {
77
+ ok: true,
78
+ state: "foreground",
79
+ realBackgrounding,
80
+ heldMs: holdMs,
81
+ note: realBackgrounding
82
+ ? "backgrounded for the hold window (real front-tab swap + synthetic visibilitychange), then auto-foregrounded; timer/rAF throttling is best-effort and may not occur under headless"
83
+ : "synthetic visibilitychange only (no second page could be created to take front focus); on-focus/visibilitychange handlers fire but real timer throttling is not simulated",
84
+ };
85
+ }
86
+ return {
87
+ ok: true,
88
+ state,
89
+ realBackgrounding,
90
+ note: realBackgrounding
91
+ ? "page backgrounded (front-tab swap + synthetic visibilitychange); call tab_visibility({state:'foreground'}) to return. Real timer/rAF throttling is best-effort under headless."
92
+ : "synthetic visibilitychange only; real timer throttling not simulated",
93
+ };
94
+ }
@@ -0,0 +1,29 @@
1
+ import { type NetworkEntry, type NetworkSummary, type WsFrame } from "./network.js";
2
+ import type { ActionContext } from "./actionresult.js";
3
+ export interface WatchedRegion {
4
+ role: string;
5
+ name?: string;
6
+ ref: string;
7
+ appearedAtMs: number;
8
+ /** ms offset when it vanished, or null if still present at window end. */
9
+ disappearedAtMs: number | null;
10
+ }
11
+ export interface WatchResult {
12
+ durationMs: number;
13
+ samples: number;
14
+ regions: WatchedRegion[];
15
+ console: {
16
+ errors: string[];
17
+ warnings: number;
18
+ pageErrors: string[];
19
+ };
20
+ network: {
21
+ summary: NetworkSummary;
22
+ requests: NetworkEntry[];
23
+ };
24
+ wsFrames: WsFrame[];
25
+ }
26
+ export declare function watchWindow(ctx: ActionContext, opts: {
27
+ durationMs: number;
28
+ sampleMs?: number;
29
+ }): Promise<WatchResult>;
@@ -0,0 +1,99 @@
1
+ // timed observation window with no driving action.
2
+ //
3
+ // `ActionResult`'s structure diff is endpoint-only (pre vs post) — a *transient*
4
+ // element that appears AND disappears inside the window is invisible to it.
5
+ // `watch` samples the top-level regions across the window, so double-fire /
6
+ // missing-broadcast / flash-of-content classes are caught: each region gets
7
+ // `appearedAtMs` and `disappearedAtMs` (null = still present at the end).
8
+ //
9
+ // Console / network / WS are time-stamped buffers already — sliced over the
10
+ // same window.
11
+ import { walk } from "./a11y.js";
12
+ /** Roles that signal a page-level transient/notification surface. */
13
+ const WATCHED_ROLES = new Set([
14
+ "dialog",
15
+ "alertdialog",
16
+ "alert",
17
+ "status",
18
+ "banner",
19
+ "tooltip",
20
+ "log",
21
+ "marquee",
22
+ "timer",
23
+ ]);
24
+ const MAX_DURATION_MS = 60_000;
25
+ const DEFAULT_SAMPLE_MS = 250;
26
+ export async function watchWindow(ctx, opts) {
27
+ const durationMs = Math.min(Math.max(opts.durationMs, 1), MAX_DURATION_MS);
28
+ const sampleMs = Math.max(opts.sampleMs ?? DEFAULT_SAMPLE_MS, 50);
29
+ const tStart = Date.now();
30
+ // Thread the session's secrets registry (when capability `secrets` is
31
+ // active and the registry exists on the action context) so the network
32
+ // tap's literal-value sanitisation runs over URLs / mutation
33
+ // responseShape keys during the watch window — same chokepoint the
34
+ // action-window tap uses.
35
+ // The per-action network tap comes from the engine's substrate:
36
+ // chromium → the CDP NetworkTap; firefox/webkit → the Playwright context-event
37
+ // tap. Same close shape on every engine, so the watch result is engine-blind.
38
+ const net = ctx.network ? ctx.network.openActionTap() : null;
39
+ if (net)
40
+ await net.open();
41
+ // ref → tracking record across samples.
42
+ const seen = new Map();
43
+ let samples = 0;
44
+ const sampleOnce = async () => {
45
+ const tree = await ctx.snapshot.a11yTree(ctx.refs, ctx.testAttributes).catch(() => null);
46
+ if (!tree)
47
+ return;
48
+ const nowMs = Date.now() - tStart;
49
+ samples++;
50
+ for (const { node } of walk(tree)) {
51
+ if (!WATCHED_ROLES.has(node.role))
52
+ continue;
53
+ const rec = seen.get(node.ref);
54
+ if (rec) {
55
+ rec.lastMs = nowMs;
56
+ }
57
+ else {
58
+ seen.set(node.ref, { role: node.role, name: node.name, firstMs: nowMs, lastMs: nowMs });
59
+ }
60
+ }
61
+ };
62
+ await sampleOnce();
63
+ while (Date.now() - tStart < durationMs) {
64
+ await new Promise((r) => setTimeout(r, sampleMs));
65
+ await sampleOnce();
66
+ }
67
+ const endMs = Date.now() - tStart;
68
+ const network = net
69
+ ? await net.close()
70
+ : { summary: { total: 0, byType: {}, failed: 0 }, requests: [] };
71
+ const errors = ctx.console.errorsSince(tStart);
72
+ const pageErrors = ctx.console.pageErrorsSince(tStart);
73
+ const warnings = ctx.console.warningCountSince(tStart);
74
+ const wsFrames = ctx.ws ? ctx.ws.since(tStart, 100) : [];
75
+ // A region "disappeared" if its last sighting was more than ~1.5 sample
76
+ // intervals before the final sample (i.e. it wasn't in the last sample).
77
+ const staleCut = endMs - sampleMs * 1.5;
78
+ const regions = [...seen.values()].map((r) => ({
79
+ role: r.role,
80
+ name: r.name,
81
+ ref: "",
82
+ appearedAtMs: r.firstMs,
83
+ disappearedAtMs: r.lastMs < staleCut ? r.lastMs : null,
84
+ }));
85
+ // attach refs back (Map key is the ref)
86
+ let i = 0;
87
+ for (const ref of seen.keys()) {
88
+ regions[i].ref = ref;
89
+ i++;
90
+ }
91
+ return {
92
+ durationMs,
93
+ samples,
94
+ regions,
95
+ console: { errors, warnings, pageErrors },
96
+ network: { summary: network.summary, requests: network.requests },
97
+ wsFrames,
98
+ };
99
+ }
@@ -0,0 +1,126 @@
1
+ import type { CDPSession, Page } from "playwright-core";
2
+ export type WorkerType = "web" | "service";
3
+ export type WorkerFilter = WorkerType | "all";
4
+ export interface WorkerListing {
5
+ workerId: string;
6
+ type: WorkerType;
7
+ url: string;
8
+ /** Best-effort state. Web workers: always `"running"` (browser doesn't
9
+ * expose lifecycle once they're constructed). Service workers: the CDP
10
+ * `running_status` (`stopped` / `starting` / `running` / `stopping`). */
11
+ state?: string;
12
+ }
13
+ export interface WorkerMessage {
14
+ workerId: string;
15
+ /** Always serialised to a string for the ring; structured-clone payloads
16
+ * are `JSON.stringify`d on the page side (and silently truncated to the
17
+ * payload cap). Binary `MessagePort`s are not transferred. */
18
+ data: string;
19
+ /** epoch ms — fixed on receipt. */
20
+ at: number;
21
+ }
22
+ export interface SwFetchInterceptSpec {
23
+ /** Glob matched against the intercepted request URL. Same shape as
24
+ * `route` / `ws_intercept`. `*` = single path segment, `**` = any. */
25
+ pattern: string;
26
+ /** Canned response. `body` defaults to `""`. `contentType` defaults
27
+ * to `application/json`. `status` defaults to `200`. */
28
+ response: {
29
+ status?: number;
30
+ body?: string;
31
+ contentType?: string;
32
+ headers?: Record<string, string>;
33
+ };
34
+ }
35
+ export declare const WORKERS_PAGE_SCRIPT = "(() => {\n if (window.__browxWorkers) return;\n var NativeWorker = window.Worker;\n if (!NativeWorker) return;\n var nativePost = NativeWorker.prototype.postMessage;\n var workers = new Map(); // wwId -> Worker\n var messages = []; // {workerId, data, at} ring (capped at 500)\n var MAX = 500;\n var nextId = 1;\n\n function recordMessage(id, payload) {\n var data;\n try {\n data = typeof payload === \"string\" ? payload : JSON.stringify(payload);\n } catch (_) {\n data = \"[unserialisable]\";\n }\n if (data && data.length > 4000) data = data.slice(0, 4000) + \"\u2026\";\n messages.push({ workerId: id, data: data, at: Date.now() });\n if (messages.length > MAX) messages.splice(0, messages.length - MAX);\n }\n\n function Wrapped(scriptURL, opts) {\n var w = arguments.length > 1 ? new NativeWorker(scriptURL, opts) : new NativeWorker(scriptURL);\n var id = \"ww-\" + (nextId++);\n workers.set(id, w);\n try { w.__browxId = id; } catch (_) {}\n // Mirror every message-from-worker into the ring. We use addEventListener\n // (not onmessage) so we don't fight with app-side onmessage handlers.\n try {\n w.addEventListener(\"message\", function (ev) { recordMessage(id, ev.data); });\n } catch (_) {}\n return w;\n }\n Wrapped.prototype = NativeWorker.prototype;\n try { Object.defineProperty(Wrapped, \"name\", { value: \"Worker\" }); } catch (_) {}\n window.Worker = Wrapped;\n\n window.__browxWorkers = {\n list: function () {\n var out = [];\n workers.forEach(function (w, id) {\n // We can't get the scriptURL back from a Worker after construction\n // in all browsers \u2014 fall back to the recorded url if we tracked it,\n // else the empty string. (Chromium DOES expose it via internal slot\n // but not via any public API; we track it at construction via the\n // initial scriptURL argument \u2014 see __browxWorkers._urls.\n var url = (window.__browxWorkers._urls && window.__browxWorkers._urls.get(id)) || \"\";\n out.push({ workerId: id, url: url });\n });\n return out;\n },\n _urls: new Map(),\n post: function (id, msg) {\n var w = workers.get(id);\n if (!w) return { ok: false, error: \"no worker with id \" + id };\n try {\n nativePost.call(w, msg);\n return { ok: true };\n } catch (e) {\n return { ok: false, error: e && e.message ? e.message : String(e) };\n }\n },\n drain: function (id) {\n var out;\n if (id) {\n out = [];\n var kept = [];\n for (var i = 0; i < messages.length; i++) {\n if (messages[i].workerId === id) out.push(messages[i]);\n else kept.push(messages[i]);\n }\n messages = kept;\n } else {\n out = messages.slice();\n messages.length = 0;\n }\n return out;\n },\n };\n\n // Track scriptURL at construction. We can't get it post-hoc on most engines.\n var origWrapped = Wrapped;\n window.Worker = function (scriptURL, opts) {\n var w = arguments.length > 1 ? origWrapped(scriptURL, opts) : origWrapped(scriptURL);\n try {\n var id = w.__browxId;\n if (id) {\n var url = \"\";\n try { url = String(scriptURL && scriptURL.href ? scriptURL.href : scriptURL || \"\"); } catch (_) {}\n window.__browxWorkers._urls.set(id, url);\n }\n } catch (_) {}\n return w;\n };\n window.Worker.prototype = NativeWorker.prototype;\n try { Object.defineProperty(window.Worker, \"name\", { value: \"Worker\" }); } catch (_) {}\n})();";
36
+ interface BrowxWorkersApi {
37
+ list(): Array<{
38
+ workerId: string;
39
+ url: string;
40
+ }>;
41
+ post(id: string, msg: string): {
42
+ ok: boolean;
43
+ error?: string;
44
+ };
45
+ drain(id?: string): Array<{
46
+ workerId: string;
47
+ data: string;
48
+ at: number;
49
+ }>;
50
+ }
51
+ declare global {
52
+ var __browxWorkers: BrowxWorkersApi | undefined;
53
+ }
54
+ export declare class WorkersRegistry {
55
+ /** SW attachments keyed by CDP sessionId. */
56
+ private swAttached;
57
+ /** Stable monotonic id for the SW listing — `sw-1`, `sw-2`, …. Keyed by
58
+ * CDP sessionId so the id survives status transitions on the same SW. */
59
+ private swIdBySession;
60
+ private nextSwId;
61
+ /** Active fetch interceptors. Re-add of the same pattern replaces. */
62
+ private fetchInterceptors;
63
+ /** Server-side ring of FROM-SW messages (we relay these via a CDP
64
+ * `Runtime.bindingCalled` shuttle on each SW session). */
65
+ private swMessages;
66
+ /** True once the page-side wrapper has been installed. */
67
+ private pageInstalled;
68
+ /** True once we've called `ServiceWorker.enable` + wired the auto-attach
69
+ * on the top-level CDP session. */
70
+ private swEnabled;
71
+ /** Detach functions for cleanup. */
72
+ private detachers;
73
+ /** Install the page-side `Worker` wrapper. Idempotent. Called eagerly at
74
+ * session creation (under capability `read`) so workers opened by the
75
+ * initial document are seen — same posture as `WsInteractiveRegistry`. */
76
+ installPageWrapper(page: Page): Promise<void>;
77
+ /** Enable the CDP ServiceWorker domain on the session's top-level CDP and
78
+ * wire `Target.setAutoAttach` so newly-registered SWs auto-attach as child
79
+ * sessions. Idempotent. */
80
+ /** Register a CDP event handler + push its detacher onto `this.detachers`.
81
+ * The event name is dynamic here, so the strongly-typed per-event `on`/`off`
82
+ * overloads are bridged through a single untyped seam. */
83
+ private onCdp;
84
+ /** `ServiceWorker.workerVersionUpdated` — refresh url/status on the matching
85
+ * attachment(s). */
86
+ private registerVersionUpdated;
87
+ /** `Target.attachedToTarget` / `detachedFromTarget` — track the SW attachment
88
+ * map, arming any already-armed fetch interceptors on a new SW. */
89
+ private registerAttachDetach;
90
+ /** `Fetch.requestPaused` (TOP session; flatten routes child events up by
91
+ * `sessionId`) — fulfill against a matching interceptor, else continue. */
92
+ private registerRequestPaused;
93
+ private handleRequestPaused;
94
+ installSwListener(cdp: CDPSession): Promise<void>;
95
+ private applyFetchEnable;
96
+ list(page: Page, cdp: CDPSession, filter?: WorkerFilter): Promise<WorkerListing[]>;
97
+ sendMessage(page: Page, cdp: CDPSession, args: {
98
+ workerId: string;
99
+ message: string;
100
+ }): Promise<{
101
+ ok: boolean;
102
+ workerId: string;
103
+ error?: string;
104
+ }>;
105
+ readMessages(page: Page, args: {
106
+ workerId?: string;
107
+ }): Promise<WorkerMessage[]>;
108
+ addFetchIntercept(cdp: CDPSession, spec: SwFetchInterceptSpec): Promise<{
109
+ key: string;
110
+ active: string[];
111
+ }>;
112
+ removeFetchIntercept(cdp: CDPSession, sel: {
113
+ pattern?: string;
114
+ }): Promise<{
115
+ removed: string[];
116
+ active: string[];
117
+ }>;
118
+ listFetchIntercepts(): string[];
119
+ /** Append a FROM-SW message to the server-side ring. Currently unused by
120
+ * the production path (the SW side message-relay is left as a future
121
+ * follow-up — see report); kept for symmetry + future use. */
122
+ recordSwMessage(workerId: string, data: string): void;
123
+ /** Release all CDP listeners. Called from the session teardown. */
124
+ dispose(): void;
125
+ }
126
+ export {};