@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
@@ -47,6 +47,14 @@ export type FailureCard = CardSubject & {
47
47
  location?: SourceLocation;
48
48
  /** Paths inside the run folder, joined to the run folder as it was given. */
49
49
  screenshots: string[];
50
+ /**
51
+ * The files the failing assertion left, each by what it is, such as a screenshot comparison's expected and actual
52
+ * pictures and their difference, joined to the run folder as it was given. Absent when it left none.
53
+ */
54
+ attachments?: {
55
+ name: string;
56
+ path: string;
57
+ }[];
50
58
  evidenceProblems: string[];
51
59
  /** Cleanup failures besides `failure`. */
52
60
  cleanupFailures: Failure[];
@@ -106,7 +114,8 @@ export type RecordedValues = {
106
114
  export declare function recordedValues(call: FailingCall | undefined): RecordedValues | undefined;
107
115
  /**
108
116
  * Whether the failure's message only repeats the recorded values, as the message of a check that failed on
109
- * them does. Any other failure, such as a timeout that stopped the check, says something the values do not.
117
+ * them does. Any other failure, such as a timeout that stopped the check, says something the values do not, and so
118
+ * does a screenshot comparison's, which names the baseline's file, the ratio of pixels and how many may differ.
110
119
  */
111
120
  export declare function messageRepeatsValues(card: FailureCard): boolean;
112
121
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"failure-card.d.ts","sourceRoot":"","sources":["../../src/reporters/failure-card.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"failure-card.d.ts","sourceRoot":"","sources":["../../src/reporters/failure-card.ts"],"names":[],"mappings":"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"}
@@ -154,6 +154,7 @@ export function testCard(test, options) {
154
154
  notRunChecks: notRunHostChecks(test),
155
155
  location: call?.location ?? failure?.location ?? test.location,
156
156
  screenshots: evidencePaths(events, test).map((path) => join(options.runFolder, path)),
157
+ ...(call?.type === 'assertion.failed' && call.attachments !== undefined ? { attachments: call.attachments.map(({ name, path }) => ({ name, path: join(options.runFolder, path) })) } : {}),
157
158
  evidenceProblems: events.flatMap((event) => (event.type === 'evidence.failed' ? [event.message] : [])),
158
159
  cleanupFailures,
159
160
  evaluations: evaluationCardLines(test.evaluations ?? [], options.runFolder),
@@ -212,9 +213,12 @@ export function recordedValues(call) {
212
213
  }
213
214
  /**
214
215
  * Whether the failure's message only repeats the recorded values, as the message of a check that failed on
215
- * them does. Any other failure, such as a timeout that stopped the check, says something the values do not.
216
+ * them does. Any other failure, such as a timeout that stopped the check, says something the values do not, and so
217
+ * does a screenshot comparison's, which names the baseline's file, the ratio of pixels and how many may differ.
216
218
  */
217
219
  export function messageRepeatsValues(card) {
220
+ if (card.call?.type === 'assertion.failed' && card.call.matcher === 'toHaveScreenshot')
221
+ return false;
218
222
  return card.failure?.class === 'check_failed' && recordedValues(card.call) !== undefined;
219
223
  }
220
224
  /**
@@ -29,6 +29,13 @@ export declare function runNotes(result: {
29
29
  complete: boolean;
30
30
  narrowed?: Narrowed | undefined;
31
31
  }): string[];
32
+ /**
33
+ * How many screenshot baselines a run wrote, as reports say it, so a run that wrote them never reads as an ordinary
34
+ * pass: its checks compared nothing with what they wrote.
35
+ *
36
+ * @example describeBaselinesWritten(2) // '2 written by --update-screenshots'
37
+ */
38
+ export declare function describeBaselinesWritten(count: number): string;
32
39
  export declare function totalTests(counts: Counts): number;
33
40
  /**
34
41
  * How `test.only` narrowed a run, as the warning a report prints.
@@ -45,6 +52,32 @@ export declare function describeLocks(event: {
45
52
  locks: readonly string[];
46
53
  waitedMs: number;
47
54
  }): string;
55
+ /**
56
+ * A test's read of an inbox: the message it was given, by its subject as the test read it, or that it was given none,
57
+ * and how many looks it took.
58
+ *
59
+ * @example describeInboxRead({ inbox: 'owner', subject: 'Your code is {{code}}', looks: 3 }) // 'inbox owner gave "Your code is {{code}}" after 3 looks'
60
+ */
61
+ export declare function describeInboxRead(event: {
62
+ inbox: string;
63
+ subject?: string | undefined;
64
+ looks: number;
65
+ }): string;
66
+ /**
67
+ * A download a page made: the name the browser suggested, where it began when not in the app's page, and its size once
68
+ * saved, that Retest removed it for holding a secret, how much of it arrived when the browser stopped it, or that it was
69
+ * still on its way when its test ended.
70
+ *
71
+ * @example describeDownload({ suggestedFilename: 'tasks.csv', state: 'completed', size: 35 }) // 'download tasks.csv, 35 bytes'
72
+ */
73
+ export declare function describeDownload(event: {
74
+ suggestedFilename: string;
75
+ startedIn?: 'popup' | 'other' | undefined;
76
+ state: 'completed' | 'withheld' | 'canceled' | 'unfinished';
77
+ size?: number | undefined;
78
+ receivedBytes?: number | undefined;
79
+ totalBytes?: number | undefined;
80
+ }): string;
48
81
  /**
49
82
  * The desktop, devices and data folders an attempt took, and how long it waited for them.
50
83
  *
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/reporters/format.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/reporters/format.ts"],"names":[],"mappings":"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"}
@@ -91,6 +91,15 @@ export function runNotes(result) {
91
91
  ...(result.narrowed === undefined ? [] : ['narrowed by test.only']),
92
92
  ];
93
93
  }
94
+ /**
95
+ * How many screenshot baselines a run wrote, as reports say it, so a run that wrote them never reads as an ordinary
96
+ * pass: its checks compared nothing with what they wrote.
97
+ *
98
+ * @example describeBaselinesWritten(2) // '2 written by --update-screenshots'
99
+ */
100
+ export function describeBaselinesWritten(count) {
101
+ return `${count} written by --update-screenshots`;
102
+ }
94
103
  export function totalTests(counts) {
95
104
  return counts.passed + counts.failed + counts.error + counts.notRun + counts.inconclusive + (counts.skipped ?? 0);
96
105
  }
@@ -112,6 +121,39 @@ export function describeLocks(event) {
112
121
  const held = `holds ${event.locks.length === 1 ? 'lock' : 'locks'} ${listWords(event.locks, 'and')}`;
113
122
  return event.waitedMs === 0 ? held : `${held}, after waiting ${formatDuration(event.waitedMs)}`;
114
123
  }
124
+ /**
125
+ * A test's read of an inbox: the message it was given, by its subject as the test read it, or that it was given none,
126
+ * and how many looks it took.
127
+ *
128
+ * @example describeInboxRead({ inbox: 'owner', subject: 'Your code is {{code}}', looks: 3 }) // 'inbox owner gave "Your code is {{code}}" after 3 looks'
129
+ */
130
+ export function describeInboxRead(event) {
131
+ const given = event.subject === undefined ? 'gave no message' : `gave ${JSON.stringify(event.subject)}`;
132
+ return `inbox ${event.inbox} ${given}${event.looks === 0 ? '' : ` after ${plural(event.looks, 'look')}`}`;
133
+ }
134
+ /**
135
+ * A download a page made: the name the browser suggested, where it began when not in the app's page, and its size once
136
+ * saved, that Retest removed it for holding a secret, how much of it arrived when the browser stopped it, or that it was
137
+ * still on its way when its test ended.
138
+ *
139
+ * @example describeDownload({ suggestedFilename: 'tasks.csv', state: 'completed', size: 35 }) // 'download tasks.csv, 35 bytes'
140
+ */
141
+ export function describeDownload(event) {
142
+ const started = event.startedIn === undefined ? '' : event.startedIn === 'popup' ? ' from a page it opened' : ' from another page';
143
+ const name = `download ${printable(event.suggestedFilename)}${started}`;
144
+ const received = event.receivedBytes ?? 0;
145
+ const arrived = event.totalBytes === undefined || event.totalBytes === 0 ? plural(received, 'byte') : `${received} of ${plural(event.totalBytes, 'byte')}`;
146
+ switch (event.state) {
147
+ case 'completed':
148
+ return `${name}, ${plural(event.size ?? 0, 'byte')}`;
149
+ case 'withheld':
150
+ return `${name} not kept: it held a secret`;
151
+ case 'canceled':
152
+ return `${name} stopped after ${arrived}`;
153
+ case 'unfinished':
154
+ return `${name} unfinished when the test ended, ${arrived}`;
155
+ }
156
+ }
115
157
  /**
116
158
  * The desktop, devices and data folders an attempt took, and how long it waited for them.
117
159
  *
@@ -0,0 +1,12 @@
1
+ import type { FailureCard } from '../failure-card.ts';
2
+ import type { ArtifactFiles } from './artifact-files.ts';
3
+ import type { Markup } from './markup.ts';
4
+ /**
5
+ * The pictures a failed screenshot comparison left, side by side, each linked to its file in the run folder: the
6
+ * baseline it expected, the picture the page showed, and where the two differ, in red. A picture the safe read refuses
7
+ * is named in a frame where it would have been. Undefined when the failing call left no pictures.
8
+ *
9
+ * @example comparisonView(card, context.files)
10
+ */
11
+ export declare function comparisonView(card: FailureCard, files: ArtifactFiles): Markup | undefined;
12
+ //# sourceMappingURL=comparison-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparison-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/comparison-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAMzC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAS1F"}
@@ -0,0 +1,21 @@
1
+ import { html } from "./markup.js";
2
+ import { pictureView } from "./screenshots-view.js";
3
+ const names = { expected: 'Expected', actual: 'Actual', diff: 'Difference' };
4
+ /**
5
+ * The pictures a failed screenshot comparison left, side by side, each linked to its file in the run folder: the
6
+ * baseline it expected, the picture the page showed, and where the two differ, in red. A picture the safe read refuses
7
+ * is named in a frame where it would have been. Undefined when the failing call left no pictures.
8
+ *
9
+ * @example comparisonView(card, context.files)
10
+ */
11
+ export function comparisonView(card, files) {
12
+ const { call } = card;
13
+ if (call?.type !== 'assertion.failed' || call.attachments === undefined || call.attachments.length === 0)
14
+ return undefined;
15
+ const subject = call.screenshot === undefined ? 'the check' : `"${call.screenshot.name}"`;
16
+ const shown = call.attachments.map(({ name, path }) => {
17
+ const label = names[name] ?? name;
18
+ return pictureView(files.picture(path), `${label} picture of ${subject}`, `${label} · ${path}`);
19
+ });
20
+ return html `<div class="shots comparison">${shown}</div>`;
21
+ }
@@ -135,11 +135,19 @@ function requestRow(row, clock) {
135
135
  ...(failed === undefined ? [] : [failed.blocked === undefined ? failed.reason : `${failed.reason}, blocked: ${failed.blocked}`]),
136
136
  ...(pending === undefined ? [] : [describePending(pending)]),
137
137
  ...(response?.serviceWorker === true ? ['answered by a service worker'] : []),
138
+ ...mockedBy(response?.route ?? failed?.route, failed?.routeRefused),
138
139
  ];
139
140
  const during = elapsed === undefined ? undefined : clock.during(elapsed);
140
141
  const under = [...endings, ...(during === undefined ? [] : [`during ${during}`])].map((line) => html `<div class="muted small words">${line}</div>`);
141
142
  return html `<tr><td class="time">${elapsed === undefined ? '?' : formatDuration(elapsed)}</td><td class="muted">${request.requestId}</td><td>${request.method}</td><td>${status}</td><td class="number">${durationMs === undefined ? '' : formatMilliseconds(durationMs)}</td><td><span class="words">${request.url}</span>${under}</td></tr>`;
142
143
  }
144
+ // A hop one of the page's routes answered or refused is the test's own, and says which route, and why Chrome refused
145
+ // the route's answer when it did.
146
+ function mockedBy(route, refused) {
147
+ if (route === undefined)
148
+ return [];
149
+ return [`mocked by page.route(${route})${refused === undefined ? '' : `, whose answer Chrome refused: ${refused}`}`];
150
+ }
143
151
  // A hop handed outside the scope is not pending: its end is reported where Retest does not listen.
144
152
  function describePending({ reason, lastState }) {
145
153
  return reason === 'out_of_scope' ? `out of scope after it was ${lastState}` : `pending, ${lastState}, ${reason.replaceAll('_', ' ')}`;
@@ -0,0 +1,10 @@
1
+ import type { TestEvent } from '../run-record.ts';
2
+ import type { Markup } from './markup.ts';
3
+ /**
4
+ * A test's downloads, each linked to its file in the run folder so a reviewer can open it, or saying why there is none:
5
+ * the browser stopped it, it was unfinished when the test ended, or its file is not where its record says.
6
+ *
7
+ * @example downloadsView(events, '/work/.retest/runs/2026-10-14T10-00-00')
8
+ */
9
+ export declare function downloadsView(events: readonly TestEvent[], directory: string): Markup | undefined;
10
+ //# sourceMappingURL=downloads-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloads-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/downloads-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAQzC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjG"}
@@ -0,0 +1,29 @@
1
+ import { checkArtifact } from "../../store/artifacts.js";
2
+ import { describeDownload, failureLabel } from "../format.js";
3
+ import { artifactLink, html } from "./markup.js";
4
+ // Larger than any file a test downloads; the report links to the file and never reads it.
5
+ const maxDownloadBytes = Number.MAX_SAFE_INTEGER;
6
+ /**
7
+ * A test's downloads, each linked to its file in the run folder so a reviewer can open it, or saying why there is none:
8
+ * the browser stopped it, it was unfinished when the test ended, or its file is not where its record says.
9
+ *
10
+ * @example downloadsView(events, '/work/.retest/runs/2026-10-14T10-00-00')
11
+ */
12
+ export function downloadsView(events, directory) {
13
+ const downloads = events.filter((event) => event.type === 'download');
14
+ if (downloads.length === 0)
15
+ return undefined;
16
+ return html `<ul class="downloads">${downloads.map((event) => html `<li class="words">${downloadItem(event, directory)}</li>`)}</ul>`;
17
+ }
18
+ function downloadItem(event, directory) {
19
+ const what = describeDownload(event);
20
+ if (event.state !== 'completed' || event.path === undefined) {
21
+ const failed = event.failure === undefined ? '' : html ` <span class="status status-failed">${failureLabel(event.failure.class)}</span>`;
22
+ return html `${what}${failed}`;
23
+ }
24
+ const checked = checkArtifact(directory, event.path, { maxBytes: maxDownloadBytes });
25
+ const link = artifactLink(event.path);
26
+ if (!checked.ok || link === undefined)
27
+ return html `${what}: <code>${event.path}</code> cannot be opened (${checked.ok ? 'not a path inside the run folder' : checked.message})`;
28
+ return html `<a href="${link}" download><code>${event.path}</code></a> · ${what}`;
29
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/style.ts"],"names":[],"mappings":"AAIA,yEAAyE;AACzE,eAAO,MAAM,UAAU,EAAE,MAqIxB,CAAA"}
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/style.ts"],"names":[],"mappings":"AAIA,yEAAyE;AACzE,eAAO,MAAM,UAAU,EAAE,MAwIxB,CAAA"}
@@ -113,6 +113,9 @@ tr.row-failed td.what { color: var(--failed); }
113
113
  .shot { margin: 0; max-width: 100%; }
114
114
  .shot img, .shot video { display: block; max-width: min(100%, 38rem); height: auto; border: 1px solid var(--rule); border-radius: 4px; }
115
115
  .shot figcaption { font-size: 12px; color: var(--muted); margin-top: 4px; overflow-wrap: anywhere; }
116
+ .comparison { flex-wrap: nowrap; }
117
+ .comparison .shot { flex: 1 1 0; min-width: 0; max-width: 24rem; }
118
+ .comparison .shot img { width: 100%; max-width: 100%; height: auto; }
116
119
  .gap { margin: 10px 0 0; padding: 12px 14px; border: 1.5px dashed var(--muted); border-radius: 4px; color: var(--muted); font-size: 13px; overflow-wrap: anywhere; }
117
120
  .gap strong { color: var(--ink); font-weight: 600; }
118
121
  .part { margin: 14px 0 0; }
@@ -1 +1 @@
1
- {"version":3,"file":"summary-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/summary-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAmB/C,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAO5F;AA+ED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAQ1F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAK7F"}
1
+ {"version":3,"file":"summary-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/summary-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAmB/C,uEAAuE;AACvE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAO5F;AAgFD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAQ1F;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAK7F"}
@@ -1,7 +1,7 @@
1
1
  import { diagnosticsTotals } from "../../diagnostics/report.js";
2
2
  import { countEvaluations } from "../../evaluation/report.js";
3
3
  import { describeFileProblem, runFailureToShow } from "../failure-card.js";
4
- import { countParts, describeNarrowed, failureLabel, formatDetail, formatDuration, runNotes, testTitle } from "../format.js";
4
+ import { countParts, describeBaselinesWritten, describeNarrowed, failureLabel, formatDetail, formatDuration, runNotes, testTitle } from "../format.js";
5
5
  import { countHostChecks } from "../host-checks.js";
6
6
  import { describeBrowser, describeNative, targetSummaries, variantLabel } from "../targets.js";
7
7
  import { codeFrameView, failureView } from "./failure-view.js";
@@ -113,7 +113,8 @@ function noticesView(context) {
113
113
  const stopped = result.status === 'interrupted' ? html `<div class="notice notice-error">The run was stopped before it finished. Tests it had not reached did not run.</div>` : undefined;
114
114
  const incomplete = result.complete ? undefined : html `<div class="notice notice-error">The run is incomplete: it did not check everything it was asked to check.</div>`;
115
115
  const narrowed = result.narrowed === undefined ? undefined : html `<div class="notice notice-error words">${describeNarrowed(result.narrowed)}</div>`;
116
- return html `${read}${failed}${stopped}${incomplete}${narrowed}`;
116
+ const baselines = result.baselinesWritten === undefined ? undefined : html `<div class="notice notice-error words">Screenshot baselines: ${describeBaselinesWritten(result.baselinesWritten)}, so their checks compared nothing.</div>`;
117
+ return html `${read}${failed}${stopped}${incomplete}${narrowed}${baselines}`;
117
118
  }
118
119
  /**
119
120
  * Every test in one table, in run order, each linked to its section: its status, title, targets, time and how much of
@@ -1 +1 @@
1
- {"version":3,"file":"test-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/test-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAiBxD,+GAA+G;AAC/G,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAA;AAI9I,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAE9E"}
1
+ {"version":3,"file":"test-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/test-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAmBxD,+GAA+G;AAC/G,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAA;AAI9I,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAEhF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,MAAM,CAE9E"}
@@ -3,11 +3,13 @@ import { formatInspectCommand } from "../commands.js";
3
3
  import { notRunReason } from "../failure-card.js";
4
4
  import { failureLabel, formatDuration, statusLabel, testTitle } from "../format.js";
5
5
  import { namingTargets, variantLabel } from "../targets.js";
6
+ import { comparisonView } from "./comparison-view.js";
6
7
  import { diagnosticsView } from "./diagnostics-view.js";
8
+ import { downloadsView } from "./downloads-view.js";
7
9
  import { evaluationsView } from "./evaluations-view.js";
8
10
  import { evidenceLabel, noScreenshotReason } from "./evidence-status.js";
9
11
  import { codeFrameView, failureView } from "./failure-view.js";
10
- import { html } from "./markup.js";
12
+ import { html, join } from "./markup.js";
11
13
  import { recordingsView } from "./recordings-view.js";
12
14
  import { replayView } from "./replay-view.js";
13
15
  import { screenshotsView } from "./screenshots-view.js";
@@ -54,7 +56,7 @@ function head({ test, evidence }, context) {
54
56
  }
55
57
  function body(entry, context) {
56
58
  const { test, card, evidence, events } = entry;
57
- const failing = card === undefined ? undefined : failureView(card);
59
+ const failing = card === undefined ? undefined : join([failureView(card), comparisonView(card, context.files)]);
58
60
  const reasons = evidenceReasons(entry);
59
61
  const warnings = evaluationWarnings(test).map((warning) => html `<div class="notice notice-error words">${warning}</div>`);
60
62
  const notRun = notRunNote(test, context);
@@ -62,11 +64,12 @@ function body(entry, context) {
62
64
  const pictures = screenshotsView(evidence.screenshots, { missing });
63
65
  const code = card?.location === undefined ? undefined : codeFrameView(context, card.location);
64
66
  const recordings = recordingsView(test.recordings ?? [], context.files);
67
+ const downloads = downloadsView(events, context.input.directory);
65
68
  const evaluations = evaluationsView(test.evaluations ?? [], context.files);
66
69
  const openChecks = (test.evaluations ?? []).some((record) => record.verdict !== 'pass' && record.verdict !== 'not_run');
67
70
  const diagnostics = diagnosticsView(test.diagnostics ?? [], events, context.files);
68
71
  const replay = replayView(test);
69
- return html `${failing}${notRun}${warnings}${reasons}${pictures}${code}${part('Recordings', recordings, card !== undefined)}${part('AI checks', evaluations, openChecks)}${part('Steps', timelineView(test, events), false)}${part('Console and network', diagnostics, false)}${part('Targets', targetsView(test, context), false)}${part('Replay facts', replay, false)}${commands(entry, context)}`;
72
+ return html `${failing}${notRun}${warnings}${reasons}${pictures}${code}${part('Recordings', recordings, card !== undefined)}${part('Downloads', downloads, card !== undefined)}${part('AI checks', evaluations, openChecks)}${part('Steps', timelineView(test, events), false)}${part('Console and network', diagnostics, false)}${part('Targets', targetsView(test, context), false)}${part('Replay facts', replay, false)}${commands(entry, context)}`;
70
73
  }
71
74
  function part(title, content, open) {
72
75
  if (content === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"timeline-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/timeline-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAqCzC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAoBnF"}
1
+ {"version":3,"file":"timeline-view.d.ts","sourceRoot":"","sources":["../../../src/reporters/html/timeline-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE9D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAyCzC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAqBnF"}
@@ -5,7 +5,9 @@ import { describeLocator } from "../../protocol/locator.js";
5
5
  import { secretPlaceholder } from "../../protocol/secret.js";
6
6
  import { describeLeaseParts } from "../../runner/resources.js";
7
7
  import { actionNotes, describeWrittenAction } from "../actions.js";
8
- import { describeCleanup, describeLeaseExpired, describeLocks, describePage, describePreparation, describeResources, describeSessions, describeSessionsReleased, describeStateEvent, failureLabel, formatDuration, plural, printable, statusLabel, } from "../format.js";
8
+ import { describeDialog, describePopupClosed, describePopupOpened } from "../dialogs-popups.js";
9
+ import { describeRouteChange } from "../routes.js";
10
+ import { describeCleanup, describeDownload, describeInboxRead, describeLeaseExpired, describeLocks, describePage, describePreparation, describeResources, describeSessions, describeSessionsReleased, describeStateEvent, failureLabel, formatDuration, plural, printable, statusLabel, } from "../format.js";
9
11
  import { describeHostCheck, hostCheckPage } from "../host-checks.js";
10
12
  import { html } from "./markup.js";
11
13
  const marks = { passed: '✓', failed: '✗', warning: '!' };
@@ -23,7 +25,8 @@ export function timelineView(test, events) {
23
25
  if (events.length === 0)
24
26
  return html `<p class="gap">No steps are shown: the run folder holds no events for this test.</p>`;
25
27
  const start = events[0]?.elapsedMs ?? 0;
26
- const named = test.variant !== undefined;
28
+ // A popup's steps are the popup's own, so a test that was given one names the app of every row, as a variant does.
29
+ const named = test.variant !== undefined || events.some((event) => event.type === 'popup.opened');
27
30
  const stepNames = new Map();
28
31
  let depth = 0;
29
32
  const rows = [];
@@ -70,7 +73,12 @@ function isPageEvent(event) {
70
73
  case 'recording.finished':
71
74
  case 'capture.withheld':
72
75
  case 'capture.resumed':
76
+ case 'dialog':
77
+ case 'popup.opened':
78
+ case 'popup.closed':
73
79
  case 'capture.masked_entry':
80
+ case 'download':
81
+ case 'route':
74
82
  return true;
75
83
  default:
76
84
  return false;
@@ -133,6 +141,22 @@ function describe(entry, stepNames) {
133
141
  return { what: `screenshot not saved: ${event.message}`, mark: 'warning' };
134
142
  case 'evaluation.finished':
135
143
  return describeEvaluationEvent(event);
144
+ case 'inbox.read':
145
+ return event.failure === undefined ? { what: describeInboxRead(event), took: event.waitedMs } : { what: describeInboxRead(event), mark: 'failed', took: event.waitedMs, failure: failureLabel(event.failure.class) };
146
+ case 'dialog':
147
+ return event.by === 'test' ? { what: describeDialog(event) } : { what: describeDialog(event), mark: 'warning' };
148
+ case 'popup.opened':
149
+ return { what: describePopupOpened(event) };
150
+ case 'popup.closed':
151
+ return { what: describePopupClosed(event) };
152
+ case 'download': {
153
+ const what = describeDownload(event);
154
+ if (event.state === 'completed')
155
+ return { what, ...(event.path === undefined ? {} : { details: [`file ${event.path}`] }) };
156
+ return event.failure === undefined ? { what, mark: 'warning' } : { what, mark: 'failed', failure: failureLabel(event.failure.class) };
157
+ }
158
+ case 'route':
159
+ return event.failure === undefined ? { what: describeRouteChange(event) } : { what: describeRouteChange(event), mark: 'failed', failure: failureLabel(event.failure.class) };
136
160
  case 'recording.started':
137
161
  return { what: `recording ${event.number} started: ${event.source}, ${event.mode}, ${event.width}×${event.height} at ${event.fps} fps` };
138
162
  case 'recording.finished': {
@@ -29,7 +29,7 @@ export function renderCard(card, options) {
29
29
  function heading(card, style) {
30
30
  const after = card.test === undefined ? describeFileProblem(card.fileProblem) : formatDuration(card.test.durationMs);
31
31
  const variant = card.variant === undefined ? '' : ` ${style.cyan(card.variant)}`;
32
- return ` ${style.red('✗')} ${style.bold(card.title)}${variant} ${style.dim(after)}`;
32
+ return ` ${style.red(style.marks.failed)} ${style.bold(card.title)}${variant} ${style.dim(after)}`;
33
33
  }
34
34
  // The failure first, then each other host check that failed, then the host checks that never ran.
35
35
  function summary(card, style) {
@@ -135,6 +135,8 @@ function closing(card, options) {
135
135
  const lines = card.screenshots.map((path) => field('Screenshot', path));
136
136
  for (const problem of card.evidenceProblems)
137
137
  lines.push(field('Screenshot', `not saved: ${problem}`));
138
+ for (const { name, path } of card.attachments ?? [])
139
+ lines.push(field(attachmentLabel(name), path));
138
140
  for (const { label, value } of card.diagnostics ?? [])
139
141
  lines.push(field(label, value));
140
142
  for (const failure of card.cleanupFailures) {
@@ -146,6 +148,14 @@ function closing(card, options) {
146
148
  lines.push(field('Inspect', inspect));
147
149
  return lines;
148
150
  }
151
+ // A screenshot comparison's pictures are named as a reader looks for them: what was expected, what came, and where.
152
+ function attachmentLabel(name) {
153
+ if (name === 'expected')
154
+ return 'Expected';
155
+ if (name === 'actual')
156
+ return 'Actual';
157
+ return name === 'diff' ? 'Difference' : name;
158
+ }
149
159
  // Labels may carry colour codes, so the padding counts only the visible characters.
150
160
  function field(label, value) {
151
161
  const gap = ' '.repeat(Math.max(2, labelWidth - visibleLength(label)));
@@ -1,10 +1,12 @@
1
1
  import type { ChildOutput } from '../runner/contract.ts';
2
2
  import type { Reporter } from './reporter.ts';
3
- import { type Writer } from './style.ts';
3
+ import { type Marks, type Writer } from './style.ts';
4
4
  export type HumanReporterOptions = {
5
5
  stdout: Writer;
6
6
  stderr: Writer;
7
7
  color: boolean;
8
+ /** The marks the terminal draws for a pass and a failure; the glyphs when absent. */
9
+ marks?: Marks;
8
10
  /** The run folder as the person gave it, used in printed paths and commands. */
9
11
  runFolder: string;
10
12
  };
@@ -1 +1 @@
1
- {"version":3,"file":"human.d.ts","sourceRoot":"","sources":["../../src/reporters/human.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAqC7C,OAAO,EAA0C,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAYhF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,mFAAmF;AACnF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAA;AAE9E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA0GhF"}
1
+ {"version":3,"file":"human.d.ts","sourceRoot":"","sources":["../../src/reporters/human.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAsC7C,OAAO,EAA8B,KAAK,KAAK,EAAc,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAY5F,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,qFAAqF;IACrF,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,mFAAmF;AACnF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAA;AAE9E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CA0GhF"}
@@ -3,7 +3,7 @@ import { countEvaluations } from "../evaluation/report.js";
3
3
  import { variantKey } from "../protocol/variant.js";
4
4
  import { createChildEcho } from "./child-output.js";
5
5
  import { describeFileProblem, failureCards, fileProblemOf, notRunReason, runFailureToShow, testsNotRun, } from "./failure-card.js";
6
- import { countParts, describeAppEvent, describeBorrowedSetup, describeHolders, describeLeaseExpired, describeLocks, describeNarrowed, describeResources, describeSessions, describeStateEvent, failureLabel, formatDetail, formatDuration, messageLines, plural, runNotes, testTitle, titleWithin, } from "./format.js";
6
+ import { countParts, describeAppEvent, describeBaselinesWritten, describeBorrowedSetup, describeHolders, describeLeaseExpired, describeLocks, describeNarrowed, describeResources, describeSessions, describeStateEvent, failureLabel, formatDetail, formatDuration, messageLines, plural, runNotes, testTitle, titleWithin, } from "./format.js";
7
7
  import { countHostChecks } from "./host-checks.js";
8
8
  import { renderCard } from "./human-card.js";
9
9
  import { RunRecord } from "./run-record.js";
@@ -16,7 +16,7 @@ import { acrossTargets, describeBrowser, describeProxy, runTargets, targetSummar
16
16
  * @example runFiles(options, [createHumanReporter({ stdout, stderr, color: true, runFolder })])
17
17
  */
18
18
  export function createHumanReporter(options) {
19
- const style = createStyle(options.color);
19
+ const style = createStyle(options.color, options.marks);
20
20
  const record = new RunRecord();
21
21
  const echo = createChildEcho({ stdout: options.stdout, stderr: options.stderr, style });
22
22
  const write = (text) => {
@@ -61,7 +61,7 @@ export function createHumanReporter(options) {
61
61
  return;
62
62
  case 'app.failed':
63
63
  head();
64
- write(` ${style.red('✗')} ${event.app} ${style.dim(describeAppEvent(event))}\n`);
64
+ write(` ${style.red(style.marks.failed)} ${event.app} ${style.dim(describeAppEvent(event))}\n`);
65
65
  return;
66
66
  case 'collection.completed':
67
67
  head();
@@ -69,11 +69,11 @@ export function createHumanReporter(options) {
69
69
  return;
70
70
  case 'collection.failed':
71
71
  head();
72
- write(`\n ${style.red('✗')} ${style.bold(event.file)} ${style.dim(describeFileProblem('collection'))}\n`);
72
+ write(`\n ${style.red(style.marks.failed)} ${style.bold(event.file)} ${style.dim(describeFileProblem('collection'))}\n`);
73
73
  return;
74
74
  case 'file.failed':
75
75
  head();
76
- write(` ${style.red('✗')} ${style.bold(event.file)} ${style.dim(describeFileProblem('process'))}\n`);
76
+ write(` ${style.red(style.marks.failed)} ${style.bold(event.file)} ${style.dim(describeFileProblem('process'))}\n`);
77
77
  return;
78
78
  case 'test.finished': {
79
79
  head();
@@ -142,8 +142,8 @@ function browserLine(browser) {
142
142
  function testLines(event, test, context) {
143
143
  const { style } = context;
144
144
  const marks = {
145
- passed: style.green('✓'),
146
- failed: style.red('✗'),
145
+ passed: style.green(style.marks.passed),
146
+ failed: style.red(style.marks.failed),
147
147
  error: style.yellow('!'),
148
148
  not_run: style.dim('-'),
149
149
  inconclusive: style.yellow('?'),
@@ -228,6 +228,8 @@ function summaryLines(result, context) {
228
228
  rows.push(['Files', files.join(' · ')]);
229
229
  if (result.evidenceStatus !== undefined)
230
230
  rows.push(['Evidence', describeEvidence(result.evidenceStatus)]);
231
+ if (result.baselinesWritten !== undefined)
232
+ rows.push(['Baselines', describeBaselinesWritten(result.baselinesWritten)]);
231
233
  rows.push(['Time', formatDuration(result.durationMs)], ['Output', context.runFolder]);
232
234
  const notes = runNotes(result);
233
235
  const exit = `${result.exitCode}${notes.length === 0 ? '' : ` · ${notes.join(', ')}`}`;
@@ -266,12 +268,12 @@ function targetLines(summaries, style) {
266
268
  function targetMark(summary, style) {
267
269
  const { counts } = summary;
268
270
  if (counts.failed > 0)
269
- return style.red('✗');
271
+ return style.red(style.marks.failed);
270
272
  if (counts.error > 0 || counts.notRun > 0)
271
273
  return style.yellow('!');
272
274
  if (counts.inconclusive > 0)
273
275
  return style.yellow('?');
274
- return style.green('✓');
276
+ return style.green(style.marks.passed);
275
277
  }
276
278
  function fileProblemCounts(result) {
277
279
  const problems = result.files.map(fileProblemOf);
@@ -0,0 +1,9 @@
1
+ import type { EventOfType } from './run-record.ts';
2
+ /**
3
+ * A change to an app's routes as reports name it: the call as the test wrote it, with what an added route answers, or
4
+ * how many routes a removal took away; or a request a route could not answer because Chrome refused its answer.
5
+ *
6
+ * @example describeRouteChange({ operation: 'add', pattern: '/tasks/i', answer: { status: 200, bodyBytes: 2 } }) // 'page.route(/tasks/i) answers 200, 2 bytes'
7
+ */
8
+ export declare function describeRouteChange(event: Pick<EventOfType<'route'>, 'operation' | 'pattern' | 'answer' | 'removed' | 'url'>): string;
9
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/reporters/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAIlD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC,GAAG,MAAM,CAMrI"}
@@ -0,0 +1,17 @@
1
+ import { describeRouteSummary } from "../protocol/routes.js";
2
+ import { plural, printable } from "./format.js";
3
+ /**
4
+ * A change to an app's routes as reports name it: the call as the test wrote it, with what an added route answers, or
5
+ * how many routes a removal took away; or a request a route could not answer because Chrome refused its answer.
6
+ *
7
+ * @example describeRouteChange({ operation: 'add', pattern: '/tasks/i', answer: { status: 200, bodyBytes: 2 } }) // 'page.route(/tasks/i) answers 200, 2 bytes'
8
+ */
9
+ export function describeRouteChange(event) {
10
+ const pattern = printable(event.pattern);
11
+ if (event.operation === 'remove')
12
+ return `page.unroute(${pattern})${event.removed === undefined ? '' : ` removed ${plural(event.removed, 'route')}`}`;
13
+ if (event.operation === 'answer')
14
+ return `page.route(${pattern}) could not answer ${printable(event.url ?? 'a request')}, which Retest failed`;
15
+ const answer = event.answer === undefined ? '' : ` ${'abort' in event.answer ? '' : 'answers '}${describeRouteSummary(event.answer)}`;
16
+ return `page.route(${pattern})${answer}`;
17
+ }