@rehearsal-labs/retest 0.1.0 → 0.3.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 (502) hide show
  1. package/README.md +12 -5
  2. package/dist/agent/session.d.ts +21 -2
  3. package/dist/agent/session.d.ts.map +1 -1
  4. package/dist/agent/session.js +73 -11
  5. package/dist/api/app-page.d.ts +39 -3
  6. package/dist/api/app-page.d.ts.map +1 -1
  7. package/dist/api/app-page.js +108 -0
  8. package/dist/api/dialog.d.ts +38 -0
  9. package/dist/api/dialog.d.ts.map +1 -0
  10. package/dist/api/dialog.js +78 -0
  11. package/dist/api/drag.d.ts +32 -0
  12. package/dist/api/drag.d.ts.map +1 -0
  13. package/dist/api/drag.js +26 -0
  14. package/dist/api/files.d.ts +49 -0
  15. package/dist/api/files.d.ts.map +1 -0
  16. package/dist/api/files.js +168 -0
  17. package/dist/api/inbox.d.ts +97 -0
  18. package/dist/api/inbox.d.ts.map +1 -0
  19. package/dist/api/inbox.js +191 -0
  20. package/dist/api/locator-recipes.d.ts +1 -1
  21. package/dist/api/locator-recipes.d.ts.map +1 -1
  22. package/dist/api/locator-recipes.js +4 -3
  23. package/dist/api/page.d.ts +214 -4
  24. package/dist/api/page.d.ts.map +1 -1
  25. package/dist/api/route.d.ts +21 -0
  26. package/dist/api/route.d.ts.map +1 -0
  27. package/dist/api/route.js +99 -0
  28. package/dist/api/source-location.d.ts.map +1 -1
  29. package/dist/api/source-location.js +3 -1
  30. package/dist/api/test-run.d.ts +127 -1
  31. package/dist/api/test-run.d.ts.map +1 -1
  32. package/dist/api/test-run.js +293 -0
  33. package/dist/assertions/expect.d.ts +91 -2
  34. package/dist/assertions/expect.d.ts.map +1 -1
  35. package/dist/assertions/expect.js +98 -0
  36. package/dist/assertions/look-until.d.ts +5 -0
  37. package/dist/assertions/look-until.d.ts.map +1 -1
  38. package/dist/assertions/look-until.js +1 -1
  39. package/dist/assertions/poll-layout.d.ts +24 -0
  40. package/dist/assertions/poll-layout.d.ts.map +1 -0
  41. package/dist/assertions/poll-layout.js +63 -0
  42. package/dist/assertions/screenshot.d.ts +36 -0
  43. package/dist/assertions/screenshot.d.ts.map +1 -0
  44. package/dist/assertions/screenshot.js +125 -0
  45. package/dist/browser/accessibility.d.ts.map +1 -1
  46. package/dist/browser/accessibility.js +22 -1
  47. package/dist/browser/actionability.d.ts +9 -6
  48. package/dist/browser/actionability.d.ts.map +1 -1
  49. package/dist/browser/actionability.js +17 -8
  50. package/dist/browser/browser.d.ts.map +1 -1
  51. package/dist/browser/browser.js +15 -4
  52. package/dist/browser/builds.d.ts +35 -6
  53. package/dist/browser/builds.d.ts.map +1 -1
  54. package/dist/browser/builds.js +115 -16
  55. package/dist/browser/cdp/connection.d.ts +6 -0
  56. package/dist/browser/cdp/connection.d.ts.map +1 -1
  57. package/dist/browser/cdp/connection.js +8 -0
  58. package/dist/browser/cdp/transport.d.ts.map +1 -1
  59. package/dist/browser/cdp/transport.js +4 -4
  60. package/dist/browser/checked-state.d.ts +2 -2
  61. package/dist/browser/checked-state.d.ts.map +1 -1
  62. package/dist/browser/chromium-process.d.ts +32 -2
  63. package/dist/browser/chromium-process.d.ts.map +1 -1
  64. package/dist/browser/chromium-process.js +95 -17
  65. package/dist/browser/contract.d.ts +119 -5
  66. package/dist/browser/contract.d.ts.map +1 -1
  67. package/dist/browser/dialogs.d.ts +157 -0
  68. package/dist/browser/dialogs.d.ts.map +1 -0
  69. package/dist/browser/dialogs.js +271 -0
  70. package/dist/browser/downloads.d.ts +71 -0
  71. package/dist/browser/downloads.d.ts.map +1 -0
  72. package/dist/browser/downloads.js +253 -0
  73. package/dist/browser/drag.d.ts +50 -0
  74. package/dist/browser/drag.d.ts.map +1 -0
  75. package/dist/browser/drag.js +584 -0
  76. package/dist/browser/electron-window-watch.d.ts +32 -0
  77. package/dist/browser/electron-window-watch.d.ts.map +1 -0
  78. package/dist/browser/electron-window-watch.js +93 -0
  79. package/dist/browser/electron.d.ts +14 -3
  80. package/dist/browser/electron.d.ts.map +1 -1
  81. package/dist/browser/electron.js +57 -9
  82. package/dist/browser/element-queries.d.ts +51 -15
  83. package/dist/browser/element-queries.d.ts.map +1 -1
  84. package/dist/browser/element-queries.js +92 -13
  85. package/dist/browser/emulation.d.ts.map +1 -1
  86. package/dist/browser/emulation.js +7 -5
  87. package/dist/browser/executables.d.ts +16 -1
  88. package/dist/browser/executables.d.ts.map +1 -1
  89. package/dist/browser/executables.js +50 -18
  90. package/dist/browser/file-chooser.d.ts +75 -0
  91. package/dist/browser/file-chooser.d.ts.map +1 -0
  92. package/dist/browser/file-chooser.js +449 -0
  93. package/dist/browser/firefox/accessible-names.d.ts +5 -4
  94. package/dist/browser/firefox/accessible-names.d.ts.map +1 -1
  95. package/dist/browser/firefox/accessible-names.js +11 -6
  96. package/dist/browser/firefox/bridge.js +3 -2
  97. package/dist/browser/firefox/executable.d.ts +14 -14
  98. package/dist/browser/firefox/executable.d.ts.map +1 -1
  99. package/dist/browser/firefox/executable.js +29 -21
  100. package/dist/browser/firefox/input.d.ts +5 -0
  101. package/dist/browser/firefox/input.d.ts.map +1 -1
  102. package/dist/browser/firefox/input.js +6 -3
  103. package/dist/browser/firefox/launch.js +1 -1
  104. package/dist/browser/firefox/navigation.d.ts +5 -2
  105. package/dist/browser/firefox/navigation.d.ts.map +1 -1
  106. package/dist/browser/firefox/navigation.js +48 -14
  107. package/dist/browser/firefox/orphans.d.ts.map +1 -1
  108. package/dist/browser/firefox/orphans.js +34 -2
  109. package/dist/browser/firefox/page.d.ts +11 -1
  110. package/dist/browser/firefox/page.d.ts.map +1 -1
  111. package/dist/browser/firefox/page.js +179 -26
  112. package/dist/browser/firefox/process.d.ts +20 -1
  113. package/dist/browser/firefox/process.d.ts.map +1 -1
  114. package/dist/browser/firefox/process.js +124 -22
  115. package/dist/browser/firefox/profile.d.ts +5 -0
  116. package/dist/browser/firefox/profile.d.ts.map +1 -1
  117. package/dist/browser/firefox/profile.js +17 -1
  118. package/dist/browser/firefox/storage.d.ts.map +1 -1
  119. package/dist/browser/firefox/storage.js +4 -2
  120. package/dist/browser/firefox/subscriptions.d.ts +26 -0
  121. package/dist/browser/firefox/subscriptions.d.ts.map +1 -0
  122. package/dist/browser/firefox/subscriptions.js +10 -0
  123. package/dist/browser/frames.d.ts +205 -0
  124. package/dist/browser/frames.d.ts.map +1 -0
  125. package/dist/browser/frames.js +657 -0
  126. package/dist/browser/input-guard.d.ts +18 -5
  127. package/dist/browser/input-guard.d.ts.map +1 -1
  128. package/dist/browser/input-guard.js +65 -6
  129. package/dist/browser/isolated-world.d.ts +8 -1
  130. package/dist/browser/isolated-world.d.ts.map +1 -1
  131. package/dist/browser/launch.d.ts +6 -0
  132. package/dist/browser/launch.d.ts.map +1 -1
  133. package/dist/browser/launch.js +14 -1
  134. package/dist/browser/layout.d.ts +120 -0
  135. package/dist/browser/layout.d.ts.map +1 -0
  136. package/dist/browser/layout.js +213 -0
  137. package/dist/browser/locate.d.ts +10 -0
  138. package/dist/browser/locate.d.ts.map +1 -1
  139. package/dist/browser/locate.js +24 -6
  140. package/dist/browser/origin-document.d.ts +4 -0
  141. package/dist/browser/origin-document.d.ts.map +1 -1
  142. package/dist/browser/origin-document.js +9 -1
  143. package/dist/browser/page-scripts.d.ts +48 -0
  144. package/dist/browser/page-scripts.d.ts.map +1 -1
  145. package/dist/browser/page-scripts.js +515 -39
  146. package/dist/browser/page.d.ts +60 -1
  147. package/dist/browser/page.d.ts.map +1 -1
  148. package/dist/browser/page.js +275 -32
  149. package/dist/browser/popups.d.ts +166 -0
  150. package/dist/browser/popups.d.ts.map +1 -0
  151. package/dist/browser/popups.js +317 -0
  152. package/dist/browser/routes.d.ts +97 -0
  153. package/dist/browser/routes.d.ts.map +1 -0
  154. package/dist/browser/routes.js +226 -0
  155. package/dist/browser/screenshot.d.ts +44 -0
  156. package/dist/browser/screenshot.d.ts.map +1 -0
  157. package/dist/browser/screenshot.js +51 -0
  158. package/dist/browser/shadow-candidates.d.ts +20 -0
  159. package/dist/browser/shadow-candidates.d.ts.map +1 -0
  160. package/dist/browser/shadow-candidates.js +77 -0
  161. package/dist/browser/webkit/page.d.ts +11 -1
  162. package/dist/browser/webkit/page.d.ts.map +1 -1
  163. package/dist/browser/webkit/page.js +53 -2
  164. package/dist/browser/webkit/relay.d.ts.map +1 -1
  165. package/dist/browser/webkit/relay.js +5 -1
  166. package/dist/cli/commands/doctor.js +3 -3
  167. package/dist/cli/commands/inspect.js +3 -2
  168. package/dist/cli/commands/install.d.ts.map +1 -1
  169. package/dist/cli/commands/install.js +26 -13
  170. package/dist/cli/commands/licences.d.ts +22 -0
  171. package/dist/cli/commands/licences.d.ts.map +1 -1
  172. package/dist/cli/commands/licences.js +62 -20
  173. package/dist/cli/commands/run.d.ts.map +1 -1
  174. package/dist/cli/commands/run.js +4 -2
  175. package/dist/cli/doctor/checks.js +4 -1
  176. package/dist/cli/inspect/diagnostics.js +3 -3
  177. package/dist/cli/inspect/test-timeline.d.ts.map +1 -1
  178. package/dist/cli/inspect/test-timeline.js +45 -11
  179. package/dist/cli/install/doctor-rows.d.ts.map +1 -1
  180. package/dist/cli/install/doctor-rows.js +5 -4
  181. package/dist/cli/install/file-changes.d.ts +44 -0
  182. package/dist/cli/install/file-changes.d.ts.map +1 -0
  183. package/dist/cli/install/file-changes.js +81 -0
  184. package/dist/cli/install/install-archive.d.ts +3 -1
  185. package/dist/cli/install/install-archive.d.ts.map +1 -1
  186. package/dist/cli/install/install-archive.js +80 -33
  187. package/dist/cli/install/lock.d.ts.map +1 -1
  188. package/dist/cli/install/lock.js +108 -21
  189. package/dist/cli/install/media-doctor.d.ts.map +1 -1
  190. package/dist/cli/install/media-doctor.js +2 -1
  191. package/dist/cli/install/media-install.d.ts.map +1 -1
  192. package/dist/cli/install/media-install.js +38 -19
  193. package/dist/cli/install/media-pins.d.ts +7 -1
  194. package/dist/cli/install/media-pins.d.ts.map +1 -1
  195. package/dist/cli/install/media-pins.js +23 -12
  196. package/dist/cli/install/media-record.d.ts.map +1 -1
  197. package/dist/cli/install/media-record.js +10 -9
  198. package/dist/cli/install/media-report.d.ts +3 -1
  199. package/dist/cli/install/media-report.d.ts.map +1 -1
  200. package/dist/cli/install/media-report.js +7 -5
  201. package/dist/cli/install/media-tools.d.ts.map +1 -1
  202. package/dist/cli/install/media-tools.js +6 -4
  203. package/dist/cli/install/process-start.d.ts +3 -2
  204. package/dist/cli/install/process-start.d.ts.map +1 -1
  205. package/dist/cli/install/process-start.js +4 -0
  206. package/dist/cli/install/report.d.ts.map +1 -1
  207. package/dist/cli/install/report.js +11 -7
  208. package/dist/cli/install/supervisor-install.d.ts +33 -0
  209. package/dist/cli/install/supervisor-install.d.ts.map +1 -0
  210. package/dist/cli/install/supervisor-install.js +158 -0
  211. package/dist/cli/install/supervisor-locate.d.ts +47 -0
  212. package/dist/cli/install/supervisor-locate.d.ts.map +1 -0
  213. package/dist/cli/install/supervisor-locate.js +113 -0
  214. package/dist/cli/install/supervisor-pins.d.ts +21 -0
  215. package/dist/cli/install/supervisor-pins.d.ts.map +1 -0
  216. package/dist/cli/install/supervisor-pins.js +28 -0
  217. package/dist/cli/install/supervisor-record.d.ts +31 -0
  218. package/dist/cli/install/supervisor-record.d.ts.map +1 -0
  219. package/dist/cli/install/supervisor-record.js +104 -0
  220. package/dist/cli/install/supervisor-report.d.ts +11 -0
  221. package/dist/cli/install/supervisor-report.d.ts.map +1 -0
  222. package/dist/cli/install/supervisor-report.js +33 -0
  223. package/dist/cli/install/supervisor-tools.d.ts +43 -0
  224. package/dist/cli/install/supervisor-tools.d.ts.map +1 -0
  225. package/dist/cli/install/supervisor-tools.js +114 -0
  226. package/dist/cli/install/unpack.d.ts +23 -3
  227. package/dist/cli/install/unpack.d.ts.map +1 -1
  228. package/dist/cli/install/unpack.js +124 -10
  229. package/dist/cli/install/zip-member.d.ts +15 -0
  230. package/dist/cli/install/zip-member.d.ts.map +1 -0
  231. package/dist/cli/install/zip-member.js +77 -0
  232. package/dist/cli/interrupt.d.ts +1 -1
  233. package/dist/cli/interrupt.d.ts.map +1 -1
  234. package/dist/cli/interrupt.js +15 -10
  235. package/dist/cli/terminal.d.ts +9 -1
  236. package/dist/cli/terminal.d.ts.map +1 -1
  237. package/dist/cli/terminal.js +14 -0
  238. package/dist/config/define.d.ts +2 -2
  239. package/dist/config/define.js +2 -2
  240. package/dist/config/loaded.d.ts +12 -2
  241. package/dist/config/loaded.d.ts.map +1 -1
  242. package/dist/config/read-inboxes.d.ts +10 -0
  243. package/dist/config/read-inboxes.d.ts.map +1 -0
  244. package/dist/config/read-inboxes.js +78 -0
  245. package/dist/config/register.d.ts +5 -1
  246. package/dist/config/register.d.ts.map +1 -1
  247. package/dist/config/types.d.ts +36 -0
  248. package/dist/config/types.d.ts.map +1 -1
  249. package/dist/config/validate.d.ts.map +1 -1
  250. package/dist/config/validate.js +4 -1
  251. package/dist/diagnostics/artifact.d.ts.map +1 -1
  252. package/dist/diagnostics/artifact.js +10 -2
  253. package/dist/diagnostics/attempt.d.ts +5 -0
  254. package/dist/diagnostics/attempt.d.ts.map +1 -1
  255. package/dist/diagnostics/attempt.js +10 -0
  256. package/dist/diagnostics/chromium-collector.d.ts +9 -1
  257. package/dist/diagnostics/chromium-collector.d.ts.map +1 -1
  258. package/dist/diagnostics/chromium-collector.js +19 -4
  259. package/dist/diagnostics/firefox-collector.d.ts +11 -10
  260. package/dist/diagnostics/firefox-collector.d.ts.map +1 -1
  261. package/dist/diagnostics/firefox-collector.js +16 -11
  262. package/dist/diagnostics/observations.d.ts +8 -0
  263. package/dist/diagnostics/observations.d.ts.map +1 -1
  264. package/dist/diagnostics/session-capture.d.ts.map +1 -1
  265. package/dist/diagnostics/session-capture.js +8 -0
  266. package/dist/index.d.ts +9 -4
  267. package/dist/index.d.ts.map +1 -1
  268. package/dist/index.js +1 -0
  269. package/dist/media/client.d.ts +2 -1
  270. package/dist/media/client.d.ts.map +1 -1
  271. package/dist/media/client.js +16 -5
  272. package/dist/media/host.d.ts +32 -0
  273. package/dist/media/host.d.ts.map +1 -0
  274. package/dist/media/host.js +50 -0
  275. package/dist/media/locate.d.ts.map +1 -1
  276. package/dist/media/locate.js +4 -3
  277. package/dist/media/policy.d.ts +2 -2
  278. package/dist/media/policy.d.ts.map +1 -1
  279. package/dist/media/policy.js +1 -1
  280. package/dist/native/processes.d.ts.map +1 -1
  281. package/dist/native/processes.js +7 -3
  282. package/dist/playwright/not-yet.d.ts.map +1 -1
  283. package/dist/playwright/not-yet.js +5 -2
  284. package/dist/protocol/commands.d.ts +122 -13
  285. package/dist/protocol/commands.d.ts.map +1 -1
  286. package/dist/protocol/commands.js +85 -6
  287. package/dist/protocol/diagnostics.d.ts +10 -0
  288. package/dist/protocol/diagnostics.d.ts.map +1 -1
  289. package/dist/protocol/diagnostics.js +5 -0
  290. package/dist/protocol/dialogs.d.ts +104 -0
  291. package/dist/protocol/dialogs.d.ts.map +1 -0
  292. package/dist/protocol/dialogs.js +101 -0
  293. package/dist/protocol/drag.d.ts +45 -0
  294. package/dist/protocol/drag.d.ts.map +1 -0
  295. package/dist/protocol/drag.js +31 -0
  296. package/dist/protocol/events.d.ts +153 -1
  297. package/dist/protocol/events.d.ts.map +1 -1
  298. package/dist/protocol/events.js +97 -0
  299. package/dist/protocol/files.d.ts +83 -0
  300. package/dist/protocol/files.d.ts.map +1 -0
  301. package/dist/protocol/files.js +73 -0
  302. package/dist/protocol/inbox.d.ts +87 -0
  303. package/dist/protocol/inbox.d.ts.map +1 -0
  304. package/dist/protocol/inbox.js +51 -0
  305. package/dist/protocol/index.d.ts +4 -1
  306. package/dist/protocol/index.d.ts.map +1 -1
  307. package/dist/protocol/layout-checks.d.ts +83 -0
  308. package/dist/protocol/layout-checks.d.ts.map +1 -0
  309. package/dist/protocol/layout-checks.js +214 -0
  310. package/dist/protocol/layout.d.ts +135 -0
  311. package/dist/protocol/layout.d.ts.map +1 -0
  312. package/dist/protocol/layout.js +124 -0
  313. package/dist/protocol/locator-checks.d.ts +19 -2
  314. package/dist/protocol/locator-checks.d.ts.map +1 -1
  315. package/dist/protocol/locator-checks.js +23 -1
  316. package/dist/protocol/locator.d.ts +55 -7
  317. package/dist/protocol/locator.d.ts.map +1 -1
  318. package/dist/protocol/locator.js +99 -18
  319. package/dist/protocol/messages.d.ts +95 -0
  320. package/dist/protocol/messages.d.ts.map +1 -1
  321. package/dist/protocol/messages.js +63 -0
  322. package/dist/protocol/popups.d.ts +43 -0
  323. package/dist/protocol/popups.d.ts.map +1 -0
  324. package/dist/protocol/popups.js +27 -0
  325. package/dist/protocol/result.d.ts +5 -0
  326. package/dist/protocol/result.d.ts.map +1 -1
  327. package/dist/protocol/result.js +1 -0
  328. package/dist/protocol/routes.d.ts +136 -0
  329. package/dist/protocol/routes.d.ts.map +1 -0
  330. package/dist/protocol/routes.js +191 -0
  331. package/dist/protocol/screenshot.d.ts +219 -0
  332. package/dist/protocol/screenshot.d.ts.map +1 -0
  333. package/dist/protocol/screenshot.js +335 -0
  334. package/dist/reporters/actions.d.ts +6 -4
  335. package/dist/reporters/actions.d.ts.map +1 -1
  336. package/dist/reporters/actions.js +24 -6
  337. package/dist/reporters/agent.d.ts.map +1 -1
  338. package/dist/reporters/agent.js +4 -2
  339. package/dist/reporters/commands.d.ts +12 -3
  340. package/dist/reporters/commands.d.ts.map +1 -1
  341. package/dist/reporters/commands.js +29 -11
  342. package/dist/reporters/dialogs-popups.d.ts +22 -0
  343. package/dist/reporters/dialogs-popups.d.ts.map +1 -0
  344. package/dist/reporters/dialogs-popups.js +30 -0
  345. package/dist/reporters/failure-card.d.ts +10 -1
  346. package/dist/reporters/failure-card.d.ts.map +1 -1
  347. package/dist/reporters/failure-card.js +5 -1
  348. package/dist/reporters/format.d.ts +33 -0
  349. package/dist/reporters/format.d.ts.map +1 -1
  350. package/dist/reporters/format.js +42 -0
  351. package/dist/reporters/html/comparison-view.d.ts +12 -0
  352. package/dist/reporters/html/comparison-view.d.ts.map +1 -0
  353. package/dist/reporters/html/comparison-view.js +21 -0
  354. package/dist/reporters/html/diagnostics-view.js +8 -0
  355. package/dist/reporters/html/downloads-view.d.ts +10 -0
  356. package/dist/reporters/html/downloads-view.d.ts.map +1 -0
  357. package/dist/reporters/html/downloads-view.js +29 -0
  358. package/dist/reporters/html/style.d.ts.map +1 -1
  359. package/dist/reporters/html/style.js +3 -0
  360. package/dist/reporters/html/summary-view.d.ts.map +1 -1
  361. package/dist/reporters/html/summary-view.js +3 -2
  362. package/dist/reporters/html/test-view.d.ts.map +1 -1
  363. package/dist/reporters/html/test-view.js +6 -3
  364. package/dist/reporters/html/timeline-view.d.ts.map +1 -1
  365. package/dist/reporters/html/timeline-view.js +26 -2
  366. package/dist/reporters/human-card.js +11 -1
  367. package/dist/reporters/human.d.ts +3 -1
  368. package/dist/reporters/human.d.ts.map +1 -1
  369. package/dist/reporters/human.js +11 -9
  370. package/dist/reporters/routes.d.ts +9 -0
  371. package/dist/reporters/routes.d.ts.map +1 -0
  372. package/dist/reporters/routes.js +17 -0
  373. package/dist/reporters/style.d.ts +21 -2
  374. package/dist/reporters/style.d.ts.map +1 -1
  375. package/dist/reporters/style.js +11 -2
  376. package/dist/runner/app-server.d.ts +27 -7
  377. package/dist/runner/app-server.d.ts.map +1 -1
  378. package/dist/runner/app-server.js +74 -24
  379. package/dist/runner/child-program.js +10 -0
  380. package/dist/runner/child.js +6 -2
  381. package/dist/runner/contract.d.ts +5 -0
  382. package/dist/runner/contract.d.ts.map +1 -1
  383. package/dist/runner/dialogs.d.ts +71 -0
  384. package/dist/runner/dialogs.d.ts.map +1 -0
  385. package/dist/runner/dialogs.js +189 -0
  386. package/dist/runner/files.d.ts +79 -0
  387. package/dist/runner/files.d.ts.map +1 -0
  388. package/dist/runner/files.js +312 -0
  389. package/dist/runner/inbox-links.d.ts +19 -0
  390. package/dist/runner/inbox-links.d.ts.map +1 -0
  391. package/dist/runner/inbox-links.js +63 -0
  392. package/dist/runner/inbox.d.ts +87 -0
  393. package/dist/runner/inbox.d.ts.map +1 -0
  394. package/dist/runner/inbox.js +340 -0
  395. package/dist/runner/index.d.ts +2 -1
  396. package/dist/runner/index.d.ts.map +1 -1
  397. package/dist/runner/media-leftovers.d.ts +7 -3
  398. package/dist/runner/media-leftovers.d.ts.map +1 -1
  399. package/dist/runner/media-leftovers.js +27 -6
  400. package/dist/runner/native-pool.d.ts.map +1 -1
  401. package/dist/runner/native-pool.js +2 -0
  402. package/dist/runner/observations.d.ts +15 -2
  403. package/dist/runner/observations.d.ts.map +1 -1
  404. package/dist/runner/observations.js +109 -6
  405. package/dist/runner/popups.d.ts +82 -0
  406. package/dist/runner/popups.d.ts.map +1 -0
  407. package/dist/runner/popups.js +236 -0
  408. package/dist/runner/redactor.d.ts.map +1 -1
  409. package/dist/runner/redactor.js +10 -6
  410. package/dist/runner/resources.d.ts +8 -0
  411. package/dist/runner/resources.d.ts.map +1 -1
  412. package/dist/runner/resources.js +12 -1
  413. package/dist/runner/routes.d.ts +23 -0
  414. package/dist/runner/routes.d.ts.map +1 -0
  415. package/dist/runner/routes.js +128 -0
  416. package/dist/runner/run-media.d.ts +6 -0
  417. package/dist/runner/run-media.d.ts.map +1 -1
  418. package/dist/runner/run-media.js +21 -0
  419. package/dist/runner/run-session.d.ts.map +1 -1
  420. package/dist/runner/run-session.js +102 -12
  421. package/dist/runner/run.d.ts.map +1 -1
  422. package/dist/runner/run.js +2 -1
  423. package/dist/runner/running-test.d.ts +35 -0
  424. package/dist/runner/running-test.d.ts.map +1 -1
  425. package/dist/runner/running-test.js +333 -22
  426. package/dist/runner/screenshot-baselines.d.ts +159 -0
  427. package/dist/runner/screenshot-baselines.d.ts.map +1 -0
  428. package/dist/runner/screenshot-baselines.js +357 -0
  429. package/dist/runner/secrets.d.ts +13 -0
  430. package/dist/runner/secrets.d.ts.map +1 -1
  431. package/dist/runner/secrets.js +6 -4
  432. package/dist/runner/target-drivers.d.ts +5 -2
  433. package/dist/runner/target-drivers.d.ts.map +1 -1
  434. package/dist/runner/target-drivers.js +10 -1
  435. package/dist/runner/test-file-process.d.ts +8 -0
  436. package/dist/runner/test-file-process.d.ts.map +1 -1
  437. package/dist/runner/test-file-process.js +26 -3
  438. package/dist/runner/test-pages.d.ts +3 -1
  439. package/dist/runner/test-pages.d.ts.map +1 -1
  440. package/dist/runner/test-pages.js +9 -5
  441. package/dist/schemas/event-v1.schema.json +118873 -6311
  442. package/dist/schemas/result-v1.schema.json +4 -0
  443. package/dist/shared/environment.d.ts +17 -0
  444. package/dist/shared/environment.d.ts.map +1 -0
  445. package/dist/shared/environment.js +27 -0
  446. package/dist/shared/image-diff.d.ts +36 -0
  447. package/dist/shared/image-diff.d.ts.map +1 -0
  448. package/dist/shared/image-diff.js +242 -0
  449. package/dist/shared/metadata-process-worker.js +15 -7
  450. package/dist/shared/metadata-process.d.ts +9 -1
  451. package/dist/shared/metadata-process.d.ts.map +1 -1
  452. package/dist/shared/metadata-process.js +84 -12
  453. package/dist/shared/png.d.ts +35 -0
  454. package/dist/shared/png.d.ts.map +1 -0
  455. package/dist/shared/png.js +251 -0
  456. package/dist/shared/posix-path.d.ts +12 -0
  457. package/dist/shared/posix-path.d.ts.map +1 -1
  458. package/dist/shared/posix-path.js +16 -0
  459. package/dist/shared/private-file.d.ts +38 -0
  460. package/dist/shared/private-file.d.ts.map +1 -0
  461. package/dist/shared/private-file.js +132 -0
  462. package/dist/shared/process-ownership.d.ts +67 -6
  463. package/dist/shared/process-ownership.d.ts.map +1 -1
  464. package/dist/shared/process-ownership.js +227 -45
  465. package/dist/shared/process-supervisor.d.ts +309 -0
  466. package/dist/shared/process-supervisor.d.ts.map +1 -0
  467. package/dist/shared/process-supervisor.js +737 -0
  468. package/dist/shared/process-system.d.ts +113 -0
  469. package/dist/shared/process-system.d.ts.map +1 -0
  470. package/dist/shared/process-system.js +254 -0
  471. package/dist/shared/regular-file.d.ts +2 -2
  472. package/dist/shared/regular-file.d.ts.map +1 -1
  473. package/dist/shared/regular-file.js +19 -2
  474. package/dist/store/artifacts.d.ts +28 -6
  475. package/dist/store/artifacts.d.ts.map +1 -1
  476. package/dist/store/artifacts.js +58 -6
  477. package/dist/store/rebuild-result.d.ts.map +1 -1
  478. package/dist/store/rebuild-result.js +6 -0
  479. package/dist/store/run-store.d.ts +5 -2
  480. package/dist/store/run-store.d.ts.map +1 -1
  481. package/dist/store/run-store.js +48 -4
  482. package/media/Cargo.lock +16 -0
  483. package/media/Cargo.toml +16 -1
  484. package/media/src/encoder.rs +56 -12
  485. package/media/src/frame.rs +7 -1
  486. package/media/src/main.rs +20 -2
  487. package/media/src/place.rs +230 -11
  488. package/media/src/process_ownership_windows.rs +1058 -0
  489. package/media/src/recording.rs +15 -7
  490. package/media/src/replies.rs +55 -0
  491. package/media/src/server.rs +72 -2
  492. package/media/src/store.rs +71 -2
  493. package/package.json +9 -4
  494. package/src/cli/install/media-notices.txt +465 -1
  495. package/supervisor/Cargo.lock +25 -0
  496. package/supervisor/Cargo.toml +22 -0
  497. package/supervisor/NOTICES +464 -0
  498. package/supervisor/build.rs +44 -0
  499. package/supervisor/src/command.rs +612 -0
  500. package/supervisor/src/jobs.rs +1650 -0
  501. package/supervisor/src/main.rs +71 -0
  502. package/supervisor/src/reply.rs +367 -0
@@ -0,0 +1,38 @@
1
+ import type { DialogRecord, DialogType } from '../protocol/dialogs.ts';
2
+ import type { Dialog } from './page.ts';
3
+ import type { TestRun } from './test-run.ts';
4
+ /** A dialog the parent handed to the test, which the test answers through the page that showed it. */
5
+ export declare class AppDialog implements Dialog {
6
+ #private;
7
+ readonly type: DialogType;
8
+ readonly message: string;
9
+ readonly defaultValue: string;
10
+ constructor(run: TestRun, app: string, record: DialogRecord, acted: Promise<void>);
11
+ accept(promptText?: unknown): Promise<void>;
12
+ dismiss(): Promise<void>;
13
+ }
14
+ /** The test, the app and the dialect behind a page, for the waits it starts. */
15
+ export type WaitTarget = {
16
+ readonly run: TestRun;
17
+ readonly app: string;
18
+ };
19
+ /**
20
+ * Arms an app's page for its next dialog, runs `action`, and resolves with the dialog as soon as it opens, while the
21
+ * action still waits on it. `options` may shorten the wait, as `{ timeout }` does an action's.
22
+ *
23
+ * @example const dialog = await waitForDialog({ run, app: 'web' }, () => page.getByRole('button', { name: 'Delete' }).click())
24
+ */
25
+ export declare function waitForDialog({ run, app }: WaitTarget, action: unknown, options: unknown): Promise<AppDialog>;
26
+ /** What a wait for a dialog or a popup was given, once read: the action, which must return a promise, and its time. */
27
+ export type OpeningCall = {
28
+ readonly action: () => Promise<unknown>;
29
+ readonly timeoutMs: number | undefined;
30
+ };
31
+ /**
32
+ * Reads the action and the options `page.dialog()` or `page.popup()` was given, as a JavaScript caller may have passed
33
+ * them any way it liked. The action must be a function, and what it returns must be a promise, the action's own.
34
+ *
35
+ * @example readOpening('popup', run, () => page.getByRole('link', { name: 'Terms' }).click(), undefined).timeoutMs // undefined
36
+ */
37
+ export declare function readOpening(kind: 'dialog' | 'popup', run: TestRun, action: unknown, options: unknown): OpeningCall;
38
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/api/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAEtE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAM5C,sGAAsG;AACtG,qBAAa,SAAU,YAAW,MAAM;;IACtC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;gBAOjB,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC;IAUjF,MAAM,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAUzB;AAID,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAExE;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAI7G;AAED,uHAAuH;AACvH,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAE7G;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,WAAW,CAYlH"}
@@ -0,0 +1,78 @@
1
+ import { readCallOptions } from "./call-options.js";
2
+ import { formatValue } from "./format-value.js";
3
+ import { misuse } from "./misuse.js";
4
+ import { isThenable } from "./operation.js";
5
+ /** A dialog the parent handed to the test, which the test answers through the page that showed it. */
6
+ export class AppDialog {
7
+ type;
8
+ message;
9
+ defaultValue;
10
+ #run;
11
+ #app;
12
+ #id;
13
+ #acted;
14
+ #answered;
15
+ constructor(run, app, record, acted) {
16
+ this.type = record.type;
17
+ this.message = record.message;
18
+ this.defaultValue = record.defaultValue;
19
+ this.#run = run;
20
+ this.#app = app;
21
+ this.#id = record.id;
22
+ this.#acted = acted;
23
+ }
24
+ accept(promptText) {
25
+ const location = this.#run.location();
26
+ if (promptText !== undefined && typeof promptText !== 'string')
27
+ throw misuse(`accept() takes the text a prompt dialog answers with, received ${formatValue(promptText)}.`, this.#run);
28
+ if (promptText !== undefined && this.type !== 'prompt')
29
+ throw misuse(`accept() takes text only for a prompt dialog, and this is ${article(this.type)} ${this.type} dialog.`, this.#run);
30
+ return this.#answer({ accept: true, promptText, label: 'dialog.accept()', how: 'accepted', location });
31
+ }
32
+ dismiss() {
33
+ return this.#answer({ accept: false, promptText: undefined, label: 'dialog.dismiss()', how: 'dismissed', location: this.#run.location() });
34
+ }
35
+ #answer({ accept, promptText, label, how, location }) {
36
+ const answered = this.#answered;
37
+ if (answered !== undefined)
38
+ throw misuse(`This ${this.type} dialog was already ${answered.how} on ${this.#run.describeLine(answered.location)}. Answer each dialog once.`, this.#run);
39
+ this.#answered = { how, location };
40
+ return this.#run.answerDialog({ app: this.#app, dialog: this.#id, accept, promptText, label, location, acted: this.#acted });
41
+ }
42
+ }
43
+ /**
44
+ * Arms an app's page for its next dialog, runs `action`, and resolves with the dialog as soon as it opens, while the
45
+ * action still waits on it. `options` may shorten the wait, as `{ timeout }` does an action's.
46
+ *
47
+ * @example const dialog = await waitForDialog({ run, app: 'web' }, () => page.getByRole('button', { name: 'Delete' }).click())
48
+ */
49
+ export function waitForDialog({ run, app }, action, options) {
50
+ const location = run.location();
51
+ const read = readOpening('dialog', run, action, options);
52
+ return run.waitForDialog({ app, label: 'page.dialog()', location, timeoutMs: read.timeoutMs, action: read.action }, (record, acted) => new AppDialog(run, app, record, acted));
53
+ }
54
+ /**
55
+ * Reads the action and the options `page.dialog()` or `page.popup()` was given, as a JavaScript caller may have passed
56
+ * them any way it liked. The action must be a function, and what it returns must be a promise, the action's own.
57
+ *
58
+ * @example readOpening('popup', run, () => page.getByRole('link', { name: 'Terms' }).click(), undefined).timeoutMs // undefined
59
+ */
60
+ export function readOpening(kind, run, action, options) {
61
+ const call = `page.${kind}()`;
62
+ const example = kind === 'dialog' ? "() => page.getByRole('button', { name: 'Delete' }).click()" : "() => page.getByRole('link', { name: 'Terms' }).click()";
63
+ if (typeof action !== 'function')
64
+ throw misuse(`${call} takes a function that runs the action, such as ${example}, received ${formatValue(action)}.`, run);
65
+ const read = readCallOptions(kind, options);
66
+ if (!read.ok)
67
+ throw misuse(read.problem, run);
68
+ const returning = async () => {
69
+ const returned = action();
70
+ if (!isThenable(returned))
71
+ throw misuse(`${call} runs its function and waits for the promise it returns, and it returned ${formatValue(returned)}. Return the action, as in ${example}.`, run);
72
+ return returned;
73
+ };
74
+ return { action: returning, timeoutMs: read.timeoutMs };
75
+ }
76
+ function article(word) {
77
+ return /^[aeiou]/.test(word) ? 'an' : 'a';
78
+ }
@@ -0,0 +1,32 @@
1
+ import type { CallOptions } from './call-options.ts';
2
+ /**
3
+ * Options a drag takes: `steps`, how many positions the mouse moves through on its way to the target, 5 when absent and
4
+ * at most 100, and the `timeout` every action takes.
5
+ */
6
+ export type DragOptions = CallOptions & {
7
+ readonly steps?: number | undefined;
8
+ };
9
+ /**
10
+ * A drag's options as the command takes them: its steps when given, and the timeout as the caller passed it, which the
11
+ * action reads as every action reads its own.
12
+ */
13
+ export type ReadDragOptions = {
14
+ readonly ok: true;
15
+ readonly steps: {
16
+ steps?: number;
17
+ };
18
+ readonly call: {
19
+ readonly timeout: unknown;
20
+ } | undefined;
21
+ } | {
22
+ readonly ok: false;
23
+ readonly problem: string;
24
+ };
25
+ /**
26
+ * Reads the options a JavaScript caller may have passed `dragTo` any way it liked, and says what is wrong as a sentence.
27
+ * `timeout` is left for the action to read, as every action reads its own.
28
+ *
29
+ * @example readDragOptions({ steps: 10, timeout: 2000 }) // { ok: true, steps: { steps: 10 }, call: { timeout: 2000 } }
30
+ */
31
+ export declare function readDragOptions(options: unknown): ReadDragOptions;
32
+ //# sourceMappingURL=drag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/api/drag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAKpD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAE/E;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpM;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,CAWjE"}
@@ -0,0 +1,26 @@
1
+ import { dragProblem } from "../protocol/drag.js";
2
+ import { isPlainObject } from "../protocol/schema.js";
3
+ import { formatValue } from "./format-value.js";
4
+ /**
5
+ * Reads the options a JavaScript caller may have passed `dragTo` any way it liked, and says what is wrong as a sentence.
6
+ * `timeout` is left for the action to read, as every action reads its own.
7
+ *
8
+ * @example readDragOptions({ steps: 10, timeout: 2000 }) // { ok: true, steps: { steps: 10 }, call: { timeout: 2000 } }
9
+ */
10
+ export function readDragOptions(options) {
11
+ if (options === undefined)
12
+ return { ok: true, steps: {}, call: undefined };
13
+ if (!isPlainObject(options))
14
+ return { ok: false, problem: `dragTo() takes options such as { steps: 10, timeout: 2000 }, received ${formatValue(options)}.` };
15
+ const given = Object.entries(options).filter(([, value]) => value !== undefined);
16
+ const unknown = given.find(([key]) => key !== 'steps' && key !== 'timeout');
17
+ if (unknown !== undefined)
18
+ return { ok: false, problem: `Unknown dragTo() option ${JSON.stringify(unknown[0])}. Its options are steps and timeout.` };
19
+ const { steps, timeout } = Object.fromEntries(given);
20
+ if (steps !== undefined && typeof steps !== 'number')
21
+ return { ok: false, problem: `dragTo() takes steps as a whole number from 1 to 100, received ${formatValue(steps)}.` };
22
+ const problem = dragProblem({ steps });
23
+ if (problem !== undefined)
24
+ return { ok: false, problem: problem.message };
25
+ return { ok: true, steps: steps === undefined ? {} : { steps }, call: timeout === undefined ? undefined : { timeout } };
26
+ }
@@ -0,0 +1,49 @@
1
+ import type { InputFileRecord } from '../protocol/files.ts';
2
+ import type { LocatorRecipe } from '../protocol/locator.ts';
3
+ import type { Download, FileChooser } from './page.ts';
4
+ import type { TestRun } from './test-run.ts';
5
+ /** The test, app and recipe behind a locator, as giving files to it needs them. */
6
+ type InputTarget = {
7
+ readonly run: TestRun;
8
+ readonly app: string;
9
+ readonly recipe: LocatorRecipe;
10
+ };
11
+ /** The test and app behind a page. */
12
+ type PageTarget = {
13
+ readonly run: TestRun;
14
+ readonly app: string;
15
+ };
16
+ /**
17
+ * Gives the one file input a locator finds the files: the input that `setInputFiles` is called on.
18
+ *
19
+ * @example await setInputFiles(target, './report.pdf', undefined)
20
+ */
21
+ export declare function setInputFiles({ run, app, recipe }: InputTarget, files: unknown, options: unknown): Promise<void>;
22
+ /**
23
+ * Arms the app's page for the next file picker it opens, runs `action`, and gives the picker that opened. The wait for
24
+ * it starts before the action and lasts the action budget, or a shorter `{ timeout }`.
25
+ *
26
+ * @example const chooser = await fileChooser(page, () => button.click(), undefined)
27
+ */
28
+ export declare function fileChooser(page: PageTarget, action: unknown, options: unknown): Promise<FileChooser>;
29
+ /**
30
+ * Arms the app's page for the next download it begins, runs `action`, and gives the download that began. The wait for
31
+ * it starts before the action and lasts the action budget, or a shorter `{ timeout }`.
32
+ *
33
+ * @example const download = await download(page, () => link.click(), undefined)
34
+ */
35
+ export declare function download(page: PageTarget, action: unknown, options: unknown): Promise<Download>;
36
+ /** The files a test gave, as the parent takes them, and whether it gave a list. */
37
+ type ReadFiles = {
38
+ files: InputFileRecord[];
39
+ list: boolean;
40
+ };
41
+ /**
42
+ * Reads the files a JavaScript caller may have passed any way it liked, and says what is wrong as a sentence. A path is
43
+ * kept as the test wrote it, with the folder it is read against.
44
+ *
45
+ * @example readInputFiles('./report.pdf', '/work/tests', 'setInputFiles') // { files: [{ path: './report.pdf', folder: '/work/tests' }], list: false }
46
+ */
47
+ export declare function readInputFiles(value: unknown, folder: string, method: string): ReadFiles | string;
48
+ export {};
49
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/api/files.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAc,MAAM,WAAW,CAAA;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAU5C,mFAAmF;AACnF,KAAK,WAAW,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAA;AAElG,sCAAsC;AACtC,KAAK,UAAU,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAkEjE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhH;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAUrG;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAU/F;AAQD,mFAAmF;AACnF,KAAK,SAAS,GAAG;IAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAejG"}
@@ -0,0 +1,168 @@
1
+ import { copyFile, mkdir } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { errorMessage, failure } from "../protocol/failures.js";
4
+ import { inputFilesProblem } from "../protocol/files.js";
5
+ import { isArray, isPlainObject } from "../protocol/schema.js";
6
+ import { readCallOptions } from "./call-options.js";
7
+ import { formatValue } from "./format-value.js";
8
+ import { misuse } from "./misuse.js";
9
+ /** A file picker the parent caught for the test, whose input the test gives files through the page that opened it. */
10
+ class AppFileChooser {
11
+ multiple;
12
+ #page;
13
+ #chooser;
14
+ constructor(page, chooser, multiple) {
15
+ this.#page = page;
16
+ this.#chooser = chooser;
17
+ this.multiple = multiple;
18
+ }
19
+ setFiles(files, options) {
20
+ const { run, app } = this.#page;
21
+ const location = run.location();
22
+ const read = readInputFiles(files, run.callerFolder(location), 'setFiles');
23
+ if (typeof read === 'string')
24
+ throw misuse(read, run);
25
+ return run.action(app, { kind: 'setChooserFiles', chooser: this.#chooser, files: read.files, ...(read.list ? { list: true } : {}) }, location, options);
26
+ }
27
+ }
28
+ /** A download the parent caught for the test, whose saved file the test asks the parent for. */
29
+ class AppDownload {
30
+ suggestedFilename;
31
+ #page;
32
+ #download;
33
+ constructor(page, download, suggestedFilename) {
34
+ this.#page = page;
35
+ this.#download = download;
36
+ this.suggestedFilename = suggestedFilename;
37
+ }
38
+ path(options) {
39
+ return this.#saved('download.path()', 'path', options, async (path) => path);
40
+ }
41
+ saveAs(path, options) {
42
+ const { run } = this.#page;
43
+ if (typeof path !== 'string' || path === '')
44
+ throw misuse(`download.saveAs() takes the path to copy the file to, received ${formatValue(path)}.`, run);
45
+ const target = resolve(run.callerFolder(run.location()), path);
46
+ return this.#saved('download.saveAs()', 'saveAs', options, async (saved) => {
47
+ try {
48
+ await mkdir(dirname(target), { recursive: true });
49
+ await copyFile(saved, target);
50
+ }
51
+ catch (error) {
52
+ throw run.fail(failure('usage', `download.saveAs() could not copy ${this.suggestedFilename} to ${target}: ${errorMessage(error)}`, run.location()));
53
+ }
54
+ });
55
+ }
56
+ #saved(label, method, options, then) {
57
+ const { run } = this.#page;
58
+ const location = run.location();
59
+ const read = readCallOptions(method, options);
60
+ if (!read.ok)
61
+ throw misuse(read.problem, run);
62
+ const timeoutMs = Math.min(read.timeoutMs ?? run.timeouts.navigation, run.timeouts.navigation);
63
+ return run.awaitFiles({ label, request: { kind: 'saved', download: this.#download }, location, timeoutMs }, (answer) => {
64
+ if (answer.kind !== 'saved')
65
+ throw new Error(`Retest answered a wait for a saved download with ${answer.kind}`);
66
+ return then(answer.path);
67
+ });
68
+ }
69
+ }
70
+ /**
71
+ * Gives the one file input a locator finds the files: the input that `setInputFiles` is called on.
72
+ *
73
+ * @example await setInputFiles(target, './report.pdf', undefined)
74
+ */
75
+ export function setInputFiles({ run, app, recipe }, files, options) {
76
+ const location = run.location();
77
+ const read = readInputFiles(files, run.callerFolder(location), 'setInputFiles');
78
+ if (typeof read === 'string')
79
+ throw misuse(read, run);
80
+ return run.action(app, { kind: 'setInputFiles', locator: recipe, files: read.files, ...(read.list ? { list: true } : {}) }, location, options);
81
+ }
82
+ /**
83
+ * Arms the app's page for the next file picker it opens, runs `action`, and gives the picker that opened. The wait for
84
+ * it starts before the action and lasts the action budget, or a shorter `{ timeout }`.
85
+ *
86
+ * @example const chooser = await fileChooser(page, () => button.click(), undefined)
87
+ */
88
+ export function fileChooser(page, action, options) {
89
+ const { run } = page;
90
+ const location = run.location();
91
+ if (typeof action !== 'function')
92
+ throw misuse(`page.fileChooser() takes the action that opens the picker, such as () => upload.click(), received ${formatValue(action)}.`, run);
93
+ const timeoutMs = actionBudget(run, 'fileChooser', options);
94
+ const request = { kind: 'chooser', app: page.app };
95
+ return run.awaitFiles({ label: 'page.fileChooser()', request, location, timeoutMs }, (answer) => {
96
+ if (answer.kind !== 'chooser')
97
+ throw new Error(`Retest answered a wait for a file picker with ${answer.kind}`);
98
+ return new AppFileChooser(page, answer.chooser, answer.multiple);
99
+ }, () => action());
100
+ }
101
+ /**
102
+ * Arms the app's page for the next download it begins, runs `action`, and gives the download that began. The wait for
103
+ * it starts before the action and lasts the action budget, or a shorter `{ timeout }`.
104
+ *
105
+ * @example const download = await download(page, () => link.click(), undefined)
106
+ */
107
+ export function download(page, action, options) {
108
+ const { run } = page;
109
+ const location = run.location();
110
+ if (typeof action !== 'function')
111
+ throw misuse(`page.download() takes the action that starts the download, such as () => link.click(), received ${formatValue(action)}.`, run);
112
+ const timeoutMs = actionBudget(run, 'download', options);
113
+ const request = { kind: 'download', app: page.app };
114
+ return run.awaitFiles({ label: 'page.download()', request, location, timeoutMs }, (answer) => {
115
+ if (answer.kind !== 'download')
116
+ throw new Error(`Retest answered a wait for a download with ${answer.kind}`);
117
+ return new AppDownload(page, answer.download, answer.suggestedFilename);
118
+ }, () => action());
119
+ }
120
+ function actionBudget(run, method, options) {
121
+ const read = readCallOptions(method, options);
122
+ if (!read.ok)
123
+ throw misuse(read.problem, run);
124
+ return Math.min(read.timeoutMs ?? run.timeouts.action, run.timeouts.action);
125
+ }
126
+ /**
127
+ * Reads the files a JavaScript caller may have passed any way it liked, and says what is wrong as a sentence. A path is
128
+ * kept as the test wrote it, with the folder it is read against.
129
+ *
130
+ * @example readInputFiles('./report.pdf', '/work/tests', 'setInputFiles') // { files: [{ path: './report.pdf', folder: '/work/tests' }], list: false }
131
+ */
132
+ export function readInputFiles(value, folder, method) {
133
+ const list = isArray(value);
134
+ const given = isArray(value) ? value : [value];
135
+ const files = [];
136
+ for (const item of given) {
137
+ const file = readInputFile(item, folder);
138
+ if (file === undefined) {
139
+ const shown = list ? `a list holding ${formatValue(item)}` : formatValue(value);
140
+ return `${method}() takes a path, a file such as { name: 'notes.txt', content: 'hello' }, or a list of them, received ${shown}.`;
141
+ }
142
+ if (typeof file === 'string')
143
+ return `${method}() ${file}`;
144
+ files.push(file);
145
+ }
146
+ const problem = inputFilesProblem(files, method);
147
+ return problem === undefined ? { files, list } : problem.message;
148
+ }
149
+ // One file, or undefined for something that is not one, or what is wrong with a file by content.
150
+ function readInputFile(item, folder) {
151
+ if (typeof item === 'string')
152
+ return { path: item, folder };
153
+ if (!isPlainObject(item))
154
+ return undefined;
155
+ const given = Object.entries(item).filter(([, entry]) => entry !== undefined);
156
+ const unknown = given.find(([key]) => key !== 'name' && key !== 'mimeType' && key !== 'content');
157
+ if (unknown !== undefined)
158
+ return `has no file option ${JSON.stringify(unknown[0])}. A file by content takes name, mimeType and content.`;
159
+ const { name, mimeType, content } = Object.fromEntries(given);
160
+ if (typeof name !== 'string')
161
+ return `takes a file's name as text, received ${formatValue(name)}.`;
162
+ if (mimeType !== undefined && typeof mimeType !== 'string')
163
+ return `takes mimeType as text, such as 'text/plain', received ${formatValue(mimeType)}.`;
164
+ const bytes = typeof content === 'string' ? Buffer.from(content, 'utf8') : content instanceof Uint8Array ? Buffer.from(content.buffer, content.byteOffset, content.byteLength) : undefined;
165
+ if (bytes === undefined)
166
+ return `takes a file's content as text or bytes, received ${formatValue(content)}.`;
167
+ return { name, ...(mimeType === undefined ? {} : { mimeType }), base64: bytes.toString('base64') };
168
+ }
@@ -0,0 +1,97 @@
1
+ import type { InboxName } from '../config/register.ts';
2
+ import type { InboxCodeRef, InboxLinkRef, ReceivedMessageRecord } from '../protocol/inbox.ts';
3
+ import { Secret } from './secret.ts';
4
+ /**
5
+ * How `latest()` reads: `subject` picks the newest message whose subject holds this text, in any case, or matches this
6
+ * `RegExp`, as the test reads the subject, with its codes and links replaced by placeholders. `timeout` is how long it
7
+ * looks, in milliseconds, the assertion budget by default, never longer than the test has left.
8
+ */
9
+ export type InboxReadOptions = {
10
+ readonly subject?: string | RegExp | undefined;
11
+ readonly timeout?: number | undefined;
12
+ };
13
+ /** Which link `link()` takes: its number among the message's links, from 1, or the first whose path is `path` or lies under it. */
14
+ export type LinkChoice = number | {
15
+ readonly path: string;
16
+ };
17
+ /**
18
+ * A link in a received message: the text it was shown under, its origin, and its path with each token in it replaced
19
+ * by its placeholder. `token` says whether it carries a token. Its query and fragment are never in the test's process.
20
+ */
21
+ export type ReceivedLink = {
22
+ readonly text: string;
23
+ readonly origin: string;
24
+ readonly path: string;
25
+ readonly token: boolean;
26
+ };
27
+ /**
28
+ * A one-time code from a message, named but never held: the process that runs Retest types it, bound to origins as a
29
+ * secret is. It is a secret, so it goes only to `fill()`, and however it is printed it reads `{{code}}`.
30
+ */
31
+ export declare class InboxCode extends Secret {
32
+ #private;
33
+ constructor(reference: InboxCodeRef);
34
+ }
35
+ /**
36
+ * A link from a message, named but never held: the process that runs Retest opens it, when its origin is one the test
37
+ * may open. It goes only to `goto()`, and however it is printed it reads `{{link}}`, or `{{link:2}}` when it was chosen
38
+ * by number or path.
39
+ */
40
+ export declare class InboxLink {
41
+ #private;
42
+ constructor(reference: InboxLinkRef);
43
+ toString(): string;
44
+ toJSON(): string;
45
+ }
46
+ /**
47
+ * A message an inbox gave the test. `subject`, `from` and `text` have each code written `{{code}}` and each link that
48
+ * carries a token written `{{link:1}}`, `{{link:2}}` and so on, by its number. `code` is its first code, for `fill()`,
49
+ * and `link()` one of its links, for `goto()`; the test's process never holds either value.
50
+ */
51
+ export declare class ReceivedMessage {
52
+ #private;
53
+ readonly subject: string;
54
+ readonly from: string;
55
+ readonly text: string;
56
+ /** When the mailbox received it. */
57
+ readonly receivedAt: Date;
58
+ readonly links: readonly ReceivedLink[];
59
+ /** The message's first code. A fill of it fails when the message holds none. */
60
+ readonly code: InboxCode;
61
+ constructor(record: ReceivedMessageRecord);
62
+ /**
63
+ * One of the message's links, for `goto()`. With no argument, the first link that carries a token, or else the first
64
+ * link. A number takes that link, from 1; `{ path }` the first link whose path is `path` or lies under it.
65
+ *
66
+ * @example await page.goto(message.link({ path: '/verify' }))
67
+ */
68
+ link(choice?: LinkChoice): InboxLink;
69
+ }
70
+ /** A test mailbox from the config, named for the reads a test makes of it. */
71
+ export declare class Inbox {
72
+ #private;
73
+ constructor(name: string);
74
+ /** The inbox's name in the config. */
75
+ get name(): string;
76
+ /**
77
+ * Waits for the newest message the mailbox received since the test started, or since the last message this test was
78
+ * given from it, and gives it to the test. It looks again, as a matcher does, until one arrives or its time runs out.
79
+ *
80
+ * @example const message = await inbox('owner').latest({ subject: 'Your sign-in code' })
81
+ */
82
+ latest(options?: InboxReadOptions): Promise<ReceivedMessage>;
83
+ }
84
+ /**
85
+ * Names an inbox from the config, whose messages a test reads with `latest()`. The test's process never holds a code or
86
+ * a link that carries a token.
87
+ *
88
+ * @example
89
+ * const message = await inbox('owner').latest({ subject: 'Your sign-in code' })
90
+ * await page.getByLabel('Code').fill(message.code)
91
+ */
92
+ export declare function inbox(name: InboxName): Inbox;
93
+ /** The code a value names, when it is a code from an inbox. */
94
+ export declare function inboxCodeReference(value: unknown): InboxCodeRef | undefined;
95
+ /** The link a value names, when it is a link from an inbox. */
96
+ export declare function inboxLinkReference(value: unknown): InboxLinkRef | undefined;
97
+ //# sourceMappingURL=inbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/api/inbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAgB,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAS3G,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAExH,mIAAmI;AACnI,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3D;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAK7H;;;GAGG;AACH,qBAAa,SAAU,SAAQ,MAAM;;gBAOvB,SAAS,EAAE,YAAY;CAIpC;AAED;;;;GAIG;AACH,qBAAa,SAAS;;gBAaR,SAAS,EAAE,YAAY;IAInC,QAAQ,IAAI,MAAM;IAIlB,MAAM,IAAI,MAAM;CAGjB;AAED;;;;GAIG;AACH,qBAAa,eAAe;;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAA;IACvC,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;gBAGZ,MAAM,EAAE,qBAAqB;IAUzC;;;;;OAKG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS;CA+BrC;AAED,8EAA8E;AAC9E,qBAAa,KAAK;;gBAGJ,IAAI,EAAE,MAAM;IAIxB,sCAAsC;IACtC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CAS7D;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,SAAS,GAAG,KAAK,CAK5C;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAE3E;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAE3E"}