@itmetsam/samurai-framework 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/README.md +129 -0
  2. package/bin/samurai.mjs +31 -0
  3. package/dist/api.js +3 -0
  4. package/dist/assert/assertion-error.d.ts +23 -0
  5. package/dist/assert/assertion-error.js +45 -0
  6. package/dist/assert/expect.d.ts +55 -0
  7. package/dist/assert/expect.js +188 -0
  8. package/dist/browser/browser-context.d.ts +91 -0
  9. package/dist/browser/browser-context.js +146 -0
  10. package/dist/browser/browser-finder.d.ts +2 -0
  11. package/dist/browser/browser-finder.js +95 -0
  12. package/dist/browser/browser.d.ts +95 -0
  13. package/dist/browser/browser.js +372 -0
  14. package/dist/browser/context-tree.d.ts +23 -0
  15. package/dist/browser/context-tree.js +60 -0
  16. package/dist/browser/dialog.d.ts +37 -0
  17. package/dist/browser/dialog.js +61 -0
  18. package/dist/browser/download.d.ts +71 -0
  19. package/dist/browser/download.js +137 -0
  20. package/dist/browser/downloads-dir.d.ts +8 -0
  21. package/dist/browser/downloads-dir.js +38 -0
  22. package/dist/browser/emulation.d.ts +61 -0
  23. package/dist/browser/emulation.js +144 -0
  24. package/dist/browser/file-chooser.d.ts +39 -0
  25. package/dist/browser/file-chooser.js +86 -0
  26. package/dist/browser/file-paths.d.ts +4 -0
  27. package/dist/browser/file-paths.js +18 -0
  28. package/dist/browser/index.d.ts +4 -0
  29. package/dist/browser/index.js +4 -0
  30. package/dist/browser/navigation-error.d.ts +13 -0
  31. package/dist/browser/navigation-error.js +19 -0
  32. package/dist/browser/page-logs.d.ts +86 -0
  33. package/dist/browser/page-logs.js +149 -0
  34. package/dist/browser/page-wait.d.ts +9 -0
  35. package/dist/browser/page-wait.js +17 -0
  36. package/dist/browser/page.d.ts +370 -0
  37. package/dist/browser/page.js +1038 -0
  38. package/dist/browser/pdf.d.ts +72 -0
  39. package/dist/browser/pdf.js +37 -0
  40. package/dist/browser/screenshot.d.ts +29 -0
  41. package/dist/browser/screenshot.js +42 -0
  42. package/dist/cli/args.d.ts +35 -0
  43. package/dist/cli/args.js +69 -0
  44. package/dist/cli/cli.cli-test.d.ts +1 -0
  45. package/dist/cli/cli.cli-test.js +170 -0
  46. package/dist/cli/console-reporter.d.ts +15 -0
  47. package/dist/cli/console-reporter.js +52 -0
  48. package/dist/cli/init.d.ts +7 -0
  49. package/dist/cli/init.js +61 -0
  50. package/dist/cli/main.d.ts +12 -0
  51. package/dist/cli/main.js +156 -0
  52. package/dist/config/config.d.ts +24 -0
  53. package/dist/config/config.js +42 -0
  54. package/dist/config/default.d.ts +2 -0
  55. package/dist/config/default.js +3 -0
  56. package/dist/config/mask.d.ts +11 -0
  57. package/dist/config/mask.js +85 -0
  58. package/dist/config/run-settings.d.ts +28 -0
  59. package/dist/config/run-settings.js +61 -0
  60. package/dist/config/secrets.d.ts +10 -0
  61. package/dist/config/secrets.js +67 -0
  62. package/dist/config/variables.d.ts +11 -0
  63. package/dist/config/variables.js +26 -0
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.js +15 -0
  66. package/dist/locator/action-timeout-error.d.ts +25 -0
  67. package/dist/locator/action-timeout-error.js +35 -0
  68. package/dist/locator/element-state.d.ts +44 -0
  69. package/dist/locator/element-state.js +109 -0
  70. package/dist/locator/label-locator.d.ts +13 -0
  71. package/dist/locator/label-locator.js +49 -0
  72. package/dist/locator/locator.d.ts +168 -0
  73. package/dist/locator/locator.js +591 -0
  74. package/dist/locator/selector-errors.d.ts +9 -0
  75. package/dist/locator/selector-errors.js +15 -0
  76. package/dist/locator/selector.d.ts +60 -0
  77. package/dist/locator/selector.js +113 -0
  78. package/dist/locator/text-locator.d.ts +13 -0
  79. package/dist/logger/index.d.ts +2 -0
  80. package/dist/logger/index.js +30 -0
  81. package/dist/network/data-collector.d.ts +26 -0
  82. package/dist/network/data-collector.js +77 -0
  83. package/dist/network/network-tracker.d.ts +94 -0
  84. package/dist/network/network-tracker.js +198 -0
  85. package/dist/network/network-wait.d.ts +16 -0
  86. package/dist/network/network-wait.js +24 -0
  87. package/dist/network/response.d.ts +22 -0
  88. package/dist/network/response.js +42 -0
  89. package/dist/network/router.d.ts +120 -0
  90. package/dist/network/router.js +343 -0
  91. package/dist/network/url-match.d.ts +8 -0
  92. package/dist/network/url-match.js +38 -0
  93. package/dist/recorder/apply.d.ts +3 -0
  94. package/dist/recorder/apply.js +10 -0
  95. package/dist/recorder/capture.d.ts +18 -0
  96. package/dist/recorder/capture.js +198 -0
  97. package/dist/recorder/index.d.ts +3 -0
  98. package/dist/recorder/index.js +3 -0
  99. package/dist/recorder/normalise.d.ts +68 -0
  100. package/dist/recorder/normalise.js +104 -0
  101. package/dist/recorder/ranking.d.ts +9 -0
  102. package/dist/recorder/ranking.js +21 -0
  103. package/dist/recorder/recorder.d.ts +52 -0
  104. package/dist/recorder/recorder.js +143 -0
  105. package/dist/recorder/session.d.ts +49 -0
  106. package/dist/recorder/session.js +113 -0
  107. package/dist/runner/module-type.d.ts +6 -0
  108. package/dist/runner/module-type.js +29 -0
  109. package/dist/runner/page-logs-report.d.ts +40 -0
  110. package/dist/runner/page-logs-report.js +44 -0
  111. package/dist/runner/prepare-run.d.ts +14 -0
  112. package/dist/runner/prepare-run.js +20 -0
  113. package/dist/runner/project.d.ts +17 -0
  114. package/dist/runner/project.js +33 -0
  115. package/dist/runner/registry.d.ts +7 -0
  116. package/dist/runner/registry.js +40 -0
  117. package/dist/runner/reporter.d.ts +43 -0
  118. package/dist/runner/reporter.js +83 -0
  119. package/dist/runner/run.d.ts +27 -0
  120. package/dist/runner/run.js +34 -0
  121. package/dist/runner/test-error.d.ts +3 -0
  122. package/dist/runner/test-error.js +18 -0
  123. package/dist/runner/test-runner.d.ts +44 -0
  124. package/dist/runner/test-runner.js +205 -0
  125. package/dist/script/call-function.d.ts +34 -0
  126. package/dist/script/call-function.js +71 -0
  127. package/dist/script/element-handle.d.ts +10 -0
  128. package/{src/script/element-handle.ts → dist/script/element-handle.js} +4 -4
  129. package/dist/script/helpers.d.ts +28 -0
  130. package/dist/script/helpers.js +50 -0
  131. package/dist/script/preload.d.ts +31 -0
  132. package/dist/script/preload.js +71 -0
  133. package/dist/script/serialize.d.ts +29 -0
  134. package/dist/script/serialize.js +207 -0
  135. package/dist/steps/build.d.ts +5 -0
  136. package/dist/steps/build.js +38 -0
  137. package/dist/steps/edit.d.ts +30 -0
  138. package/dist/steps/edit.js +80 -0
  139. package/dist/steps/emit.d.ts +6 -0
  140. package/dist/steps/emit.js +73 -0
  141. package/dist/steps/index.d.ts +5 -0
  142. package/dist/steps/index.js +4 -0
  143. package/dist/steps/model.d.ts +103 -0
  144. package/dist/steps/model.js +1 -0
  145. package/dist/steps/parse.d.ts +3 -0
  146. package/dist/steps/parse.js +272 -0
  147. package/dist/transport/bidi-connection.d.ts +46 -0
  148. package/dist/transport/bidi-connection.js +176 -0
  149. package/dist/transport/bidi-error.d.ts +10 -0
  150. package/dist/transport/bidi-error.js +10 -0
  151. package/dist/transport/subscriptions.d.ts +36 -0
  152. package/dist/transport/subscriptions.js +81 -0
  153. package/{src → dist}/types/test.d.ts +10 -4
  154. package/dist/wait/wait-until.d.ts +20 -0
  155. package/dist/wait/wait-until.js +63 -0
  156. package/package.json +48 -7
  157. package/.claude/settings.local.json +0 -7
  158. package/.env.example +0 -3
  159. package/.github/actions/setup/action.yml +0 -16
  160. package/.github/workflows/ci.yml +0 -71
  161. package/.trunk/configs/.markdownlint.yaml +0 -2
  162. package/.trunk/configs/.yamllint.yaml +0 -7
  163. package/.trunk/configs/svgo.config.mjs +0 -14
  164. package/.trunk/trunk.yaml +0 -34
  165. package/docs/superpowers/bidi-roadmap.md +0 -60
  166. package/docs/superpowers/plans/2026-09-29-auto-wait.md +0 -1827
  167. package/docs/superpowers/plans/2026-09-29-expect.md +0 -1350
  168. package/docs/superpowers/plans/2026-10-01-ci.md +0 -350
  169. package/docs/superpowers/plans/2026-10-01-test-api-alignment.md +0 -1821
  170. package/docs/superpowers/recorder-roadmap.md +0 -52
  171. package/docs/superpowers/specs/2026-09-29-auto-wait-design.md +0 -185
  172. package/docs/superpowers/specs/2026-09-29-bidi-foundation-design.md +0 -130
  173. package/docs/superpowers/specs/2026-09-29-contexts-and-storage-design.md +0 -88
  174. package/docs/superpowers/specs/2026-09-29-downloads-and-file-dialogs-design.md +0 -94
  175. package/docs/superpowers/specs/2026-09-29-emulation-design.md +0 -88
  176. package/docs/superpowers/specs/2026-09-29-expect-design.md +0 -130
  177. package/docs/superpowers/specs/2026-09-29-locate-nodes-design.md +0 -90
  178. package/docs/superpowers/specs/2026-09-29-logs-and-errors-design.md +0 -87
  179. package/docs/superpowers/specs/2026-09-29-navigation-waits-design.md +0 -83
  180. package/docs/superpowers/specs/2026-09-29-network-data-design.md +0 -78
  181. package/docs/superpowers/specs/2026-09-29-network-interception-design.md +0 -91
  182. package/docs/superpowers/specs/2026-09-29-network-tracking-design.md +0 -86
  183. package/docs/superpowers/specs/2026-09-29-page-api-design.md +0 -90
  184. package/docs/superpowers/specs/2026-09-29-preload-scripts-design.md +0 -82
  185. package/docs/superpowers/specs/2026-09-29-script-call-function-design.md +0 -107
  186. package/docs/superpowers/specs/2026-09-29-set-files-design.md +0 -62
  187. package/docs/superpowers/specs/2026-09-29-user-prompts-design.md +0 -75
  188. package/docs/superpowers/specs/2026-10-01-ci-design.md +0 -106
  189. package/docs/superpowers/specs/2026-10-01-test-api-alignment-design.md +0 -241
  190. package/public/logo-dark.svg +0 -236
  191. package/public/logo-light.svg +0 -262
  192. package/samurai.config.ts +0 -7
  193. package/src/assert/assertion-error.test.ts +0 -55
  194. package/src/assert/assertion-error.ts +0 -62
  195. package/src/assert/expect-locator.test.ts +0 -217
  196. package/src/assert/expect.test.ts +0 -73
  197. package/src/assert/expect.ts +0 -299
  198. package/src/browser/browser-context.browser-test.ts +0 -201
  199. package/src/browser/browser-context.test.ts +0 -407
  200. package/src/browser/browser-context.ts +0 -208
  201. package/src/browser/browser-finder.ts +0 -110
  202. package/src/browser/browser.test.ts +0 -88
  203. package/src/browser/browser.ts +0 -515
  204. package/src/browser/context-tree.test.ts +0 -86
  205. package/src/browser/context-tree.ts +0 -70
  206. package/src/browser/dialog.browser-test.ts +0 -144
  207. package/src/browser/dialog.test.ts +0 -322
  208. package/src/browser/dialog.ts +0 -83
  209. package/src/browser/download.test.ts +0 -161
  210. package/src/browser/download.ts +0 -172
  211. package/src/browser/downloads-dir.test.ts +0 -75
  212. package/src/browser/downloads-dir.ts +0 -39
  213. package/src/browser/emulation.browser-test.ts +0 -186
  214. package/src/browser/emulation.test.ts +0 -200
  215. package/src/browser/emulation.ts +0 -204
  216. package/src/browser/file-chooser.test.ts +0 -142
  217. package/src/browser/file-chooser.ts +0 -99
  218. package/src/browser/file-paths.ts +0 -18
  219. package/src/browser/goto.browser-test.ts +0 -44
  220. package/src/browser/navigation-error.ts +0 -26
  221. package/src/browser/navigation.browser-test.ts +0 -172
  222. package/src/browser/page-api.browser-test.ts +0 -228
  223. package/src/browser/page-logs.browser-test.ts +0 -119
  224. package/src/browser/page-logs.test.ts +0 -212
  225. package/src/browser/page-logs.ts +0 -208
  226. package/src/browser/page-wait.ts +0 -19
  227. package/src/browser/page.test.ts +0 -1567
  228. package/src/browser/page.ts +0 -1176
  229. package/src/browser/pdf.ts +0 -62
  230. package/src/browser/screenshot.ts +0 -65
  231. package/src/browser/transfers.browser-test.ts +0 -180
  232. package/src/config/config.ts +0 -33
  233. package/src/config/default.ts +0 -5
  234. package/src/config/fixtures.test.ts +0 -137
  235. package/src/config/mask.test.ts +0 -143
  236. package/src/config/mask.ts +0 -87
  237. package/src/config/run-settings.test.ts +0 -163
  238. package/src/config/run-settings.ts +0 -114
  239. package/src/config/secrets.ts +0 -70
  240. package/src/config/variables.ts +0 -31
  241. package/src/index.ts +0 -10
  242. package/src/locator/action-timeout-error.test.ts +0 -83
  243. package/src/locator/action-timeout-error.ts +0 -72
  244. package/src/locator/element-state.test.ts +0 -181
  245. package/src/locator/element-state.ts +0 -159
  246. package/src/locator/locate-nodes.browser-test.ts +0 -169
  247. package/src/locator/locator-actions.test.ts +0 -355
  248. package/src/locator/locator-chain.test.ts +0 -292
  249. package/src/locator/locator.browser-test.ts +0 -137
  250. package/src/locator/locator.test.ts +0 -179
  251. package/src/locator/locator.ts +0 -656
  252. package/src/locator/selector-errors.ts +0 -18
  253. package/src/locator/selector.test.ts +0 -124
  254. package/src/locator/selector.ts +0 -107
  255. package/src/locator/set-files.browser-test.ts +0 -141
  256. package/src/locator/set-files.test.ts +0 -191
  257. package/src/locator/text-locator.test.ts +0 -118
  258. package/src/logger/index.test.ts +0 -28
  259. package/src/logger/index.ts +0 -40
  260. package/src/network/data-collector.test.ts +0 -111
  261. package/src/network/data-collector.ts +0 -92
  262. package/src/network/network-data.browser-test.ts +0 -192
  263. package/src/network/network-tracker.browser-test.ts +0 -151
  264. package/src/network/network-tracker.test.ts +0 -307
  265. package/src/network/network-tracker.ts +0 -286
  266. package/src/network/network-wait.ts +0 -28
  267. package/src/network/response.test.ts +0 -93
  268. package/src/network/response.ts +0 -58
  269. package/src/network/router.browser-test.ts +0 -260
  270. package/src/network/router.test.ts +0 -528
  271. package/src/network/router.ts +0 -420
  272. package/src/network/url-match.test.ts +0 -69
  273. package/src/network/url-match.ts +0 -41
  274. package/src/runner/page-logs-report.test.ts +0 -144
  275. package/src/runner/page-logs-report.ts +0 -82
  276. package/src/runner/prepare-run.test.ts +0 -33
  277. package/src/runner/prepare-run.ts +0 -36
  278. package/src/runner/registry.test.ts +0 -59
  279. package/src/runner/registry.ts +0 -46
  280. package/src/runner/reporter.test.ts +0 -73
  281. package/src/runner/reporter.ts +0 -109
  282. package/src/runner/test-error.test.ts +0 -39
  283. package/src/runner/test-error.ts +0 -20
  284. package/src/runner/test-runner.ts +0 -184
  285. package/src/script/call-function.browser-test.ts +0 -112
  286. package/src/script/call-function.test.ts +0 -174
  287. package/src/script/call-function.ts +0 -113
  288. package/src/script/helpers.test.ts +0 -116
  289. package/src/script/helpers.ts +0 -68
  290. package/src/script/preload.browser-test.ts +0 -144
  291. package/src/script/preload.test.ts +0 -180
  292. package/src/script/preload.ts +0 -102
  293. package/src/script/serialize.test.ts +0 -182
  294. package/src/script/serialize.ts +0 -203
  295. package/src/testing/browser-fixture.ts +0 -18
  296. package/src/testing/fake-websocket.ts +0 -72
  297. package/src/testing/stub-connector.ts +0 -154
  298. package/src/tests/index.spec.ts +0 -30
  299. package/src/transport/bidi-connection.test.ts +0 -155
  300. package/src/transport/bidi-connection.ts +0 -256
  301. package/src/transport/bidi-error.ts +0 -23
  302. package/src/transport/foundation.browser-test.ts +0 -73
  303. package/src/transport/subscriptions.test.ts +0 -140
  304. package/src/transport/subscriptions.ts +0 -110
  305. package/src/types/bidi-commands.test-d.ts +0 -55
  306. package/src/wait/wait-until.test.ts +0 -117
  307. package/src/wait/wait-until.ts +0 -86
  308. package/tsconfig.json +0 -44
  309. /package/{src/api.ts → dist/api.d.ts} +0 -0
  310. /package/{src/locator/text-locator.ts → dist/locator/text-locator.js} +0 -0
  311. /package/{src → dist}/types/bidi-modules/browser.d.ts +0 -0
  312. /package/{src → dist}/types/bidi-modules/browsing-context.d.ts +0 -0
  313. /package/{src → dist}/types/bidi-modules/emulation.d.ts +0 -0
  314. /package/{src → dist}/types/bidi-modules/input.d.ts +0 -0
  315. /package/{src → dist}/types/bidi-modules/log.d.ts +0 -0
  316. /package/{src → dist}/types/bidi-modules/network.d.ts +0 -0
  317. /package/{src → dist}/types/bidi-modules/permissions.d.ts +0 -0
  318. /package/{src → dist}/types/bidi-modules/script.d.ts +0 -0
  319. /package/{src → dist}/types/bidi-modules/session.d.ts +0 -0
  320. /package/{src → dist}/types/bidi-modules/storage.d.ts +0 -0
  321. /package/{src → dist}/types/bidi-modules/web-extensions.d.ts +0 -0
  322. /package/{src → dist}/types/bidi-protocols/command.d.ts +0 -0
  323. /package/{src → dist}/types/bidi-protocols/error.d.ts +0 -0
  324. /package/{src → dist}/types/bidi-protocols/event.d.ts +0 -0
  325. /package/{src → dist}/types/bidi.d.ts +0 -0
  326. /package/{src → dist}/types/browser.d.ts +0 -0
  327. /package/{src → dist}/types/config.d.ts +0 -0
  328. /package/{src → dist}/types/env.d.ts +0 -0
@@ -0,0 +1,146 @@
1
+ import { BiDiError } from "../transport/bidi-error.js";
2
+ import { applyEmulation } from "./emulation.js";
3
+ /**
4
+ * An isolated browsing session inside one browser: its own cookies, storage and cache. Pages opened in it
5
+ * share them; pages of other contexts see none of it.
6
+ */
7
+ export class BrowserContext {
8
+ constructor(host,
9
+ /** The BiDi user context id; "default" for the browser's own */
10
+ id, isDefault) {
11
+ this.host = host;
12
+ this.id = id;
13
+ this.isDefault = isDefault;
14
+ this.opened = [];
15
+ this.isClosed = false;
16
+ }
17
+ /** True once `close()` has run */
18
+ get closed() {
19
+ return this.isClosed;
20
+ }
21
+ /** Opens a tab in this context */
22
+ async newPage() {
23
+ this.assertOpen();
24
+ return this.host.newPage({ type: "tab", ...(!this.isDefault && { userContext: this.id }) });
25
+ }
26
+ /** The pages opened in this context that are still open */
27
+ pages() {
28
+ this.opened = this.opened.filter((page) => !page.closed);
29
+ return [...this.opened];
30
+ }
31
+ /** @internal Called when a page is opened in this context */
32
+ register(page) {
33
+ this.opened.push(page);
34
+ page.setContext(this);
35
+ }
36
+ /** Adds cookies to this context's storage. Every cookie is checked before any is stored */
37
+ async addCookies(cookies) {
38
+ this.assertOpen();
39
+ const prepared = cookies.map(toBiDiCookie);
40
+ for (const cookie of prepared) {
41
+ await this.host.connector.send("storage.setCookie", { cookie, partition: this.partition() });
42
+ }
43
+ }
44
+ /** The cookies of this context, optionally only those matching `filter` */
45
+ async cookies(filter) {
46
+ this.assertOpen();
47
+ const { cookies } = await this.host.connector.send("storage.getCookies", {
48
+ ...(filter && { filter }),
49
+ partition: this.partition(),
50
+ });
51
+ return cookies.map(toCookie);
52
+ }
53
+ /** Deletes all cookies of this context, or those matching `filter` */
54
+ async clearCookies(filter) {
55
+ this.assertOpen();
56
+ await this.host.connector.send("storage.deleteCookies", {
57
+ ...(filter && { filter }),
58
+ partition: this.partition(),
59
+ });
60
+ }
61
+ /**
62
+ * Pretends things about every page of this context, including pages opened later: locale, timezone, user agent,
63
+ * geolocation, offline, orientation, screen size. A page's own `emulate()` wins over the context's.
64
+ * @example
65
+ * await context.emulate({ locale: "nl-NL", timezone: "Europe/Amsterdam", offline: false });
66
+ */
67
+ async emulate(options) {
68
+ this.assertOpen();
69
+ await applyEmulation(this.host.connector, { userContexts: [this.id] }, options);
70
+ }
71
+ /**
72
+ * Grants, denies or resets a browser permission ("geolocation", "notifications", "camera", …) for `origin`
73
+ * in this context. Geolocation emulation only answers once the permission is granted.
74
+ */
75
+ async setPermission(name, state, origin) {
76
+ this.assertOpen();
77
+ await this.host.connector.send("permissions.setPermission", {
78
+ descriptor: { name },
79
+ state,
80
+ origin,
81
+ ...(!this.isDefault && { userContext: this.id }),
82
+ });
83
+ }
84
+ /** Removes the context; the browser closes its pages. The default context cannot be closed */
85
+ async close() {
86
+ if (this.isDefault)
87
+ throw new Error("cannot close the default context");
88
+ if (this.isClosed)
89
+ return;
90
+ try {
91
+ await this.host.connector.send("browser.removeUserContext", { userContext: this.id });
92
+ }
93
+ catch (err) {
94
+ // Already gone: the goal is met
95
+ if (!(err instanceof BiDiError && err.code === "no such user context"))
96
+ throw err;
97
+ }
98
+ this.isClosed = true;
99
+ const pages = this.opened;
100
+ this.opened = [];
101
+ await Promise.all(pages.map((page) => page.detach()));
102
+ this.host.forget(this);
103
+ }
104
+ partition() {
105
+ return { type: "storageKey", userContext: this.id };
106
+ }
107
+ assertOpen() {
108
+ if (this.isClosed)
109
+ throw new Error("context closed");
110
+ }
111
+ }
112
+ function toBiDiCookie(input) {
113
+ let { domain, path, secure } = input;
114
+ if (input.url !== undefined) {
115
+ const url = new URL(input.url);
116
+ domain ??= url.hostname;
117
+ path ??= url.pathname;
118
+ secure ??= url.protocol === "https:";
119
+ }
120
+ if (domain === undefined)
121
+ throw new TypeError(`cookie "${input.name}" needs a domain or a url`);
122
+ return {
123
+ name: input.name,
124
+ value: { type: "string", value: input.value },
125
+ domain,
126
+ path: path ?? "/",
127
+ ...(secure !== undefined && { secure }),
128
+ ...(input.httpOnly !== undefined && { httpOnly: input.httpOnly }),
129
+ ...(input.sameSite !== undefined && { sameSite: input.sameSite }),
130
+ ...(input.expiry !== undefined && { expiry: input.expiry }),
131
+ };
132
+ }
133
+ function toCookie(cookie) {
134
+ return {
135
+ name: cookie.name,
136
+ value: cookie.value.type === "base64"
137
+ ? Buffer.from(cookie.value.value, "base64").toString("utf8")
138
+ : cookie.value.value,
139
+ domain: cookie.domain,
140
+ path: cookie.path,
141
+ httpOnly: cookie.httpOnly,
142
+ secure: cookie.secure,
143
+ sameSite: cookie.sameSite,
144
+ ...(cookie.expiry !== undefined && { expiry: cookie.expiry }),
145
+ };
146
+ }
@@ -0,0 +1,2 @@
1
+ import type { SupportedBrowser } from "../types/browser.js";
2
+ export declare function findBrowser(browserName: SupportedBrowser): string;
@@ -0,0 +1,95 @@
1
+ import assert from "node:assert";
2
+ import { execSync } from "node:child_process";
3
+ import { existsSync } from "node:fs";
4
+ import logger from "../logger/index.js";
5
+ const supportedBrowsers = ["firefox"];
6
+ const macBrowserPaths = {
7
+ // chrome: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
8
+ firefox: "/Applications/Firefox.app/Contents/MacOS/Firefox",
9
+ };
10
+ export function findBrowser(browserName) {
11
+ logger.verbose("Checking install location for %s", browserName);
12
+ if (!supportedBrowsers.includes(browserName)) {
13
+ throw new Error("This browser is not supported. Supported browsers include: " +
14
+ supportedBrowsers.join(", "));
15
+ }
16
+ let browserLocation = "";
17
+ const notFoundMsg = `Cannot find browser ${browserName} on this machine! Is it installed?`;
18
+ try {
19
+ browserLocation = tryFindBrowser(browserName);
20
+ }
21
+ catch (err) {
22
+ throw new Error(notFoundMsg);
23
+ }
24
+ assert(browserLocation, notFoundMsg);
25
+ logger.verbose("Browser found at: %s", browserLocation);
26
+ return browserLocation;
27
+ }
28
+ function tryFindBrowser(browserName) {
29
+ logger.debug("Current platform: %s", process.platform);
30
+ switch (process.platform) {
31
+ case "win32":
32
+ return findBrowserWindows(browserName);
33
+ case "darwin":
34
+ return findBrowserMac(browserName);
35
+ case "linux":
36
+ return findBrowserLinux(browserName);
37
+ default:
38
+ throw new Error("This platform is not supported");
39
+ }
40
+ }
41
+ function findBrowserWindows(browserName) {
42
+ // Function to prevent search the entire file system
43
+ // We'll only try the most common paths
44
+ const possibleDirs = ["Program\ Files", "Program\ Files (x86)"];
45
+ const where = (dirPath) => {
46
+ const command = `where /r ${dirPath} ${browserName}.exe`;
47
+ try {
48
+ logger.verbose("Running command: %s", command);
49
+ const whereResults = execSync(command, {
50
+ encoding: "utf8",
51
+ });
52
+ logger.debug("Command results: \n", whereResults);
53
+ const results = whereResults.split(/\n/g);
54
+ return results[0];
55
+ }
56
+ catch (error) {
57
+ logger.verbose("Error while executing %s", command, { error });
58
+ }
59
+ };
60
+ let result = undefined;
61
+ for (const possibleDir of possibleDirs) {
62
+ logger.debug("Checking directory: %s", possibleDir);
63
+ result = where(possibleDir);
64
+ if (result)
65
+ break;
66
+ }
67
+ if (!result) {
68
+ throw new Error("'where' yielded no results");
69
+ }
70
+ return result;
71
+ }
72
+ function findBrowserMac(browserName) {
73
+ const checkPathExists = (path) => {
74
+ logger.debug("Checking path: %s", path);
75
+ const exists = existsSync(path);
76
+ if (!exists) {
77
+ throw new Error(`Did not find ${browserName} at ${path}`);
78
+ }
79
+ return path;
80
+ };
81
+ return checkPathExists(macBrowserPaths[browserName]);
82
+ }
83
+ const linuxBinaryNames = {
84
+ // chrome: "google-chrome",
85
+ firefox: "firefox",
86
+ };
87
+ function findBrowserLinux(browserName) {
88
+ const command = `which ${linuxBinaryNames[browserName]}`;
89
+ logger.debug("Running command: %s", command);
90
+ const result = execSync(command, {
91
+ encoding: "utf8",
92
+ stdio: "pipe",
93
+ });
94
+ return result.replace(/\n/g, "");
95
+ }
@@ -0,0 +1,95 @@
1
+ import type { ChildProcessWithoutNullStreams } from "node:child_process";
2
+ import type { SupportedBrowser } from "../types/browser.js";
3
+ import { BiDiConnector } from "../transport/bidi-connection.js";
4
+ import Page from "./page.js";
5
+ import { BrowserContext } from "./browser-context.js";
6
+ import type { UserPromptHandler } from "../types/bidi-modules/session.js";
7
+ import { type EmulationOptions } from "./emulation.js";
8
+ import type { BiDiCommands } from "../types/bidi.js";
9
+ import type { CookieFilter, PartialCookie, PartitionDescriptor } from "../types/bidi-modules/storage.js";
10
+ /**
11
+ * Sent with session.new. With "ignore" the browser leaves a JavaScript dialog open and reports it
12
+ * (`browsingContext.userPromptOpened`), so the framework decides how to answer instead of the browser.
13
+ */
14
+ export declare const SESSION_CAPABILITIES: {
15
+ alwaysMatch: {
16
+ unhandledPromptBehavior: {
17
+ default: string;
18
+ };
19
+ };
20
+ };
21
+ export declare const browserLaunchFlag: (browserName: SupportedBrowser, launchOptions: Partial<BrowserLaunchOptions>) => string[];
22
+ /**
23
+ * Stops what a failed launch started. A browser left running holds the profile (the next launch
24
+ * fails with "already open") and keeps the test process alive.
25
+ */
26
+ export declare function abandonLaunch(browserProc: {
27
+ kill(): boolean;
28
+ }, biDiConnector: {
29
+ kill(): void;
30
+ } | undefined): void;
31
+ export interface BrowserLaunchOptions {
32
+ /** Which port to use for the WebDeveloper tools */
33
+ port: number;
34
+ /** Firefox only */
35
+ profileDir: string;
36
+ /** Start the browser in headless mode or in UI mode */
37
+ headless: boolean;
38
+ }
39
+ /** Options of `browser.newContext()` */
40
+ export interface ContextOptions extends EmulationOptions {
41
+ acceptInsecureCerts?: boolean;
42
+ /** How this context's pages answer JavaScript dialogs; the session default is to leave them for the framework */
43
+ unhandledPromptBehavior?: UserPromptHandler;
44
+ }
45
+ export declare class Browser {
46
+ private browserProc;
47
+ private biDiConnector;
48
+ private userContexts;
49
+ private host;
50
+ /** The browser's own context, the one `Browser.launch`'s page lives in */
51
+ readonly defaultContext: BrowserContext;
52
+ /** Where downloads are saved; undefined when the browser could not be told (it then uses its own folder) */
53
+ readonly downloadsDir: string | undefined;
54
+ private exitedPromise;
55
+ constructor({ browserProc, biDiConnector, downloadsDir, }: {
56
+ browserProc: ChildProcessWithoutNullStreams;
57
+ biDiConnector: BiDiConnector;
58
+ downloadsDir?: string | undefined;
59
+ });
60
+ /** Resolves when the browser process has exited, whether `close()` or a person closed it */
61
+ get exited(): Promise<void>;
62
+ static launch(browserName: SupportedBrowser, launchOptions?: Partial<BrowserLaunchOptions>,
63
+ /** Aborting kills the browser process and rejects the launch */
64
+ signal?: AbortSignal): Promise<{
65
+ browser: Browser;
66
+ page: Page;
67
+ }>;
68
+ /** Closes the browser via BiDi browser.close, then makes sure the process has exited */
69
+ close(): Promise<void>;
70
+ /** Alias of close() */
71
+ kill(): Promise<void>;
72
+ newPage({ type, background, userContext, }: BiDiCommands["browsingContext.create"]["params"]): Promise<Page>;
73
+ /**
74
+ * Creates an isolated context: its own cookies, storage and cache. `browser.close()` removes the contexts
75
+ * that are still open, as Firefox would otherwise keep them in its profile.
76
+ * @example
77
+ * const alice = await browser.newContext();
78
+ * const page = await alice.newPage();
79
+ */
80
+ newContext(options?: ContextOptions): Promise<BrowserContext>;
81
+ /** The default context, then the contexts this browser created that are still open */
82
+ contexts(): BrowserContext[];
83
+ private contextFor;
84
+ /** A user context this browser did not create (Firefox keeps them in its profile): usable, never closed by `close()` */
85
+ private adopt;
86
+ getCookie(filter: CookieFilter, partition: PartitionDescriptor): Promise<{
87
+ cookies: import("../types/bidi-modules/network.js").Cookie[];
88
+ partitionKey: import("../types/bidi-modules/storage.js").PartitionKey;
89
+ }>;
90
+ setCookie(cookie: PartialCookie, partition?: PartitionDescriptor): Promise<{
91
+ partitionKey: import("../types/bidi-modules/storage.js").PartitionKey;
92
+ }>;
93
+ }
94
+ /** Writes the browser's user.js unless it already holds the current prefs; an outdated one is replaced */
95
+ export declare function ensureBrowserProfile(browserName: SupportedBrowser, profilePath?: string | undefined): void;