@crvouga/atlas 0.4.0 → 0.6.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 (444) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +191 -611
  3. package/dist/bun/src/driver.d.ts +41 -7
  4. package/dist/bun/src/driver.js +47 -6
  5. package/dist/bun/src/index.d.ts +8 -0
  6. package/dist/bun/src/index.js +8 -0
  7. package/dist/core/src/cli.d.ts +14 -1
  8. package/dist/core/src/cli.js +35 -1
  9. package/dist/core/src/config.d.ts +77 -4
  10. package/dist/core/src/config.js +110 -17
  11. package/dist/core/src/events/cloudevents.d.ts +54 -9
  12. package/dist/core/src/events/cloudevents.js +60 -9
  13. package/dist/core/src/graph.d.ts +21 -0
  14. package/dist/core/src/graph.js +26 -0
  15. package/dist/core/src/index.d.ts +11 -0
  16. package/dist/core/src/index.js +11 -0
  17. package/dist/core/src/lint.d.ts +30 -0
  18. package/dist/core/src/lint.js +13 -0
  19. package/dist/core/src/plan.d.ts +39 -1
  20. package/dist/core/src/plan.js +28 -1
  21. package/dist/core/src/privacy.d.ts +29 -2
  22. package/dist/core/src/privacy.js +19 -2
  23. package/dist/core/src/report/formats.d.ts +34 -4
  24. package/dist/core/src/report/formats.js +24 -4
  25. package/dist/core/src/report/markdown.d.ts +15 -0
  26. package/dist/core/src/report/markdown.js +8 -0
  27. package/dist/core/src/run/clients.d.ts +44 -5
  28. package/dist/core/src/run/clients.js +46 -2
  29. package/dist/core/src/run/execute.d.ts +75 -16
  30. package/dist/core/src/run/execute.js +71 -18
  31. package/dist/core/src/run/frames.d.ts +13 -4
  32. package/dist/core/src/run/frames.js +19 -4
  33. package/dist/core/src/run/http.d.ts +34 -1
  34. package/dist/core/src/run/http.js +14 -1
  35. package/dist/core/src/run/types.d.ts +76 -3
  36. package/dist/core/src/run/types.js +19 -3
  37. package/dist/core/src/signals.d.ts +49 -5
  38. package/dist/core/src/signals.js +22 -5
  39. package/dist/core/src/spec/compose.d.ts +23 -1
  40. package/dist/core/src/spec/compose.js +10 -1
  41. package/dist/core/src/spec/index.d.ts +9 -1
  42. package/dist/core/src/spec/index.js +9 -1
  43. package/dist/core/src/spec/load.d.ts +22 -1
  44. package/dist/core/src/spec/load.js +31 -1
  45. package/dist/core/src/spec/parse.d.ts +16 -2
  46. package/dist/core/src/spec/parse.js +25 -2
  47. package/dist/core/src/spec/scxml.d.ts +25 -4
  48. package/dist/core/src/spec/scxml.js +36 -4
  49. package/dist/core/src/spec/types.d.ts +52 -1
  50. package/dist/core/src/spec/types.js +24 -0
  51. package/dist/detox/src/index.d.ts +54 -11
  52. package/dist/detox/src/index.js +45 -7
  53. package/dist/playwright/src/driver.d.ts +39 -3
  54. package/dist/playwright/src/driver.js +27 -3
  55. package/dist/playwright/src/index.d.ts +10 -0
  56. package/dist/playwright/src/index.js +10 -0
  57. package/dist/playwright/src/media.d.ts +50 -4
  58. package/dist/playwright/src/media.js +55 -4
  59. package/dist/playwright/src/signals.d.ts +44 -5
  60. package/dist/playwright/src/signals.js +29 -5
  61. package/dist/reports/src/attachment-files.d.ts +44 -0
  62. package/dist/reports/src/attachment-files.js +121 -0
  63. package/dist/reports/src/attachment-response.d.ts +31 -0
  64. package/dist/reports/src/attachment-response.js +55 -0
  65. package/dist/reports/src/aws-credentials.d.ts +48 -0
  66. package/dist/reports/src/aws-credentials.js +221 -0
  67. package/dist/reports/src/browser-navigation.d.ts +14 -0
  68. package/dist/reports/src/browser-navigation.js +7 -0
  69. package/dist/reports/src/bundle.d.ts +34 -2
  70. package/dist/reports/src/bundle.js +38 -2
  71. package/dist/reports/src/catalog.d.ts +34 -3
  72. package/dist/reports/src/catalog.js +17 -3
  73. package/dist/reports/src/cli-stores.d.ts +36 -0
  74. package/dist/reports/src/cli-stores.js +73 -0
  75. package/dist/reports/src/clock.d.ts +7 -2
  76. package/dist/reports/src/clock.js +5 -2
  77. package/dist/reports/src/completion-order.d.ts +18 -5
  78. package/dist/reports/src/completion-order.js +18 -5
  79. package/dist/reports/src/compose.d.ts +80 -0
  80. package/dist/reports/src/compose.js +117 -0
  81. package/dist/reports/src/copy-store.d.ts +29 -0
  82. package/dist/reports/src/copy-store.js +52 -0
  83. package/dist/reports/src/directory-outline.d.ts +38 -0
  84. package/dist/reports/src/directory-outline.js +103 -0
  85. package/dist/reports/src/directory-store.d.ts +20 -0
  86. package/dist/reports/src/directory-store.js +166 -0
  87. package/dist/reports/src/doctor.d.ts +29 -0
  88. package/dist/reports/src/doctor.js +85 -0
  89. package/dist/reports/src/effective-delta.d.ts +34 -0
  90. package/dist/reports/src/effective-delta.js +25 -0
  91. package/dist/reports/src/evidence-detail.d.ts +64 -0
  92. package/dist/reports/src/evidence-detail.js +92 -0
  93. package/dist/reports/src/evidence-live.d.ts +35 -5
  94. package/dist/reports/src/evidence-live.js +18 -2
  95. package/dist/reports/src/evidence-types.d.ts +68 -1
  96. package/dist/reports/src/evidence-types.js +5 -1
  97. package/dist/reports/src/evidence-view.d.ts +43 -4
  98. package/dist/reports/src/evidence-view.js +13 -2
  99. package/dist/reports/src/explorer-types.d.ts +40 -3
  100. package/dist/reports/src/explorer-types.js +8 -0
  101. package/dist/reports/src/explorer-versions.d.ts +9 -1
  102. package/dist/reports/src/explorer-versions.js +18 -1
  103. package/dist/reports/src/export-evidence.d.ts +16 -1
  104. package/dist/reports/src/export-evidence.js +52 -1
  105. package/dist/reports/src/fetcher.d.ts +27 -3
  106. package/dist/reports/src/fetcher.js +11 -3
  107. package/dist/reports/src/format-date.d.ts +6 -0
  108. package/dist/reports/src/format-date.js +6 -0
  109. package/dist/reports/src/format.d.ts +16 -0
  110. package/dist/reports/src/format.js +10 -0
  111. package/dist/reports/src/frames.d.ts +36 -3
  112. package/dist/reports/src/frames.js +22 -3
  113. package/dist/reports/src/hash.d.ts +18 -0
  114. package/dist/reports/src/hash.js +13 -0
  115. package/dist/reports/src/host.d.ts +29 -0
  116. package/dist/reports/src/host.js +64 -0
  117. package/dist/reports/src/html-frame.d.ts +5 -6
  118. package/dist/reports/src/html-frame.js +12 -1
  119. package/dist/reports/src/http-store.d.ts +56 -0
  120. package/dist/reports/src/http-store.js +148 -0
  121. package/dist/reports/src/http.d.ts +7 -0
  122. package/dist/reports/src/http.js +6 -0
  123. package/dist/reports/src/ingest.d.ts +54 -0
  124. package/dist/reports/src/ingest.js +210 -0
  125. package/dist/reports/src/init.d.ts +40 -0
  126. package/dist/reports/src/init.js +369 -0
  127. package/dist/reports/src/junit.d.ts +33 -6
  128. package/dist/reports/src/junit.js +87 -21
  129. package/dist/reports/src/keyboard.d.ts +20 -0
  130. package/dist/reports/src/keyboard.js +11 -0
  131. package/dist/reports/src/keys.d.ts +21 -3
  132. package/dist/reports/src/keys.js +21 -3
  133. package/dist/reports/src/layer-axes.d.ts +35 -5
  134. package/dist/reports/src/layer-axes.js +25 -5
  135. package/dist/reports/src/layer-catalog.d.ts +28 -1
  136. package/dist/reports/src/layer-catalog.js +18 -1
  137. package/dist/reports/src/layer-merge.d.ts +98 -9
  138. package/dist/reports/src/layer-merge.js +147 -31
  139. package/dist/reports/src/layer-source.d.ts +18 -0
  140. package/dist/reports/src/layer-source.js +11 -0
  141. package/dist/reports/src/layer-store.d.ts +42 -0
  142. package/dist/reports/src/layer-store.js +63 -5
  143. package/dist/reports/src/layer-types.d.ts +32 -1
  144. package/dist/reports/src/layers-route.d.ts +47 -4
  145. package/dist/reports/src/layers-route.js +86 -7
  146. package/dist/reports/src/live-reporter.d.ts +34 -0
  147. package/dist/reports/src/live-reporter.js +122 -0
  148. package/dist/reports/src/media-types.d.ts +11 -0
  149. package/dist/reports/src/media-types.js +22 -0
  150. package/dist/reports/src/namespace-guard.d.ts +10 -1
  151. package/dist/reports/src/namespace-guard.js +10 -1
  152. package/dist/reports/src/navigation.d.ts +12 -0
  153. package/dist/reports/src/navigation.js +7 -0
  154. package/dist/reports/src/object-io.d.ts +11 -4
  155. package/dist/reports/src/object-io.js +4 -4
  156. package/dist/reports/src/object-store-conformance.d.ts +27 -0
  157. package/dist/reports/src/object-store-conformance.js +87 -0
  158. package/dist/reports/src/object-store.d.ts +33 -24
  159. package/dist/reports/src/object-store.js +17 -24
  160. package/dist/reports/src/parse-with.d.ts +16 -0
  161. package/dist/reports/src/parse-with.js +14 -0
  162. package/dist/reports/src/performance-part.d.ts +25 -1
  163. package/dist/reports/src/performance-part.js +15 -1
  164. package/dist/reports/src/performance.d.ts +22 -2
  165. package/dist/reports/src/performance.js +12 -2
  166. package/dist/reports/src/persist.d.ts +12 -3
  167. package/dist/reports/src/persist.js +12 -3
  168. package/dist/reports/src/phone.d.ts +18 -1
  169. package/dist/reports/src/phone.js +18 -1
  170. package/dist/reports/src/protocol.d.ts +26 -4
  171. package/dist/reports/src/protocol.js +15 -4
  172. package/dist/reports/src/publication.d.ts +21 -1
  173. package/dist/reports/src/publication.js +21 -1
  174. package/dist/reports/src/publish-checks.d.ts +35 -0
  175. package/dist/reports/src/publish-checks.js +122 -0
  176. package/dist/reports/src/publish.d.ts +42 -9
  177. package/dist/reports/src/publish.js +36 -7
  178. package/dist/reports/src/read.d.ts +46 -16
  179. package/dist/reports/src/read.js +38 -14
  180. package/dist/reports/src/recording-bundle.d.ts +13 -2
  181. package/dist/reports/src/recording-bundle.js +4 -2
  182. package/dist/reports/src/recording-keys.d.ts +15 -1
  183. package/dist/reports/src/recording-keys.js +15 -1
  184. package/dist/reports/src/remote-report.d.ts +28 -7
  185. package/dist/reports/src/remote-report.js +15 -7
  186. package/dist/reports/src/report-cli.d.ts +51 -0
  187. package/dist/reports/src/report-cli.js +486 -0
  188. package/dist/reports/src/report-index.d.ts +99 -0
  189. package/dist/reports/src/report-index.js +337 -0
  190. package/dist/reports/src/report-loader.d.ts +10 -0
  191. package/dist/reports/src/report-loader.js +6 -0
  192. package/dist/reports/src/report-parts.d.ts +29 -3
  193. package/dist/reports/src/report-parts.js +37 -3
  194. package/dist/reports/src/report-status.d.ts +48 -0
  195. package/dist/reports/src/report-status.js +156 -0
  196. package/dist/reports/src/report-types.d.ts +73 -0
  197. package/dist/reports/src/report-types.js +3 -0
  198. package/dist/reports/src/reporter.d.ts +67 -0
  199. package/dist/reports/src/reporter.js +128 -0
  200. package/dist/reports/src/reports-explorer-route.d.ts +541 -0
  201. package/dist/reports/src/reports-explorer-route.js +11 -0
  202. package/dist/reports/src/reports-list-route.d.ts +9 -0
  203. package/dist/reports/src/reports-list-route.js +9 -0
  204. package/dist/reports/src/reports-route.d.ts +561 -22
  205. package/dist/reports/src/reports-route.js +11 -3
  206. package/dist/reports/src/reports-store.d.ts +19 -2
  207. package/dist/reports/src/reports-store.js +10 -2
  208. package/dist/reports/src/resilient-cache.d.ts +14 -1
  209. package/dist/reports/src/resilient-cache.js +8 -1
  210. package/dist/reports/src/retention.d.ts +17 -1
  211. package/dist/reports/src/retention.js +5 -1
  212. package/dist/reports/src/run-bundle.d.ts +63 -0
  213. package/dist/reports/src/run-bundle.js +159 -0
  214. package/dist/reports/src/s3-store.d.ts +79 -0
  215. package/dist/reports/src/s3-store.js +295 -0
  216. package/dist/reports/src/scenario.d.ts +14 -4
  217. package/dist/reports/src/scenario.js +5 -4
  218. package/dist/reports/src/sigv4.d.ts +72 -0
  219. package/dist/reports/src/sigv4.js +96 -0
  220. package/dist/reports/src/snapshot-bundle.d.ts +24 -1
  221. package/dist/reports/src/snapshot-bundle.js +27 -2
  222. package/dist/reports/src/snapshot-surface.d.ts +20 -9
  223. package/dist/reports/src/snapshot-surface.js +32 -19
  224. package/dist/reports/src/source-content.d.ts +23 -0
  225. package/dist/reports/src/source-content.js +30 -1
  226. package/dist/reports/src/source-entries.d.ts +13 -0
  227. package/dist/reports/src/source-entries.js +6 -0
  228. package/dist/reports/src/source-part.d.ts +15 -0
  229. package/dist/reports/src/source-part.js +8 -0
  230. package/dist/reports/src/source-reader.d.ts +11 -0
  231. package/dist/reports/src/source-reader.js +5 -0
  232. package/dist/reports/src/spec-evidence.d.ts +12 -2
  233. package/dist/reports/src/spec-evidence.js +6 -2
  234. package/dist/reports/src/spec-inventory.d.ts +15 -1
  235. package/dist/reports/src/spec-inventory.js +22 -1
  236. package/dist/reports/src/spec-link.d.ts +28 -0
  237. package/dist/reports/src/spec-link.js +70 -0
  238. package/dist/reports/src/spec-set.d.ts +63 -0
  239. package/dist/reports/src/spec-set.js +177 -0
  240. package/dist/reports/src/status.d.ts +10 -0
  241. package/dist/reports/src/status.js +5 -0
  242. package/dist/reports/src/store-prefix.d.ts +28 -0
  243. package/dist/reports/src/store-prefix.js +22 -0
  244. package/dist/reports/src/store-url.d.ts +89 -0
  245. package/dist/reports/src/store-url.js +160 -0
  246. package/dist/reports/src/test-catalog-entity.d.ts +11 -0
  247. package/dist/reports/src/test-catalog-entity.js +6 -0
  248. package/dist/reports/src/types.d.ts +6 -1
  249. package/dist/reports/src/use-report-nav.d.ts +35 -0
  250. package/dist/reports/src/use-report-nav.js +12 -0
  251. package/dist/runners/src/codecept.d.ts +14 -0
  252. package/dist/runners/src/codecept.js +16 -0
  253. package/dist/runners/src/jest.d.ts +50 -0
  254. package/dist/runners/src/jest.js +52 -0
  255. package/dist/runners/src/mocha.d.ts +40 -0
  256. package/dist/runners/src/mocha.js +39 -0
  257. package/dist/runners/src/node-test.d.ts +28 -0
  258. package/dist/runners/src/node-test.js +44 -0
  259. package/dist/runners/src/publish.d.ts +30 -0
  260. package/dist/runners/src/publish.js +68 -0
  261. package/dist/schema/src/api.d.ts +800 -0
  262. package/dist/schema/src/api.js +201 -0
  263. package/dist/schema/src/cli-results.d.ts +210 -0
  264. package/dist/schema/src/cli-results.js +124 -0
  265. package/dist/schema/src/common.d.ts +53 -0
  266. package/dist/schema/src/common.js +42 -0
  267. package/dist/schema/src/index.d.ts +16 -0
  268. package/dist/schema/src/index.js +16 -0
  269. package/dist/schema/src/layer.d.ts +2273 -0
  270. package/dist/schema/src/layer.js +462 -0
  271. package/dist/schema/src/live-run.d.ts +123 -0
  272. package/dist/schema/src/live-run.js +30 -0
  273. package/dist/schema/src/manifest.d.ts +97 -2
  274. package/dist/schema/src/manifest.js +84 -0
  275. package/dist/schema/src/project.d.ts +20 -0
  276. package/dist/schema/src/project.js +10 -0
  277. package/dist/schema/src/report-sources.d.ts +29 -0
  278. package/dist/schema/src/report-sources.js +27 -1
  279. package/dist/schema/src/runs-index.d.ts +17 -1
  280. package/dist/schema/src/runs-index.js +15 -0
  281. package/dist/schema/src/server-config.d.ts +177 -0
  282. package/dist/schema/src/server-config.js +85 -0
  283. package/dist/schema/src/spec.d.ts +69 -0
  284. package/dist/schema/src/spec.js +58 -0
  285. package/dist/server/src/app.d.ts +72 -0
  286. package/dist/server/src/app.js +557 -0
  287. package/dist/server/src/auth.d.ts +41 -0
  288. package/dist/server/src/auth.js +59 -0
  289. package/dist/server/src/config.d.ts +83 -0
  290. package/dist/server/src/config.js +204 -0
  291. package/dist/server/src/dev.d.ts +12 -0
  292. package/dist/server/src/dev.js +89 -0
  293. package/dist/server/src/events.d.ts +29 -0
  294. package/dist/server/src/events.js +101 -0
  295. package/dist/server/src/host.d.ts +30 -0
  296. package/dist/server/src/host.js +115 -0
  297. package/dist/server/src/index.d.ts +18 -0
  298. package/dist/server/src/index.js +18 -0
  299. package/dist/server/src/live-runs.d.ts +52 -0
  300. package/dist/server/src/live-runs.js +229 -0
  301. package/dist/server/src/llms.d.ts +19 -0
  302. package/dist/server/src/llms.js +63 -0
  303. package/dist/server/src/main.d.ts +30 -0
  304. package/dist/server/src/main.js +114 -0
  305. package/dist/server/src/openapi.d.ts +56 -0
  306. package/dist/server/src/openapi.js +438 -0
  307. package/dist/server/src/problem.d.ts +8 -0
  308. package/dist/server/src/problem.js +39 -0
  309. package/dist/server/src/projects.d.ts +3 -0
  310. package/dist/server/src/projects.js +154 -0
  311. package/dist/server/src/settings-page.d.ts +9 -0
  312. package/dist/server/src/settings-page.js +93 -0
  313. package/dist/server/src/settings.d.ts +23 -0
  314. package/dist/server/src/settings.js +72 -0
  315. package/dist/server/src/site.d.ts +15 -0
  316. package/dist/server/src/site.js +78 -0
  317. package/dist/server/src/store-api.d.ts +28 -0
  318. package/dist/server/src/store-api.js +180 -0
  319. package/dist/server/src/validate.d.ts +71 -0
  320. package/dist/server/src/validate.js +197 -0
  321. package/dist/vitest/src/index.d.ts +27 -5
  322. package/dist/vitest/src/index.js +18 -5
  323. package/dist/webdriver/src/driver.d.ts +63 -11
  324. package/dist/webdriver/src/driver.js +57 -6
  325. package/dist/webdriver/src/index.d.ts +8 -0
  326. package/dist/webdriver/src/index.js +1 -0
  327. package/dist/webdriver/src/protocol.d.ts +75 -6
  328. package/dist/webdriver/src/protocol.js +79 -6
  329. package/docs/agents.md +137 -0
  330. package/docs/deploying.md +345 -0
  331. package/docs/dogfooding.md +175 -0
  332. package/docs/extending.md +242 -0
  333. package/docs/integrating.md +485 -0
  334. package/docs/reference/bun.md +141 -0
  335. package/docs/reference/cli.md +148 -0
  336. package/docs/reference/core.md +2432 -0
  337. package/docs/reference/detox.md +150 -0
  338. package/docs/reference/http-api.md +799 -0
  339. package/docs/reference/playwright.md +303 -0
  340. package/docs/reference/reports.md +7152 -0
  341. package/docs/reference/runners.md +169 -0
  342. package/docs/reference/schema.md +1762 -0
  343. package/docs/reference/server.md +825 -0
  344. package/docs/reference/vitest.md +45 -0
  345. package/docs/reference/webdriver.md +330 -0
  346. package/docs/report-backends.md +144 -0
  347. package/docs/report-contract.md +400 -0
  348. package/docs/reporting-issues.md +160 -0
  349. package/docs/runners.md +69 -0
  350. package/docs/server.md +321 -0
  351. package/docs/statecharts.md +643 -0
  352. package/llms-full.txt +4114 -0
  353. package/llms.txt +49 -0
  354. package/package.json +61 -11
  355. package/packages/core/README.md +2 -1
  356. package/packages/reports/README.md +65 -0
  357. package/packages/reports/STORAGE.md +4 -0
  358. package/packages/runners/README.md +6 -0
  359. package/packages/runners/compat/codecept.cjs +2 -0
  360. package/packages/runners/compat/jest.cjs +2 -0
  361. package/packages/runners/compat/mocha.cjs +2 -0
  362. package/packages/schema/README.md +14 -0
  363. package/packages/schema/schemas/atlas-change.schema.json +4 -0
  364. package/packages/schema/schemas/check-detail.schema.json +1032 -0
  365. package/packages/schema/schemas/checks-result.schema.json +26 -0
  366. package/packages/schema/schemas/command-error.schema.json +35 -0
  367. package/packages/schema/schemas/doctor-result.schema.json +60 -0
  368. package/packages/schema/schemas/effective-delta.schema.json +490 -0
  369. package/packages/schema/schemas/effective-evidence.schema.json +471 -0
  370. package/packages/schema/schemas/evidence-page.schema.json +271 -0
  371. package/packages/schema/schemas/hello-event.schema.json +26 -0
  372. package/packages/schema/schemas/init-plan.schema.json +347 -0
  373. package/packages/schema/schemas/layer-rows.schema.json +199 -0
  374. package/packages/schema/schemas/layer.schema.json +2888 -0
  375. package/packages/schema/schemas/live-run-start.schema.json +42 -0
  376. package/packages/schema/schemas/live-run-update.schema.json +93 -0
  377. package/packages/schema/schemas/live-run.schema.json +225 -0
  378. package/packages/schema/schemas/merge-result.schema.json +40 -0
  379. package/packages/schema/schemas/outline.schema.json +62 -0
  380. package/packages/schema/schemas/problem.schema.json +37 -0
  381. package/packages/schema/schemas/project-slug.schema.json +8 -0
  382. package/packages/schema/schemas/project.schema.json +22 -0
  383. package/packages/schema/schemas/projects.schema.json +33 -0
  384. package/packages/schema/schemas/publish-checks.schema.json +1413 -0
  385. package/packages/schema/schemas/publish-result.schema.json +168 -0
  386. package/packages/schema/schemas/ready.schema.json +68 -0
  387. package/packages/schema/schemas/report-event.schema.json +100 -0
  388. package/packages/schema/schemas/report-status.schema.json +370 -0
  389. package/packages/schema/schemas/server-config.schema.json +208 -0
  390. package/packages/schema/schemas/server-editable-settings.schema.json +132 -0
  391. package/packages/schema/schemas/server-info.schema.json +114 -0
  392. package/packages/schema/schemas/server-settings-snapshot.schema.json +285 -0
  393. package/packages/schema/schemas/spec-set.schema.json +103 -0
  394. package/packages/schema/schemas/store-listing.schema.json +29 -0
  395. package/packages/schema/schemas/store-write-result.schema.json +28 -0
  396. package/packages/schema/schemas/stream-result.schema.json +59 -0
  397. package/packages/server/README.md +43 -0
  398. package/packages/server/openapi.json +11021 -0
  399. package/packages/visualizer/README.md +32 -11
  400. package/packages/visualizer/bin/atlas-client.mjs +176 -0
  401. package/packages/visualizer/bin/atlas-visualizer.mjs +2 -175
  402. package/packages/visualizer/src/app/AppShell.tsx +32 -16
  403. package/packages/visualizer/src/app/report-sources.tsx +7 -4
  404. package/packages/visualizer/src/app/router.tsx +3 -3
  405. package/packages/visualizer/src/components/ActivityIndicator.module.css +4 -0
  406. package/packages/visualizer/src/components/ActivityIndicator.tsx +6 -0
  407. package/packages/visualizer/src/components/Header.module.css +101 -192
  408. package/packages/visualizer/src/components/Header.tsx +88 -13
  409. package/packages/visualizer/src/components/ProjectPicker.tsx +64 -0
  410. package/packages/visualizer/src/data/adapters/adapter.ts +5 -17
  411. package/packages/visualizer/src/data/adapters/index.ts +10 -1
  412. package/packages/visualizer/src/data/adapters/report-backend.test.ts +3 -2
  413. package/packages/visualizer/src/data/adapters/report-backend.ts +1 -1
  414. package/packages/visualizer/src/data/queries.ts +14 -7
  415. package/packages/visualizer/src/evidence/api.ts +16 -3
  416. package/packages/visualizer/src/evidence/artifacts.module.css +213 -0
  417. package/packages/visualizer/src/evidence/artifacts.tsx +272 -0
  418. package/packages/visualizer/src/evidence/check-detail.tsx +21 -4
  419. package/packages/visualizer/src/evidence/document-page.tsx +6 -2
  420. package/packages/visualizer/src/evidence/evidence-context.tsx +79 -12
  421. package/packages/visualizer/src/evidence/evidence.module.css +11 -1
  422. package/packages/visualizer/src/evidence/feature-page.tsx +7 -3
  423. package/packages/visualizer/src/evidence/model-page.tsx +6 -2
  424. package/packages/visualizer/src/evidence/project-home.tsx +45 -0
  425. package/packages/visualizer/src/evidence/recording-page.tsx +4 -1
  426. package/packages/visualizer/src/evidence/spec-index.tsx +2 -1
  427. package/packages/visualizer/src/evidence/spec-page.tsx +23 -16
  428. package/packages/visualizer/src/evidence/test-filter.tsx +21 -0
  429. package/packages/visualizer/src/find/Finder.tsx +1 -7
  430. package/packages/visualizer/src/find/open.ts +4 -0
  431. package/packages/visualizer/src/live/live-query.ts +21 -0
  432. package/packages/visualizer/src/live/live-runs.tsx +69 -0
  433. package/packages/visualizer/src/live/live-stream.ts +225 -0
  434. package/packages/visualizer/src/live/report-progress.ts +62 -0
  435. package/packages/visualizer/src/live/test-progress.tsx +34 -0
  436. package/packages/visualizer/src/runtime.ts +35 -0
  437. package/packages/visualizer/src/state/ui-store.ts +3 -2
  438. package/packages/visualizer/src/views/ChartPage.tsx +2 -0
  439. package/packages/visualizer/src/views/ChartTests.tsx +43 -0
  440. package/packages/visualizer/src/views/SidePanel.tsx +2 -0
  441. package/packages/visualizer/vite/atlas-files.test.ts +4 -4
  442. package/packages/visualizer/vite/atlas-files.ts +1 -5
  443. package/packages/visualizer/vite/atlas-server-proxy.ts +37 -0
  444. package/packages/visualizer/vite.config.ts +11 -3
@@ -5,6 +5,12 @@ function packageOf(testId) {
5
5
  const name = cut < 0 ? source : source.slice(0, cut);
6
6
  return name.length > 0 ? name : 'report';
7
7
  }
8
+ /**
9
+ * Flattens a recorded test into a `CatalogEntity`: its id, title, status and duration; the base name of its source
10
+ * file; the package (the part of the viewer test id's source before `--`, or `report`); its runtime; and the first
11
+ * line of its error as the detail. `search` joins the title, ids, paths, system, runtime, package and error for text
12
+ * matching. `href` is `null`; the caller sets where a row links to.
13
+ */
8
14
  export function testCatalogEntity(test) {
9
15
  const meta = test.report.meta;
10
16
  const file = fileLabel(meta.sourceFile);
@@ -1,5 +1,10 @@
1
+ /**
2
+ * @module Report viewer data
3
+ *
4
+ * The data shape the standalone and Solid report viewers render: a recorded run plus its title.
5
+ */
1
6
  import type { HtmlReportBundle } from './recording-bundle.js';
2
- /** Bundle plus document title for the standalone / Solid report viewer. */
7
+ /** A run's tests (`HtmlReportBundle`) plus the document title shown for them, for the standalone / Solid report viewer. */
3
8
  export type ReportData = HtmlReportBundle & {
4
9
  readonly title: string;
5
10
  };
@@ -1,25 +1,60 @@
1
+ /**
2
+ * @module Report viewer navigation state
3
+ *
4
+ * The Solid state behind the report viewer's navigation: the current route (kept in the URL hash), help and command
5
+ * palette visibility, frame stepping and auto-play, keyboard shortcuts and the document title. Everything outside the
6
+ * reactive state (the location, the keyboard, timers) is injected, so it runs the same in a browser and in tests. It
7
+ * creates signals and effects, so it must be called inside a Solid root, which also owns its cleanup.
8
+ */
1
9
  import type { Timers } from './clock.js';
2
10
  import type { FlatFrame } from './frames.js';
3
11
  import type { Route } from './hash.js';
4
12
  import type { ReportData } from './types.js';
5
13
  import type { Accessor } from 'solid-js';
6
14
  import type { ReportNavigation } from './navigation.js';
15
+ /** What the viewer's views read and call to move around a report. */
7
16
  export type ReportNav = {
17
+ /** The current route: the list, or one test with its params. Updates at once, before the URL is written. */
8
18
  route: Accessor<Route>;
19
+ /** Whether the keyboard help is open. */
9
20
  showHelp: Accessor<boolean>;
21
+ /** Whether the command palette is open. */
10
22
  showPalette: Accessor<boolean>;
23
+ /** Whether frames are advancing on a timer. */
11
24
  playing: Accessor<boolean>;
25
+ /** Goes to `route`. A normal navigation adds a history entry and writes the URL now; with `replace` true it updates the route at once and writes the URL, replacing the entry, 200 ms after the last such call. */
12
26
  navigate: (route: Route, replace?: boolean) => void;
13
27
  /** Write the in-memory route to the URL now (end of a scrub drag). */
14
28
  commitHash: () => void;
29
+ /** Sets one param of the current test route (replacing history); does nothing on the list route. */
15
30
  setParam: (key: string, value: string) => void;
31
+ /** Selects a frame of the current test (its 1-based position goes into the `frame` param), or clears the selection with `null`; `node` also sets the `node` param. Does nothing on the list route. */
16
32
  goFrame: (frame: FlatFrame | null, node?: string | undefined) => void;
33
+ /** Moves the selected frame by `delta` (negative goes back); does nothing at either end or off a test route. */
17
34
  stepFrame: (delta: number) => void;
35
+ /** Opens the help if closed, else closes it. */
18
36
  toggleHelp: () => void;
37
+ /** Closes the help. */
19
38
  closeHelp: () => void;
39
+ /** Opens the palette if closed, else closes it. */
20
40
  togglePalette: () => void;
41
+ /** Closes the palette. */
21
42
  closePalette: () => void;
43
+ /** Starts advancing one frame every 700 ms, or stops if playing. Stops by itself at the last frame, or when the route stops being a test. */
22
44
  togglePlay: () => void;
45
+ /** Stops playback. */
23
46
  stopPlay: () => void;
24
47
  };
48
+ /**
49
+ * Creates the navigation state for a report: the route from the URL hash (and kept in sync when it changes), help and
50
+ * palette state, playback, keyboard shortcuts and the page title (`<test title> · <report title>`).
51
+ *
52
+ * Reading the hash is the only way in: an unrecognised hash is the list route, and `parseHash` throws `URIError` on a
53
+ * malformed percent-escape. Subscriptions and timers are released when the surrounding Solid root is disposed. Must be
54
+ * called inside a Solid root.
55
+ *
56
+ * @param data the report whose tests the routes name.
57
+ * @param navigation where the hash, keys and title live (the browser, or a fake).
58
+ * @param timers timer functions for the hash-write debounce and playback.
59
+ */
25
60
  export declare function useReportNav(data: ReportData, navigation: ReportNavigation, timers: Timers): ReportNav;
@@ -94,6 +94,18 @@ function createHashRoute(navigation, timers) {
94
94
  onCleanup(cancelHashWrite);
95
95
  return { route, setRoute, commitHash, navigate, cancelHashWrite };
96
96
  }
97
+ /**
98
+ * Creates the navigation state for a report: the route from the URL hash (and kept in sync when it changes), help and
99
+ * palette state, playback, keyboard shortcuts and the page title (`<test title> · <report title>`).
100
+ *
101
+ * Reading the hash is the only way in: an unrecognised hash is the list route, and `parseHash` throws `URIError` on a
102
+ * malformed percent-escape. Subscriptions and timers are released when the surrounding Solid root is disposed. Must be
103
+ * called inside a Solid root.
104
+ *
105
+ * @param data the report whose tests the routes name.
106
+ * @param navigation where the hash, keys and title live (the browser, or a fake).
107
+ * @param timers timer functions for the hash-write debounce and playback.
108
+ */
97
109
  export function useReportNav(data, navigation, timers) {
98
110
  const { route, setRoute, commitHash, navigate, cancelHashWrite } = createHashRoute(navigation, timers);
99
111
  const [showHelp, setShowHelp] = createSignal(false);
@@ -0,0 +1,14 @@
1
+ /** @module CodeceptJS reporter
2
+ * CodeceptJS's Mocha reporter interface carries scenario outcomes and steps to the singleton Atlas server.
3
+ */
4
+ import AtlasMochaReporter from './mocha.js';
5
+ /**
6
+ * Use `codeceptjs run --reporter @crvouga/atlas/codecept` with ATLAS_SERVER_URL and ATLAS_PUBLISH_TOKEN.
7
+ * Upload failures fail the run; skipped scenarios remain not-run.
8
+ * @example
9
+ * // codecept.conf.js
10
+ * export const config = { tests: './tests/*_test.js', reporter: '@crvouga/atlas/codecept' };
11
+ */
12
+ export default class AtlasCodeceptReporter extends AtlasMochaReporter {
13
+ constructor(...args: [ConstructorParameters<typeof AtlasMochaReporter>[0], ConstructorParameters<typeof AtlasMochaReporter>[1]?]);
14
+ }
@@ -0,0 +1,16 @@
1
+ /** @module CodeceptJS reporter
2
+ * CodeceptJS's Mocha reporter interface carries scenario outcomes and steps to the singleton Atlas server.
3
+ */
4
+ import AtlasMochaReporter from './mocha.js';
5
+ /**
6
+ * Use `codeceptjs run --reporter @crvouga/atlas/codecept` with ATLAS_SERVER_URL and ATLAS_PUBLISH_TOKEN.
7
+ * Upload failures fail the run; skipped scenarios remain not-run.
8
+ * @example
9
+ * // codecept.conf.js
10
+ * export const config = { tests: './tests/*_test.js', reporter: '@crvouga/atlas/codecept' };
11
+ */
12
+ export default class AtlasCodeceptReporter extends AtlasMochaReporter {
13
+ constructor(...args) {
14
+ super(args[0], args[1], 'codeceptjs');
15
+ }
16
+ }
@@ -0,0 +1,50 @@
1
+ import { type ReporterOptions } from './publish.js';
2
+ type Result = {
3
+ testFilePath: string;
4
+ testExecError?: {
5
+ message?: string;
6
+ stack?: string;
7
+ };
8
+ failureMessage?: string;
9
+ testResults: {
10
+ title: string;
11
+ fullName: string;
12
+ status: string;
13
+ duration?: number | null;
14
+ failureMessages: string[];
15
+ invocations?: number;
16
+ }[];
17
+ };
18
+ /**
19
+ * Jest's native reporter; retain `default` in the reporter list for console output. Upload errors fail Jest.
20
+ * @example
21
+ * export default { reporters: ['default', ['@crvouga/atlas/jest', { url: 'https://atlas.example.com' }]] };
22
+ */
23
+ export default class AtlasJestReporter {
24
+ private readonly options;
25
+ private live;
26
+ private error;
27
+ constructor(_config: unknown, options?: ReporterOptions);
28
+ /** Reset publishing errors for each watch-mode invocation. */
29
+ onRunStart(result?: {
30
+ numTotalTests?: number;
31
+ }): void;
32
+ /** Publish the test as running before its body executes in a worker. */
33
+ onTestCaseStart(test: {
34
+ path: string;
35
+ }, info: {
36
+ fullName: string;
37
+ title: string;
38
+ }): void;
39
+ /** Stream each test outcome immediately, without waiting for other files to finish. */
40
+ onTestCaseResult(test: {
41
+ path: string;
42
+ }, result: Result['testResults'][number]): void;
43
+ /** Await uploading every final result, including test-file failures before any test ran. */
44
+ onRunComplete(_contexts: unknown, result: {
45
+ testResults: Result[];
46
+ }): Promise<void>;
47
+ /** Jest uses this to turn a publishing error into a failed invocation. */
48
+ getLastError(): Error | undefined;
49
+ }
50
+ export {};
@@ -0,0 +1,52 @@
1
+ import { testFile, runnerLive, finishRunner } from './publish.js';
2
+ /**
3
+ * Jest's native reporter; retain `default` in the reporter list for console output. Upload errors fail Jest.
4
+ * @example
5
+ * export default { reporters: ['default', ['@crvouga/atlas/jest', { url: 'https://atlas.example.com' }]] };
6
+ */
7
+ export default class AtlasJestReporter {
8
+ options;
9
+ live;
10
+ error;
11
+ constructor(_config, options = {}) {
12
+ this.options = options;
13
+ }
14
+ /** Reset publishing errors for each watch-mode invocation. */
15
+ onRunStart(result) { this.error = undefined; this.live = runnerLive('jest', this.options, result?.numTotalTests || undefined); }
16
+ /** Publish the test as running before its body executes in a worker. */
17
+ onTestCaseStart(test, info) {
18
+ this.live ??= runnerLive('jest', this.options);
19
+ this.live.check({ id: `${testFile(test.path, this.options.rootDir)} > ${info.fullName}`, title: info.title, status: 'running' });
20
+ }
21
+ /** Stream each test outcome immediately, without waiting for other files to finish. */
22
+ onTestCaseResult(test, result) {
23
+ this.live ??= runnerLive('jest', this.options);
24
+ this.live.check({ id: `${testFile(test.path, this.options.rootDir)} > ${result.fullName}`, title: result.title,
25
+ status: result.status === 'passed' ? 'passed' : result.status === 'failed' ? 'failed' : 'not-run', detail: result.failureMessages.join('\n') });
26
+ }
27
+ /** Await uploading every final result, including test-file failures before any test ran. */
28
+ async onRunComplete(_contexts, result) {
29
+ const checks = [];
30
+ for (const suite of result.testResults) {
31
+ const file = testFile(suite.testFilePath, this.options.rootDir);
32
+ for (const test of suite.testResults)
33
+ checks.push({ id: `${file} > ${test.fullName}`, title: test.title,
34
+ status: test.status === 'passed' ? 'passed' : test.status === 'failed' ? 'failed' : 'not-run',
35
+ detail: test.failureMessages.join('\n'), measurements: [],
36
+ ...(typeof test.duration === 'number' && Number.isFinite(test.duration) && test.duration >= 0 ? { durationMs: test.duration } : {}),
37
+ ...((test.invocations ?? 1) > 1 ? { labels: { retries: String(test.invocations - 1), ...(test.status === 'passed' ? { flaky: 'true' } : {}) } } : {}) });
38
+ if (suite.testExecError)
39
+ checks.push({ id: `${file} > [suite error]`, title: `${file}: suite error`, status: 'failed', detail: suite.testExecError.stack ?? suite.testExecError.message ?? suite.failureMessage ?? 'Suite did not execute', measurements: [] });
40
+ }
41
+ this.live ??= runnerLive('jest', this.options);
42
+ checks.forEach(check => this.live.check(check));
43
+ try {
44
+ await finishRunner(this.live, 'jest', checks, this.options);
45
+ }
46
+ catch (error) {
47
+ this.error = error instanceof Error ? error : new Error(String(error));
48
+ }
49
+ }
50
+ /** Jest uses this to turn a publishing error into a failed invocation. */
51
+ getLastError() { return this.error; }
52
+ }
@@ -0,0 +1,40 @@
1
+ import { type ReporterOptions } from './publish.js';
2
+ type Test = {
3
+ title: string;
4
+ file?: string;
5
+ duration?: number;
6
+ fullTitle(): string;
7
+ err?: {
8
+ stack?: string;
9
+ message?: string;
10
+ };
11
+ steps?: {
12
+ name?: string;
13
+ status?: string;
14
+ }[];
15
+ currentRetry?(): number;
16
+ };
17
+ type Runner = {
18
+ total?: number;
19
+ on(event: string, listener: (test: Test, error?: Error) => void): unknown;
20
+ };
21
+ /**
22
+ * Mocha reporter; use `--reporter @crvouga/atlas/mocha` or CodeceptJS `--reporter @crvouga/atlas/codecept`.
23
+ * Reporter options go in `reporterOptions`; environment variables are supported by every runner.
24
+ * A failed upload adds a runner failure through Mocha's completion callback.
25
+ * @example
26
+ * // mocha configuration
27
+ * export default { reporter: '@crvouga/atlas/mocha', reporterOptions: { url: 'https://atlas.example.com' } };
28
+ */
29
+ export default class AtlasMochaReporter {
30
+ private readonly checks;
31
+ private readonly options;
32
+ private readonly runnerName;
33
+ private readonly live;
34
+ constructor(runner: Runner, options?: {
35
+ reporterOptions?: ReporterOptions;
36
+ }, runnerName?: string);
37
+ /** Mocha waits for this callback before exiting. Publishing errors fail the invocation. */
38
+ done(failures: number, callback: (failures: number) => void): void;
39
+ }
40
+ export {};
@@ -0,0 +1,39 @@
1
+ import { testFile, runnerLive, finishRunner } from './publish.js';
2
+ /**
3
+ * Mocha reporter; use `--reporter @crvouga/atlas/mocha` or CodeceptJS `--reporter @crvouga/atlas/codecept`.
4
+ * Reporter options go in `reporterOptions`; environment variables are supported by every runner.
5
+ * A failed upload adds a runner failure through Mocha's completion callback.
6
+ * @example
7
+ * // mocha configuration
8
+ * export default { reporter: '@crvouga/atlas/mocha', reporterOptions: { url: 'https://atlas.example.com' } };
9
+ */
10
+ export default class AtlasMochaReporter {
11
+ checks = new Map();
12
+ options;
13
+ runnerName;
14
+ live;
15
+ constructor(runner, options = {}, runnerName = 'mocha') {
16
+ this.options = options.reporterOptions ?? {};
17
+ this.runnerName = runnerName;
18
+ this.live = runnerLive(runnerName, this.options, runner.total);
19
+ const add = (test, status, error) => {
20
+ const file = testFile(test.file, this.options.rootDir);
21
+ const retry = test.currentRetry?.() ?? 0;
22
+ this.checks.set(test, { id: [file, test.fullTitle()].filter(Boolean).join(' > '), title: test.title, status,
23
+ detail: error?.stack ?? error?.message ?? (status === 'failed' ? test.err?.stack ?? test.err?.message ?? 'failed' : ''), measurements: [],
24
+ ...(typeof test.duration === 'number' && Number.isFinite(test.duration) && test.duration >= 0 ? { durationMs: test.duration } : {}),
25
+ ...(retry ? { labels: { retries: String(retry), ...(status === 'passed' ? { flaky: 'true' } : {}) } } : {}),
26
+ ...(test.steps?.length ? { steps: test.steps.map(step => ({ name: step.name ?? 'step', ...(step.status ? { status: step.status } : {}) })) } : {}) });
27
+ const check = this.checks.get(test);
28
+ this.live.check({ ...check, steps: check.steps?.map(step => ({ name: step.name, status: step.status })) });
29
+ };
30
+ runner.on('test', test => add(test, 'running'));
31
+ runner.on('pass', test => add(test, 'passed'));
32
+ runner.on('fail', (test, error) => add(test, 'failed', error));
33
+ runner.on('pending', test => add(test, 'not-run'));
34
+ }
35
+ /** Mocha waits for this callback before exiting. Publishing errors fail the invocation. */
36
+ done(failures, callback) {
37
+ void finishRunner(this.live, this.runnerName, [...this.checks.values()], this.options).then(() => callback(failures), error => { console.error(error instanceof Error ? error.message : String(error)); callback(failures + 1); });
38
+ }
39
+ }
@@ -0,0 +1,28 @@
1
+ type Event = {
2
+ type: string;
3
+ data: {
4
+ name?: string;
5
+ file?: string;
6
+ nesting?: number;
7
+ type?: string;
8
+ skip?: boolean | string;
9
+ todo?: boolean | string;
10
+ details?: {
11
+ type?: string;
12
+ duration_ms?: number;
13
+ error?: {
14
+ stack?: string;
15
+ message?: string;
16
+ failureType?: string;
17
+ };
18
+ };
19
+ };
20
+ };
21
+ /**
22
+ * Async generator reporter. Use alongside Node's spec reporter to keep normal output.
23
+ * Upload errors reject the stream; skips and TODOs never count as passed. Successful suite containers are excluded; hook failures are retained.
24
+ * @example
25
+ * // node --test --test-reporter=spec --test-reporter=@crvouga/atlas/node-test
26
+ */
27
+ export default function atlasNodeReporter(source: AsyncIterable<Event>): AsyncGenerator<string>;
28
+ export {};
@@ -0,0 +1,44 @@
1
+ import { testFile, runnerLive, finishRunner } from './publish.js';
2
+ /**
3
+ * Async generator reporter. Use alongside Node's spec reporter to keep normal output.
4
+ * Upload errors reject the stream; skips and TODOs never count as passed. Successful suite containers are excluded; hook failures are retained.
5
+ * @example
6
+ * // node --test --test-reporter=spec --test-reporter=@crvouga/atlas/node-test
7
+ */
8
+ export default async function* atlasNodeReporter(source) {
9
+ const checks = [];
10
+ const live = runnerLive('node-test');
11
+ const kinds = new Map();
12
+ try {
13
+ const parents = [];
14
+ for await (const { type, data } of source) {
15
+ const nesting = data.nesting ?? 0;
16
+ const identity = `${data.file ?? ''}|${nesting}|${data.name ?? ''}`;
17
+ if (type === 'test:enqueue' && data.type)
18
+ kinds.set(identity, data.type);
19
+ if (type === 'test:start') {
20
+ parents[nesting] = data.name ?? '';
21
+ parents.length = nesting + 1;
22
+ if (kinds.get(identity) === 'test')
23
+ live.check({ id: [testFile(data.file), ...parents.slice(0, nesting), data.name].filter(Boolean).join(' > '), title: data.name ?? 'test', status: 'running' });
24
+ }
25
+ if (type !== 'test:pass' && type !== 'test:fail')
26
+ continue;
27
+ if (data.details?.type === 'suite' && (type === 'test:pass' || data.details.error?.failureType === 'subtestsFailed'))
28
+ continue;
29
+ const file = testFile(data.file);
30
+ const status = data.skip || data.todo ? 'not-run' : type === 'test:pass' ? 'passed' : 'failed';
31
+ checks.push({ id: [file, ...parents.slice(0, nesting), data.name].filter(Boolean).join(' > '), title: data.name ?? 'test', status,
32
+ detail: data.details?.error?.stack ?? data.details?.error?.message ?? '', measurements: [],
33
+ ...(typeof data.details?.duration_ms === 'number' && Number.isFinite(data.details.duration_ms) && data.details.duration_ms >= 0 ? { durationMs: data.details.duration_ms } : {}) });
34
+ live.check(checks.at(-1));
35
+ }
36
+ checks.forEach(check => live.check(check));
37
+ await finishRunner(live, 'node-test', checks);
38
+ yield `Atlas: uploaded ${checks.length} checks\n`;
39
+ }
40
+ catch (error) {
41
+ await live.finish('interrupted', 'The test event stream ended unexpectedly.').catch(() => { });
42
+ throw error;
43
+ }
44
+ }
@@ -0,0 +1,30 @@
1
+ import type { EvidenceCheck } from '../../reports/src/explorer-types.js';
2
+ /** Reporter options; explicit values override ATLAS_SERVER_URL, ATLAS_PUBLISH_TOKEN, ATLAS_ENVIRONMENT, ATLAS_BRANCH and ATLAS_SHA. */
3
+ export type ReporterOptions = {
4
+ /** Project namespace; defaults to ATLAS_PROJECT. */
5
+ readonly project?: string;
6
+ readonly url?: string;
7
+ readonly token?: string;
8
+ readonly producer?: string;
9
+ readonly environment?: string;
10
+ readonly branch?: string;
11
+ readonly sha?: string;
12
+ readonly timeoutMs?: number;
13
+ readonly rootDir?: string;
14
+ /** Explicit final evidence time; normally generated when publication finishes. */
15
+ readonly recordedAtMs?: number;
16
+ };
17
+ /** A portable check identity: paths relative to the project, using forward slashes on every OS. */
18
+ export declare function testFile(file: string | undefined, root?: string): string;
19
+ /**
20
+ * Upload one completed runner invocation. Unknown outcomes stay not-run, repeated identities are numbered.
21
+ * Throws on missing configuration, timeouts or refused uploads so CI cannot silently lose its evidence.
22
+ * No storage credentials or backend URL are needed by the runner.
23
+ * @example
24
+ * await uploadChecks('mocha', checks, { url: 'https://atlas.example.com', token: process.env.ATLAS_PUBLISH_TOKEN });
25
+ */
26
+ export declare function uploadChecks(runner: string, checks: readonly EvidenceCheck[], options?: ReporterOptions): Promise<void>;
27
+ /** Start the native runner's live feed with the same endpoint and identity as its final report. */
28
+ export declare function runnerLive(runner: string, options?: ReporterOptions, plannedChecks?: number): import('../../reports/src/live-reporter.js').LiveReporter;
29
+ /** Flush live progress, then publish the full final evidence even if the lease was interrupted. Reject either failure. */
30
+ export declare function finishRunner(live: import('../../reports/src/live-reporter.js').LiveReporter, runner: string, checks: readonly EvidenceCheck[], options?: ReporterOptions): Promise<void>;
@@ -0,0 +1,68 @@
1
+ /** @module Publishing native runner results
2
+ * Native reporters send checks to the project's Atlas server. Only the server knows its storage backend.
3
+ */
4
+ import path from 'node:path';
5
+ import { createLiveReporter } from '../../reports/src/live-reporter.js';
6
+ import { uniqueChecks } from '../../reports/src/ingest.js';
7
+ /** A portable check identity: paths relative to the project, using forward slashes on every OS. */
8
+ export function testFile(file, root = process.cwd()) {
9
+ return file ? path.relative(root, path.resolve(root, file)).replaceAll('\\', '/') : '';
10
+ }
11
+ /**
12
+ * Upload one completed runner invocation. Unknown outcomes stay not-run, repeated identities are numbered.
13
+ * Throws on missing configuration, timeouts or refused uploads so CI cannot silently lose its evidence.
14
+ * No storage credentials or backend URL are needed by the runner.
15
+ * @example
16
+ * await uploadChecks('mocha', checks, { url: 'https://atlas.example.com', token: process.env.ATLAS_PUBLISH_TOKEN });
17
+ */
18
+ export async function uploadChecks(runner, checks, options = {}) {
19
+ const url = options.url ?? process.env.ATLAS_SERVER_URL;
20
+ if (!url)
21
+ throw new Error('Atlas reporter: set ATLAS_SERVER_URL to the project Atlas server');
22
+ const target = new URL(url);
23
+ if (!['http:', 'https:'].includes(target.protocol) || target.username || target.password || target.search || target.hash)
24
+ throw new Error('Atlas reporter: use an HTTP(S) server URL without credentials, query or fragment');
25
+ target.pathname = `${target.pathname.replace(/\/$/, '')}/api/checks`;
26
+ const token = options.token ?? process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN;
27
+ const response = await fetch(target, {
28
+ method: 'POST', redirect: 'error', signal: AbortSignal.timeout(options.timeoutMs ?? 30_000),
29
+ headers: { 'content-type': 'application/json', ...((options.project ?? process.env.ATLAS_PROJECT) ? { 'x-atlas-project': options.project ?? process.env.ATLAS_PROJECT } : {}), ...(token ? { authorization: `Bearer ${token}` } : {}) },
30
+ body: JSON.stringify({ producer: options.producer ?? runner, recordedAtMs: options.recordedAtMs ?? Date.now(),
31
+ environment: options.environment ?? process.env.ATLAS_ENVIRONMENT,
32
+ branch: options.branch ?? process.env.ATLAS_BRANCH, sha: options.sha ?? process.env.ATLAS_SHA,
33
+ checks: uniqueChecks(checks) })
34
+ });
35
+ if (!response.ok) {
36
+ await response.body?.cancel();
37
+ throw new Error(`Atlas reporter: upload refused (HTTP ${response.status})`);
38
+ }
39
+ await response.body?.cancel();
40
+ }
41
+ /** Start the native runner's live feed with the same endpoint and identity as its final report. */
42
+ export function runnerLive(runner, options = {}, plannedChecks) {
43
+ const url = options.url ?? process.env.ATLAS_SERVER_URL;
44
+ if (!url)
45
+ throw new Error('Atlas reporter: set ATLAS_SERVER_URL to the project Atlas server');
46
+ return createLiveReporter({ producer: options.producer ?? runner, plannedChecks, title: `${runner} tests`, environment: options.environment ?? process.env.ATLAS_ENVIRONMENT,
47
+ branch: options.branch ?? process.env.ATLAS_BRANCH, sha: options.sha ?? process.env.ATLAS_SHA }, { url, project: options.project ?? process.env.ATLAS_PROJECT, token: options.token ?? process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN, timeoutMs: options.timeoutMs });
48
+ }
49
+ /** Flush live progress, then publish the full final evidence even if the lease was interrupted. Reject either failure. */
50
+ export async function finishRunner(live, runner, checks, options = {}) {
51
+ let error;
52
+ const finalChecks = uniqueChecks(checks);
53
+ finalChecks.forEach(check => live.check(check));
54
+ try {
55
+ await live.finish();
56
+ }
57
+ catch (caught) {
58
+ error = caught;
59
+ }
60
+ try {
61
+ await uploadChecks(runner, finalChecks, { ...options, recordedAtMs: Math.max(Date.now(), (live.finishedAtMs ?? 0) + 1) });
62
+ }
63
+ catch (caught) {
64
+ error ??= caught;
65
+ }
66
+ if (error)
67
+ throw error;
68
+ }