@crvouga/atlas 0.0.0-stage → 0.2.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 (606) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +649 -2
  4. package/dist/bun/src/driver.d.ts +67 -0
  5. package/dist/bun/src/driver.js +90 -0
  6. package/dist/bun/src/index.d.ts +2 -0
  7. package/dist/bun/src/index.js +2 -0
  8. package/dist/core/src/cli.d.ts +1 -0
  9. package/dist/core/src/cli.js +177 -0
  10. package/dist/core/src/config.d.ts +477 -0
  11. package/dist/core/src/config.js +100 -0
  12. package/dist/core/src/events/cloudevents.d.ts +56 -0
  13. package/dist/core/src/events/cloudevents.js +152 -0
  14. package/dist/core/src/graph.d.ts +113 -0
  15. package/dist/core/src/graph.js +221 -0
  16. package/dist/core/src/index.d.ts +17 -0
  17. package/dist/core/src/index.js +17 -0
  18. package/dist/core/src/lint.d.ts +53 -0
  19. package/dist/core/src/lint.js +138 -0
  20. package/dist/core/src/plan.d.ts +109 -0
  21. package/dist/core/src/plan.js +324 -0
  22. package/dist/core/src/privacy.d.ts +8 -0
  23. package/dist/core/src/privacy.js +42 -0
  24. package/dist/core/src/report/formats.d.ts +69 -0
  25. package/dist/core/src/report/formats.js +109 -0
  26. package/dist/core/src/report/markdown.d.ts +8 -0
  27. package/dist/core/src/report/markdown.js +140 -0
  28. package/dist/core/src/run/clients.d.ts +42 -0
  29. package/dist/core/src/run/clients.js +250 -0
  30. package/dist/core/src/run/execute.d.ts +854 -0
  31. package/dist/core/src/run/execute.js +877 -0
  32. package/dist/core/src/run/frames.d.ts +16 -0
  33. package/dist/core/src/run/frames.js +52 -0
  34. package/dist/core/src/run/http.d.ts +41 -0
  35. package/dist/core/src/run/http.js +71 -0
  36. package/dist/core/src/run/types.d.ts +248 -0
  37. package/dist/core/src/run/types.js +39 -0
  38. package/dist/core/src/signals.d.ts +110 -0
  39. package/dist/core/src/signals.js +121 -0
  40. package/dist/core/src/spec/compose.d.ts +28 -0
  41. package/dist/core/src/spec/compose.js +71 -0
  42. package/dist/core/src/spec/index.d.ts +5 -0
  43. package/dist/core/src/spec/index.js +5 -0
  44. package/dist/core/src/spec/load.d.ts +8 -0
  45. package/dist/core/src/spec/load.js +46 -0
  46. package/dist/core/src/spec/parse.d.ts +5 -0
  47. package/dist/core/src/spec/parse.js +32 -0
  48. package/dist/core/src/spec/scxml.d.ts +19 -0
  49. package/dist/core/src/spec/scxml.js +239 -0
  50. package/dist/core/src/spec/types.d.ts +96 -0
  51. package/dist/core/src/spec/types.js +25 -0
  52. package/dist/detox/src/index.d.ts +75 -0
  53. package/dist/detox/src/index.js +110 -0
  54. package/dist/playwright/src/driver.d.ts +44 -0
  55. package/dist/playwright/src/driver.js +82 -0
  56. package/dist/playwright/src/index.d.ts +3 -0
  57. package/dist/playwright/src/index.js +3 -0
  58. package/dist/playwright/src/media.d.ts +68 -0
  59. package/dist/playwright/src/media.js +283 -0
  60. package/dist/playwright/src/signals.d.ts +34 -0
  61. package/dist/playwright/src/signals.js +56 -0
  62. package/dist/reports/src/browser-navigation.d.ts +2 -0
  63. package/dist/reports/src/browser-navigation.js +28 -0
  64. package/dist/reports/src/bundle.d.ts +24 -0
  65. package/dist/reports/src/bundle.js +114 -0
  66. package/dist/reports/src/catalog.d.ts +37 -0
  67. package/dist/reports/src/catalog.js +127 -0
  68. package/dist/reports/src/clock.d.ts +14 -0
  69. package/dist/reports/src/clock.js +4 -0
  70. package/dist/reports/src/completion-order.d.ts +10 -0
  71. package/dist/reports/src/completion-order.js +76 -0
  72. package/dist/reports/src/evidence-live.d.ts +40 -0
  73. package/dist/reports/src/evidence-live.js +118 -0
  74. package/dist/reports/src/evidence-types.d.ts +90 -0
  75. package/dist/reports/src/evidence-types.js +15 -0
  76. package/dist/reports/src/evidence-view.d.ts +68 -0
  77. package/dist/reports/src/evidence-view.js +113 -0
  78. package/dist/reports/src/explorer-types.d.ts +56 -0
  79. package/dist/reports/src/explorer-types.js +0 -0
  80. package/dist/reports/src/explorer-versions.d.ts +4 -0
  81. package/dist/reports/src/explorer-versions.js +21 -0
  82. package/dist/reports/src/export-evidence.d.ts +11 -0
  83. package/dist/reports/src/export-evidence.js +94 -0
  84. package/dist/reports/src/fetcher.d.ts +50 -0
  85. package/dist/reports/src/fetcher.js +205 -0
  86. package/dist/reports/src/format-date.d.ts +1 -0
  87. package/dist/reports/src/format-date.js +10 -0
  88. package/dist/reports/src/format.d.ts +16 -0
  89. package/dist/reports/src/format.js +71 -0
  90. package/dist/reports/src/frames.d.ts +46 -0
  91. package/dist/reports/src/frames.js +245 -0
  92. package/dist/reports/src/hash.d.ts +17 -0
  93. package/dist/reports/src/hash.js +43 -0
  94. package/dist/reports/src/html-frame.d.ts +13 -0
  95. package/dist/reports/src/html-frame.js +63 -0
  96. package/dist/reports/src/http.d.ts +3 -0
  97. package/dist/reports/src/http.js +0 -0
  98. package/dist/reports/src/junit.d.ts +23 -0
  99. package/dist/reports/src/junit.js +119 -0
  100. package/dist/reports/src/keyboard.d.ts +16 -0
  101. package/dist/reports/src/keyboard.js +135 -0
  102. package/dist/reports/src/keys.d.ts +53 -0
  103. package/dist/reports/src/keys.js +122 -0
  104. package/dist/reports/src/layer-catalog.d.ts +5 -0
  105. package/dist/reports/src/layer-catalog.js +39 -0
  106. package/dist/reports/src/layer-merge.d.ts +43 -0
  107. package/dist/reports/src/layer-merge.js +154 -0
  108. package/dist/reports/src/layer-source.d.ts +6 -0
  109. package/dist/reports/src/layer-source.js +32 -0
  110. package/dist/reports/src/layer-store.d.ts +10 -0
  111. package/dist/reports/src/layer-store.js +36 -0
  112. package/dist/reports/src/layer-types.d.ts +32 -0
  113. package/dist/reports/src/layer-types.js +0 -0
  114. package/dist/reports/src/layers-route.d.ts +20 -0
  115. package/dist/reports/src/layers-route.js +259 -0
  116. package/dist/reports/src/namespace-guard.d.ts +11 -0
  117. package/dist/reports/src/namespace-guard.js +40 -0
  118. package/dist/reports/src/navigation.d.ts +8 -0
  119. package/dist/reports/src/navigation.js +0 -0
  120. package/dist/reports/src/object-io.d.ts +9 -0
  121. package/dist/reports/src/object-io.js +41 -0
  122. package/dist/reports/src/object-store.d.ts +67 -0
  123. package/dist/reports/src/object-store.js +32 -0
  124. package/dist/reports/src/performance-part.d.ts +9 -0
  125. package/dist/reports/src/performance-part.js +42 -0
  126. package/dist/reports/src/performance.d.ts +13 -0
  127. package/dist/reports/src/performance.js +45 -0
  128. package/dist/reports/src/persist.d.ts +10 -0
  129. package/dist/reports/src/persist.js +38 -0
  130. package/dist/reports/src/phone.d.ts +5 -0
  131. package/dist/reports/src/phone.js +18 -0
  132. package/dist/reports/src/protocol.d.ts +78 -0
  133. package/dist/reports/src/protocol.js +36 -0
  134. package/dist/reports/src/publication.d.ts +4 -0
  135. package/dist/reports/src/publication.js +35 -0
  136. package/dist/reports/src/publish.d.ts +52 -0
  137. package/dist/reports/src/publish.js +189 -0
  138. package/dist/reports/src/read.d.ts +62 -0
  139. package/dist/reports/src/read.js +214 -0
  140. package/dist/reports/src/recording-bundle.d.ts +22 -0
  141. package/dist/reports/src/recording-bundle.js +4 -0
  142. package/dist/reports/src/recording-keys.d.ts +9 -0
  143. package/dist/reports/src/recording-keys.js +50 -0
  144. package/dist/reports/src/remote-report.d.ts +39 -0
  145. package/dist/reports/src/remote-report.js +304 -0
  146. package/dist/reports/src/report-loader.d.ts +22 -0
  147. package/dist/reports/src/report-loader.js +0 -0
  148. package/dist/reports/src/report-parts.d.ts +10 -0
  149. package/dist/reports/src/report-parts.js +112 -0
  150. package/dist/reports/src/report-types.d.ts +194 -0
  151. package/dist/reports/src/report-types.js +29 -0
  152. package/dist/reports/src/reports-explorer-route.d.ts +90 -0
  153. package/dist/reports/src/reports-explorer-route.js +65 -0
  154. package/dist/reports/src/reports-list-route.d.ts +23 -0
  155. package/dist/reports/src/reports-list-route.js +55 -0
  156. package/dist/reports/src/reports-route.d.ts +267 -0
  157. package/dist/reports/src/reports-route.js +204 -0
  158. package/dist/reports/src/reports-store.d.ts +11 -0
  159. package/dist/reports/src/reports-store.js +28 -0
  160. package/dist/reports/src/resilient-cache.d.ts +3 -0
  161. package/dist/reports/src/resilient-cache.js +33 -0
  162. package/dist/reports/src/retention.d.ts +9 -0
  163. package/dist/reports/src/retention.js +16 -0
  164. package/dist/reports/src/scenario.d.ts +15 -0
  165. package/dist/reports/src/scenario.js +35 -0
  166. package/dist/reports/src/snapshot-bundle.d.ts +18 -0
  167. package/dist/reports/src/snapshot-bundle.js +94 -0
  168. package/dist/reports/src/snapshot-surface.d.ts +29 -0
  169. package/dist/reports/src/snapshot-surface.js +339 -0
  170. package/dist/reports/src/source-content.d.ts +30 -0
  171. package/dist/reports/src/source-content.js +63 -0
  172. package/dist/reports/src/source-entries.d.ts +4 -0
  173. package/dist/reports/src/source-entries.js +34 -0
  174. package/dist/reports/src/source-part.d.ts +4 -0
  175. package/dist/reports/src/source-part.js +66 -0
  176. package/dist/reports/src/source-reader.d.ts +6 -0
  177. package/dist/reports/src/source-reader.js +17 -0
  178. package/dist/reports/src/spec-evidence.d.ts +6 -0
  179. package/dist/reports/src/spec-evidence.js +20 -0
  180. package/dist/reports/src/spec-inventory.d.ts +14 -0
  181. package/dist/reports/src/spec-inventory.js +75 -0
  182. package/dist/reports/src/status.d.ts +4 -0
  183. package/dist/reports/src/status.js +8 -0
  184. package/dist/reports/src/store-prefix.d.ts +21 -0
  185. package/dist/reports/src/store-prefix.js +53 -0
  186. package/dist/reports/src/test-catalog-entity.d.ts +3 -0
  187. package/dist/reports/src/test-catalog-entity.js +34 -0
  188. package/dist/reports/src/types.d.ts +5 -0
  189. package/dist/reports/src/types.js +0 -0
  190. package/dist/reports/src/use-report-nav.d.ts +25 -0
  191. package/dist/reports/src/use-report-nav.js +181 -0
  192. package/dist/schema/src/common.d.ts +57 -0
  193. package/dist/schema/src/common.js +32 -0
  194. package/dist/schema/src/index.d.ts +5 -0
  195. package/dist/schema/src/index.js +5 -0
  196. package/dist/schema/src/manifest.d.ts +457 -0
  197. package/dist/schema/src/manifest.js +247 -0
  198. package/dist/schema/src/report-sources.d.ts +68 -0
  199. package/dist/schema/src/report-sources.js +53 -0
  200. package/dist/schema/src/runs-index.d.ts +52 -0
  201. package/dist/schema/src/runs-index.js +24 -0
  202. package/dist/schema/src/spec.d.ts +245 -0
  203. package/dist/schema/src/spec.js +133 -0
  204. package/dist/vitest/src/index.d.ts +22 -0
  205. package/dist/vitest/src/index.js +33 -0
  206. package/dist/webdriver/src/driver.d.ts +69 -0
  207. package/dist/webdriver/src/driver.js +230 -0
  208. package/dist/webdriver/src/index.d.ts +11 -0
  209. package/dist/webdriver/src/index.js +10 -0
  210. package/dist/webdriver/src/protocol.d.ts +60 -0
  211. package/dist/webdriver/src/protocol.js +146 -0
  212. package/package.json +181 -4
  213. package/packages/bun/README.md +69 -0
  214. package/packages/core/README.md +78 -0
  215. package/packages/core/bin/atlas.mjs +8 -0
  216. package/packages/detox/README.md +73 -0
  217. package/packages/playwright/README.md +77 -0
  218. package/packages/reports/README.md +47 -0
  219. package/packages/reports/STORAGE.md +73 -0
  220. package/packages/schema/README.md +23 -0
  221. package/packages/schema/schemas/atlas-change.schema.json +34 -0
  222. package/packages/schema/schemas/atlas.schema.json +32 -0
  223. package/packages/schema/schemas/cloud-event.schema.json +40 -0
  224. package/packages/schema/schemas/journeys.schema.json +17 -0
  225. package/packages/schema/schemas/manifest.schema.json +160 -0
  226. package/packages/schema/schemas/path-record.schema.json +151 -0
  227. package/packages/schema/schemas/report-sources.schema.json +95 -0
  228. package/packages/schema/schemas/run-info.schema.json +176 -0
  229. package/packages/schema/schemas/run-summary.schema.json +206 -0
  230. package/packages/schema/schemas/runs-index.schema.json +23 -0
  231. package/packages/schema/schemas/state-node.schema.json +238 -0
  232. package/packages/schema/schemas/state-record.schema.json +354 -0
  233. package/packages/schema/schemas/timeline-entry.schema.json +124 -0
  234. package/packages/schema/schemas/transition-record.schema.json +125 -0
  235. package/packages/visualizer/README.md +154 -0
  236. package/packages/visualizer/bin/atlas-visualizer.mjs +176 -0
  237. package/packages/visualizer/example/specs/coffee/ordering/checkout.scxml +82 -0
  238. package/packages/visualizer/example/specs/coffee/ordering/journeys.yaml +129 -0
  239. package/packages/visualizer/example/specs/coffee/ordering/known-issues.md +14 -0
  240. package/packages/visualizer/example/specs/coffee/ordering/machine.yaml +158 -0
  241. package/packages/visualizer/example/specs/coffee/ordering/open-questions.md +25 -0
  242. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  243. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +245 -0
  244. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +12 -0
  245. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +2003 -0
  246. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  247. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  248. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  249. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  250. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +17 -0
  251. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +9 -0
  252. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +17 -0
  253. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +17 -0
  254. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +13 -0
  255. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
  256. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +9 -0
  257. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
  258. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
  259. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  260. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  261. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  262. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  263. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  264. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  265. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
  266. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
  267. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  268. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  269. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  270. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  271. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  272. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  273. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  274. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  275. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  276. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  277. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  278. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  279. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.png +0 -0
  280. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.webp +0 -0
  281. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
  282. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
  283. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
  284. package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
  285. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/checkout.scxml +82 -0
  286. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/journeys.yaml +129 -0
  287. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/known-issues.md +14 -0
  288. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/machine.yaml +158 -0
  289. package/packages/visualizer/fixtures/failures/specs/coffee/ordering/open-questions.md +25 -0
  290. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/chart.mmd +67 -0
  291. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/ctrf.json +247 -0
  292. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/junit.xml +12 -0
  293. package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/manifest.json +1875 -0
  294. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/chart.mmd +67 -0
  295. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/ctrf.json +244 -0
  296. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/junit.xml +12 -0
  297. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/manifest.json +1977 -0
  298. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/001.vtt +9 -0
  299. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/002.vtt +9 -0
  300. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/003.vtt +9 -0
  301. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/004.vtt +9 -0
  302. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/005.vtt +17 -0
  303. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/006.vtt +9 -0
  304. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  305. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  306. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  307. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  308. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  309. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  310. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  311. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  312. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  313. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  314. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  315. package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  316. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  317. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +472 -0
  318. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +16 -0
  319. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +3701 -0
  320. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  321. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  322. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  323. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  324. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
  325. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +13 -0
  326. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +9 -0
  327. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +13 -0
  328. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +17 -0
  329. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
  330. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +13 -0
  331. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
  332. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
  333. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/014.vtt +9 -0
  334. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/015.vtt +9 -0
  335. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/016.vtt +9 -0
  336. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/017.vtt +9 -0
  337. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/018.vtt +17 -0
  338. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/019.vtt +9 -0
  339. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/020.vtt +9 -0
  340. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/021.vtt +9 -0
  341. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/022.vtt +17 -0
  342. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/023.vtt +17 -0
  343. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/024.vtt +13 -0
  344. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/025.vtt +9 -0
  345. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/026.vtt +9 -0
  346. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/027.vtt +9 -0
  347. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/028.vtt +9 -0
  348. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  349. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  350. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  351. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  352. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  353. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  354. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
  355. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
  356. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  357. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  358. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  359. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  360. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  361. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  362. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  363. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  364. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  365. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  366. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.png +0 -0
  367. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.webp +0 -0
  368. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.png +0 -0
  369. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.webp +0 -0
  370. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.png +0 -0
  371. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.webp +0 -0
  372. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.png +0 -0
  373. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.webp +0 -0
  374. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.png +0 -0
  375. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.webp +0 -0
  376. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.png +0 -0
  377. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.webp +0 -0
  378. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.png +0 -0
  379. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.webp +0 -0
  380. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.png +0 -0
  381. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.webp +0 -0
  382. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.png +0 -0
  383. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.webp +0 -0
  384. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  385. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  386. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
  387. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
  388. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
  389. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
  390. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
  391. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
  392. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.png +0 -0
  393. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.webp +0 -0
  394. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.png +0 -0
  395. package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.webp +0 -0
  396. package/packages/visualizer/fixtures/full/specs/coffee/ordering/checkout.scxml +82 -0
  397. package/packages/visualizer/fixtures/full/specs/coffee/ordering/journeys.yaml +129 -0
  398. package/packages/visualizer/fixtures/full/specs/coffee/ordering/known-issues.md +14 -0
  399. package/packages/visualizer/fixtures/full/specs/coffee/ordering/machine.yaml +158 -0
  400. package/packages/visualizer/fixtures/full/specs/coffee/ordering/open-questions.md +25 -0
  401. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/ctrf.json +1280 -0
  402. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/junit.xml +26 -0
  403. package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/manifest.json +28393 -0
  404. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/identity-check.machine.yaml +397 -0
  405. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/journeys.yaml +129 -0
  406. package/packages/visualizer/fixtures/large/specs/accounts/sign-up/machine.yaml +830 -0
  407. package/packages/visualizer/fixtures/large/specs/atlas.yaml +65 -0
  408. package/packages/visualizer/fixtures/large/specs/billing/invoices/journeys.yaml +132 -0
  409. package/packages/visualizer/fixtures/large/specs/billing/invoices/machine.yaml +830 -0
  410. package/packages/visualizer/fixtures/large/specs/billing/invoices/refund-handling.scxml +288 -0
  411. package/packages/visualizer/fixtures/large/specs/catalog/browsing/journeys.yaml +126 -0
  412. package/packages/visualizer/fixtures/large/specs/catalog/browsing/machine.yaml +831 -0
  413. package/packages/visualizer/fixtures/large/specs/catalog/browsing/product-comparison.machine.yaml +395 -0
  414. package/packages/visualizer/fixtures/large/specs/orders/checkout/journeys.yaml +120 -0
  415. package/packages/visualizer/fixtures/large/specs/orders/checkout/machine.yaml +724 -0
  416. package/packages/visualizer/fixtures/large/specs/orders/checkout/open-questions.md +16 -0
  417. package/packages/visualizer/fixtures/large/specs/orders/checkout/payment.scxml +288 -0
  418. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/delivery-scheduling.machine.yaml +397 -0
  419. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/journeys.yaml +132 -0
  420. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/known-issues.md +13 -0
  421. package/packages/visualizer/fixtures/large/specs/shipping/deliveries/machine.yaml +830 -0
  422. package/packages/visualizer/fixtures/large/specs/support/tickets/escalation.machine.yaml +395 -0
  423. package/packages/visualizer/fixtures/large/specs/support/tickets/journeys.yaml +123 -0
  424. package/packages/visualizer/fixtures/large/specs/support/tickets/machine.yaml +720 -0
  425. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T10-00-00-000Z-showcase/manifest.json +68 -0
  426. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/ctrf.json +50 -0
  427. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/junit.xml +6 -0
  428. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/manifest.json +1281 -0
  429. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/ctrf.json +50 -0
  430. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/junit.xml +6 -0
  431. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/manifest.json +1232 -0
  432. package/packages/visualizer/fixtures/malformed/runs/2026-10-06T13-00-00-000Z-showcase/manifest.json +1244 -0
  433. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/checkout.scxml +82 -0
  434. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/journeys.yaml +134 -0
  435. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/known-issues.md +14 -0
  436. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/loyalty.scxml +4 -0
  437. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/machine.yaml +156 -0
  438. package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/open-questions.md +25 -0
  439. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
  440. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +149 -0
  441. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +9 -0
  442. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1718 -0
  443. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  444. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +17 -0
  445. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +17 -0
  446. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
  447. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
  448. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  449. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  450. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  451. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  452. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
  453. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
  454. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  455. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  456. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  457. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  458. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  459. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  460. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
  461. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
  462. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
  463. package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
  464. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.png +0 -0
  465. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.webp +0 -0
  466. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  467. package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  468. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/checkout.scxml +82 -0
  469. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/journeys.yaml +129 -0
  470. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/known-issues.md +14 -0
  471. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/machine.yaml +158 -0
  472. package/packages/visualizer/fixtures/partial/specs/coffee/ordering/open-questions.md +25 -0
  473. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +79 -0
  474. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +7 -0
  475. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1504 -0
  476. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
  477. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
  478. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
  479. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +17 -0
  480. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
  481. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
  482. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
  483. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
  484. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
  485. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
  486. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
  487. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
  488. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
  489. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
  490. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
  491. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
  492. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
  493. package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
  494. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/checkout.scxml +82 -0
  495. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/journeys.yaml +129 -0
  496. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/known-issues.md +14 -0
  497. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/machine.yaml +158 -0
  498. package/packages/visualizer/fixtures/removed/specs/coffee/ordering/open-questions.md +25 -0
  499. package/packages/visualizer/fixtures/spec-only/runs/.gitkeep +0 -0
  500. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/checkout.scxml +82 -0
  501. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/journeys.yaml +129 -0
  502. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/known-issues.md +14 -0
  503. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/machine.yaml +158 -0
  504. package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/open-questions.md +25 -0
  505. package/packages/visualizer/index.html +13 -0
  506. package/packages/visualizer/scripts/make-fixtures.ts +1490 -0
  507. package/packages/visualizer/scripts/publish-data.ts +22 -0
  508. package/packages/visualizer/src/app/AppShell.tsx +56 -0
  509. package/packages/visualizer/src/app/atlas-context.tsx +23 -0
  510. package/packages/visualizer/src/app/gazetteer.module.css +97 -0
  511. package/packages/visualizer/src/app/gazetteer.tsx +105 -0
  512. package/packages/visualizer/src/app/report-sources.tsx +122 -0
  513. package/packages/visualizer/src/app/router.tsx +69 -0
  514. package/packages/visualizer/src/app/search-query.tsx +14 -0
  515. package/packages/visualizer/src/components/DataIssues.module.css +136 -0
  516. package/packages/visualizer/src/components/DataIssues.tsx +70 -0
  517. package/packages/visualizer/src/components/Header.module.css +189 -0
  518. package/packages/visualizer/src/components/Header.tsx +127 -0
  519. package/packages/visualizer/src/components/Legend.module.css +84 -0
  520. package/packages/visualizer/src/components/Legend.tsx +50 -0
  521. package/packages/visualizer/src/components/Screen.module.css +312 -0
  522. package/packages/visualizer/src/components/Screen.tsx +141 -0
  523. package/packages/visualizer/src/components/Status.module.css +116 -0
  524. package/packages/visualizer/src/components/Status.tsx +60 -0
  525. package/packages/visualizer/src/components/icons.tsx +156 -0
  526. package/packages/visualizer/src/components/labels.tsx +22 -0
  527. package/packages/visualizer/src/data/adapters/adapter.ts +112 -0
  528. package/packages/visualizer/src/data/adapters/context.tsx +11 -0
  529. package/packages/visualizer/src/data/adapters/index.ts +29 -0
  530. package/packages/visualizer/src/data/adapters/report-backend.test.ts +96 -0
  531. package/packages/visualizer/src/data/adapters/report-backend.ts +42 -0
  532. package/packages/visualizer/src/data/fixtures.test.ts +407 -0
  533. package/packages/visualizer/src/data/model/build.ts +418 -0
  534. package/packages/visualizer/src/data/model/event-kind.test.ts +59 -0
  535. package/packages/visualizer/src/data/model/event-kind.ts +54 -0
  536. package/packages/visualizer/src/data/model/index.ts +3 -0
  537. package/packages/visualizer/src/data/model/journeys.test.ts +159 -0
  538. package/packages/visualizer/src/data/model/journeys.ts +29 -0
  539. package/packages/visualizer/src/data/model/simulation.test.ts +115 -0
  540. package/packages/visualizer/src/data/model/simulation.ts +187 -0
  541. package/packages/visualizer/src/data/model/status.test.ts +34 -0
  542. package/packages/visualizer/src/data/model/status.ts +43 -0
  543. package/packages/visualizer/src/data/model/types.ts +280 -0
  544. package/packages/visualizer/src/data/parse/issues.test.ts +82 -0
  545. package/packages/visualizer/src/data/parse/issues.ts +114 -0
  546. package/packages/visualizer/src/data/parse/manifest.ts +173 -0
  547. package/packages/visualizer/src/data/parse/markdown.test.ts +119 -0
  548. package/packages/visualizer/src/data/parse/markdown.ts +133 -0
  549. package/packages/visualizer/src/data/parse/spec.test.ts +106 -0
  550. package/packages/visualizer/src/data/parse/spec.ts +557 -0
  551. package/packages/visualizer/src/data/parse/structured.ts +44 -0
  552. package/packages/visualizer/src/data/queries.ts +369 -0
  553. package/packages/visualizer/src/data/testing/load-fixture.ts +63 -0
  554. package/packages/visualizer/src/evidence/api.ts +41 -0
  555. package/packages/visualizer/src/evidence/check-detail.tsx +257 -0
  556. package/packages/visualizer/src/evidence/decision-table.tsx +68 -0
  557. package/packages/visualizer/src/evidence/document-page.tsx +40 -0
  558. package/packages/visualizer/src/evidence/evidence-context.tsx +159 -0
  559. package/packages/visualizer/src/evidence/evidence.module.css +877 -0
  560. package/packages/visualizer/src/evidence/feature-page.tsx +88 -0
  561. package/packages/visualizer/src/evidence/format.ts +56 -0
  562. package/packages/visualizer/src/evidence/gherkin.ts +98 -0
  563. package/packages/visualizer/src/evidence/marks.tsx +118 -0
  564. package/packages/visualizer/src/evidence/model-page.tsx +60 -0
  565. package/packages/visualizer/src/evidence/model-trace.tsx +57 -0
  566. package/packages/visualizer/src/evidence/overview.tsx +134 -0
  567. package/packages/visualizer/src/evidence/quint.ts +45 -0
  568. package/packages/visualizer/src/evidence/recording-page.tsx +69 -0
  569. package/packages/visualizer/src/evidence/recording.module.css +464 -0
  570. package/packages/visualizer/src/evidence/recording.tsx +197 -0
  571. package/packages/visualizer/src/evidence/snapshot.tsx +108 -0
  572. package/packages/visualizer/src/evidence/sources-panel.tsx +134 -0
  573. package/packages/visualizer/src/evidence/sources.module.css +168 -0
  574. package/packages/visualizer/src/evidence/spec-header.tsx +64 -0
  575. package/packages/visualizer/src/evidence/spec-index.tsx +82 -0
  576. package/packages/visualizer/src/evidence/spec-page.tsx +92 -0
  577. package/packages/visualizer/src/evidence/spec-snapshot.tsx +26 -0
  578. package/packages/visualizer/src/layout/graph.test.ts +113 -0
  579. package/packages/visualizer/src/layout/graph.ts +324 -0
  580. package/packages/visualizer/src/layout/layout.ts +237 -0
  581. package/packages/visualizer/src/layout/use-chart-layout.ts +18 -0
  582. package/packages/visualizer/src/main.tsx +31 -0
  583. package/packages/visualizer/src/map/ChartMap.tsx +252 -0
  584. package/packages/visualizer/src/map/EventEdge.tsx +138 -0
  585. package/packages/visualizer/src/map/map.module.css +546 -0
  586. package/packages/visualizer/src/map/nodes.tsx +145 -0
  587. package/packages/visualizer/src/map/path.ts +24 -0
  588. package/packages/visualizer/src/reachable.test.ts +54 -0
  589. package/packages/visualizer/src/spec-kind.test.ts +27 -0
  590. package/packages/visualizer/src/spec-kind.ts +56 -0
  591. package/packages/visualizer/src/state/ui-store.ts +44 -0
  592. package/packages/visualizer/src/styles/global.css +105 -0
  593. package/packages/visualizer/src/styles/tokens.css +80 -0
  594. package/packages/visualizer/src/views/ChartPage.tsx +52 -0
  595. package/packages/visualizer/src/views/ProductPage.tsx +35 -0
  596. package/packages/visualizer/src/views/SidePanel.tsx +339 -0
  597. package/packages/visualizer/src/views/views.module.css +546 -0
  598. package/packages/visualizer/vite/atlas-dev-plugin.ts +169 -0
  599. package/packages/visualizer/vite/atlas-files.test.ts +119 -0
  600. package/packages/visualizer/vite/atlas-files.ts +199 -0
  601. package/packages/visualizer/vite/publish.test.ts +52 -0
  602. package/packages/visualizer/vite/publish.ts +99 -0
  603. package/packages/visualizer/vite/reports-dev-plugin.ts +82 -0
  604. package/packages/visualizer/vite.config.ts +13 -0
  605. package/packages/vitest/README.md +58 -0
  606. package/packages/webdriver/README.md +77 -0
@@ -0,0 +1,3701 @@
1
+ {
2
+ "$schema": "https://github.com/crvouga/atlas/schemas/manifest.schema.json",
3
+ "schemaVersion": 1,
4
+ "run": {
5
+ "id": "2026-10-06T14-40-00-000Z-showcase",
6
+ "startedAt": "2026-10-06T14:40:00.000Z",
7
+ "finishedAt": "2026-10-06T14:51:24.600Z",
8
+ "durationMs": 684600,
9
+ "commit": "571dc134d087dde25bfff6177c4fdafe794c3a4a",
10
+ "branch": "main",
11
+ "environment": {
12
+ "driver": "playwright",
13
+ "baseUrl": "http://localhost:3000",
14
+ "viewport": {
15
+ "width": 390,
16
+ "height": 844
17
+ },
18
+ "deviceScaleFactor": 3
19
+ },
20
+ "mode": "showcase",
21
+ "specVersion": "f7ef440c67ed",
22
+ "specDirectory": "specs",
23
+ "approvals": [],
24
+ "scope": {
25
+ "start": "A customer on the menu"
26
+ }
27
+ },
28
+ "charts": [
29
+ {
30
+ "id": "Coffee order",
31
+ "file": "coffee/ordering/machine.yaml",
32
+ "description": "A customer picks a drink, pays for it, and picks it up when it is ready.",
33
+ "parentState": null,
34
+ "handOffs": {}
35
+ },
36
+ {
37
+ "id": "Checkout",
38
+ "file": "coffee/ordering/checkout.scxml",
39
+ "description": "Paying for the order, by card or with a wallet.",
40
+ "parentState": "Checking out",
41
+ "handOffs": {
42
+ "Paid": "Payment goes through",
43
+ "Checkout abandoned": "Leaves checkout"
44
+ }
45
+ }
46
+ ],
47
+ "map": {
48
+ "nodes": [
49
+ {
50
+ "id": "Browsing the menu",
51
+ "parent": null,
52
+ "chart": "Coffee order",
53
+ "type": "atomic",
54
+ "initial": null,
55
+ "inScope": true
56
+ },
57
+ {
58
+ "id": "Customizing the drink",
59
+ "parent": null,
60
+ "chart": "Coffee order",
61
+ "type": "compound",
62
+ "initial": "Choosing a size",
63
+ "inScope": true
64
+ },
65
+ {
66
+ "id": "Choosing a size",
67
+ "parent": "Customizing the drink",
68
+ "chart": "Coffee order",
69
+ "type": "atomic",
70
+ "initial": null,
71
+ "inScope": true
72
+ },
73
+ {
74
+ "id": "Choosing the milk",
75
+ "parent": "Customizing the drink",
76
+ "chart": "Coffee order",
77
+ "type": "atomic",
78
+ "initial": null,
79
+ "inScope": true
80
+ },
81
+ {
82
+ "id": "Ready to add the drink",
83
+ "parent": "Customizing the drink",
84
+ "chart": "Coffee order",
85
+ "type": "atomic",
86
+ "initial": null,
87
+ "inScope": true
88
+ },
89
+ {
90
+ "id": "Reviewing the cart",
91
+ "parent": null,
92
+ "chart": "Coffee order",
93
+ "type": "atomic",
94
+ "initial": null,
95
+ "inScope": true
96
+ },
97
+ {
98
+ "id": "Checking out",
99
+ "parent": null,
100
+ "chart": "Coffee order",
101
+ "type": "atomic",
102
+ "initial": null,
103
+ "inScope": true
104
+ },
105
+ {
106
+ "id": "Order in progress",
107
+ "parent": null,
108
+ "chart": "Coffee order",
109
+ "type": "parallel",
110
+ "initial": null,
111
+ "inScope": true
112
+ },
113
+ {
114
+ "id": "Drink",
115
+ "parent": "Order in progress",
116
+ "chart": "Coffee order",
117
+ "type": "compound",
118
+ "initial": "Paid, waiting for the barista",
119
+ "inScope": true
120
+ },
121
+ {
122
+ "id": "Paid, waiting for the barista",
123
+ "parent": "Drink",
124
+ "chart": "Coffee order",
125
+ "type": "atomic",
126
+ "initial": null,
127
+ "inScope": true
128
+ },
129
+ {
130
+ "id": "Drink being made",
131
+ "parent": "Drink",
132
+ "chart": "Coffee order",
133
+ "type": "atomic",
134
+ "initial": null,
135
+ "inScope": true
136
+ },
137
+ {
138
+ "id": "Drink ready for pickup",
139
+ "parent": "Drink",
140
+ "chart": "Coffee order",
141
+ "type": "atomic",
142
+ "initial": null,
143
+ "inScope": true
144
+ },
145
+ {
146
+ "id": "Updates",
147
+ "parent": "Order in progress",
148
+ "chart": "Coffee order",
149
+ "type": "compound",
150
+ "initial": "Updates on",
151
+ "inScope": true
152
+ },
153
+ {
154
+ "id": "Updates on",
155
+ "parent": "Updates",
156
+ "chart": "Coffee order",
157
+ "type": "atomic",
158
+ "initial": null,
159
+ "inScope": true
160
+ },
161
+ {
162
+ "id": "Updates off",
163
+ "parent": "Updates",
164
+ "chart": "Coffee order",
165
+ "type": "atomic",
166
+ "initial": null,
167
+ "inScope": true
168
+ },
169
+ {
170
+ "id": "Told the drink was thrown away",
171
+ "parent": null,
172
+ "chart": "Coffee order",
173
+ "type": "atomic",
174
+ "initial": null,
175
+ "inScope": true
176
+ },
177
+ {
178
+ "id": "Order complete",
179
+ "parent": null,
180
+ "chart": "Coffee order",
181
+ "type": "final",
182
+ "initial": null,
183
+ "inScope": true
184
+ },
185
+ {
186
+ "id": "Choosing how to pay",
187
+ "parent": null,
188
+ "chart": "Checkout",
189
+ "type": "atomic",
190
+ "initial": null,
191
+ "inScope": true
192
+ },
193
+ {
194
+ "id": "Entering card details",
195
+ "parent": null,
196
+ "chart": "Checkout",
197
+ "type": "atomic",
198
+ "initial": null,
199
+ "inScope": true
200
+ },
201
+ {
202
+ "id": "Confirming with the wallet",
203
+ "parent": null,
204
+ "chart": "Checkout",
205
+ "type": "atomic",
206
+ "initial": null,
207
+ "inScope": true
208
+ },
209
+ {
210
+ "id": "Waiting for the payment",
211
+ "parent": null,
212
+ "chart": "Checkout",
213
+ "type": "atomic",
214
+ "initial": null,
215
+ "inScope": true
216
+ },
217
+ {
218
+ "id": "Told the payment is slow",
219
+ "parent": null,
220
+ "chart": "Checkout",
221
+ "type": "atomic",
222
+ "initial": null,
223
+ "inScope": true
224
+ },
225
+ {
226
+ "id": "Told the payment was declined",
227
+ "parent": null,
228
+ "chart": "Checkout",
229
+ "type": "atomic",
230
+ "initial": null,
231
+ "inScope": true
232
+ },
233
+ {
234
+ "id": "Paid",
235
+ "parent": null,
236
+ "chart": "Checkout",
237
+ "type": "final",
238
+ "initial": null,
239
+ "inScope": true
240
+ },
241
+ {
242
+ "id": "Checkout abandoned",
243
+ "parent": null,
244
+ "chart": "Checkout",
245
+ "type": "final",
246
+ "initial": null,
247
+ "inScope": true
248
+ }
249
+ ],
250
+ "edges": [
251
+ {
252
+ "id": "Browsing the menu :: Picks a drink",
253
+ "source": "Browsing the menu",
254
+ "target": "Customizing the drink",
255
+ "event": "Picks a drink",
256
+ "kind": "user",
257
+ "inScope": true
258
+ },
259
+ {
260
+ "id": "Choosing a size :: Picks a size",
261
+ "source": "Choosing a size",
262
+ "target": "Choosing the milk",
263
+ "event": "Picks a size",
264
+ "kind": "user",
265
+ "inScope": true
266
+ },
267
+ {
268
+ "id": "Choosing the milk :: Picks a milk",
269
+ "source": "Choosing the milk",
270
+ "target": "Ready to add the drink",
271
+ "event": "Picks a milk",
272
+ "kind": "user",
273
+ "inScope": true
274
+ },
275
+ {
276
+ "id": "Ready to add the drink :: Adds the drink to the cart",
277
+ "source": "Ready to add the drink",
278
+ "target": "Reviewing the cart",
279
+ "event": "Adds the drink to the cart",
280
+ "kind": "user",
281
+ "inScope": true
282
+ },
283
+ {
284
+ "id": "Customizing the drink :: Goes back to the menu",
285
+ "source": "Customizing the drink",
286
+ "target": "Browsing the menu",
287
+ "event": "Goes back to the menu",
288
+ "kind": "user",
289
+ "inScope": true
290
+ },
291
+ {
292
+ "id": "Reviewing the cart :: Removes the last drink",
293
+ "source": "Reviewing the cart",
294
+ "target": "Browsing the menu",
295
+ "event": "Removes the last drink",
296
+ "kind": "user",
297
+ "inScope": true
298
+ },
299
+ {
300
+ "id": "Reviewing the cart :: Starts checkout",
301
+ "source": "Reviewing the cart",
302
+ "target": "Checking out",
303
+ "event": "Starts checkout",
304
+ "kind": "user",
305
+ "inScope": true
306
+ },
307
+ {
308
+ "id": "Paid, waiting for the barista :: Barista starts the drink",
309
+ "source": "Paid, waiting for the barista",
310
+ "target": "Drink being made",
311
+ "event": "Barista starts the drink",
312
+ "kind": "system",
313
+ "inScope": true
314
+ },
315
+ {
316
+ "id": "Drink being made :: Barista finishes the drink",
317
+ "source": "Drink being made",
318
+ "target": "Drink ready for pickup",
319
+ "event": "Barista finishes the drink",
320
+ "kind": "system",
321
+ "inScope": true
322
+ },
323
+ {
324
+ "id": "Drink ready for pickup :: Picks up the drink",
325
+ "source": "Drink ready for pickup",
326
+ "target": "Order complete",
327
+ "event": "Picks up the drink",
328
+ "kind": "user",
329
+ "inScope": true
330
+ },
331
+ {
332
+ "id": "Drink ready for pickup :: Drink sits ready for ten minutes",
333
+ "source": "Drink ready for pickup",
334
+ "target": "Told the drink was thrown away",
335
+ "event": "Drink sits ready for ten minutes",
336
+ "kind": "time",
337
+ "inScope": true
338
+ },
339
+ {
340
+ "id": "Updates on :: Turns off updates",
341
+ "source": "Updates on",
342
+ "target": "Updates off",
343
+ "event": "Turns off updates",
344
+ "kind": "user",
345
+ "inScope": true
346
+ },
347
+ {
348
+ "id": "Updates off :: Turns on updates",
349
+ "source": "Updates off",
350
+ "target": "Updates on",
351
+ "event": "Turns on updates",
352
+ "kind": "user",
353
+ "inScope": true
354
+ },
355
+ {
356
+ "id": "Told the drink was thrown away :: Orders again",
357
+ "source": "Told the drink was thrown away",
358
+ "target": "Browsing the menu",
359
+ "event": "Orders again",
360
+ "kind": "user",
361
+ "inScope": true
362
+ },
363
+ {
364
+ "id": "Choosing how to pay :: Picks card",
365
+ "source": "Choosing how to pay",
366
+ "target": "Entering card details",
367
+ "event": "Picks card",
368
+ "kind": "user",
369
+ "inScope": true
370
+ },
371
+ {
372
+ "id": "Choosing how to pay :: Picks wallet",
373
+ "source": "Choosing how to pay",
374
+ "target": "Confirming with the wallet",
375
+ "event": "Picks wallet",
376
+ "kind": "user",
377
+ "inScope": true
378
+ },
379
+ {
380
+ "id": "Choosing how to pay :: Closes checkout",
381
+ "source": "Choosing how to pay",
382
+ "target": "Checkout abandoned",
383
+ "event": "Closes checkout",
384
+ "kind": "user",
385
+ "inScope": true
386
+ },
387
+ {
388
+ "id": "Entering card details :: Submits the card",
389
+ "source": "Entering card details",
390
+ "target": "Waiting for the payment",
391
+ "event": "Submits the card",
392
+ "kind": "user",
393
+ "inScope": true
394
+ },
395
+ {
396
+ "id": "Entering card details :: Goes back to the payment options",
397
+ "source": "Entering card details",
398
+ "target": "Choosing how to pay",
399
+ "event": "Goes back to the payment options",
400
+ "kind": "user",
401
+ "inScope": true
402
+ },
403
+ {
404
+ "id": "Confirming with the wallet :: Confirms with the wallet",
405
+ "source": "Confirming with the wallet",
406
+ "target": "Waiting for the payment",
407
+ "event": "Confirms with the wallet",
408
+ "kind": "user",
409
+ "inScope": true
410
+ },
411
+ {
412
+ "id": "Confirming with the wallet :: Cancels the wallet",
413
+ "source": "Confirming with the wallet",
414
+ "target": "Choosing how to pay",
415
+ "event": "Cancels the wallet",
416
+ "kind": "user",
417
+ "inScope": true
418
+ },
419
+ {
420
+ "id": "Waiting for the payment :: Payment provider approves the payment",
421
+ "source": "Waiting for the payment",
422
+ "target": "Paid",
423
+ "event": "Payment provider approves the payment",
424
+ "kind": "system",
425
+ "inScope": true
426
+ },
427
+ {
428
+ "id": "Waiting for the payment :: Payment provider declines the payment",
429
+ "source": "Waiting for the payment",
430
+ "target": "Told the payment was declined",
431
+ "event": "Payment provider declines the payment",
432
+ "kind": "system",
433
+ "inScope": true
434
+ },
435
+ {
436
+ "id": "Waiting for the payment :: Payment takes longer than a minute",
437
+ "source": "Waiting for the payment",
438
+ "target": "Told the payment is slow",
439
+ "event": "Payment takes longer than a minute",
440
+ "kind": "time",
441
+ "inScope": true
442
+ },
443
+ {
444
+ "id": "Told the payment is slow :: Checks the payment again",
445
+ "source": "Told the payment is slow",
446
+ "target": "Waiting for the payment",
447
+ "event": "Checks the payment again",
448
+ "kind": "user",
449
+ "inScope": true
450
+ },
451
+ {
452
+ "id": "Told the payment was declined :: Tries another way to pay",
453
+ "source": "Told the payment was declined",
454
+ "target": "Choosing how to pay",
455
+ "event": "Tries another way to pay",
456
+ "kind": "user",
457
+ "inScope": true
458
+ },
459
+ {
460
+ "id": "Paid :: Payment goes through",
461
+ "source": "Paid",
462
+ "target": "Order in progress",
463
+ "event": "Payment goes through",
464
+ "kind": "hand-off",
465
+ "inScope": true
466
+ },
467
+ {
468
+ "id": "Checkout abandoned :: Leaves checkout",
469
+ "source": "Checkout abandoned",
470
+ "target": "Reviewing the cart",
471
+ "event": "Leaves checkout",
472
+ "kind": "hand-off",
473
+ "inScope": true
474
+ }
475
+ ]
476
+ },
477
+ "states": {
478
+ "Browsing the menu": {
479
+ "name": "Browsing the menu",
480
+ "chart": "Coffee order",
481
+ "description": "The menu of drinks, with a cart button.",
482
+ "snapshot": "menu",
483
+ "confidence": "confirmed",
484
+ "source": [
485
+ "src/screens/menu.tsx"
486
+ ],
487
+ "expectedEvents": [],
488
+ "status": "passed",
489
+ "screenshot": {
490
+ "png": "media/paths/journey-1/01.png",
491
+ "webp": "media/paths/journey-1/01.webp"
492
+ },
493
+ "screenshotsByPath": {
494
+ "journey-1": {
495
+ "png": "media/paths/journey-1/01.png",
496
+ "webp": "media/paths/journey-1/01.webp"
497
+ }
498
+ },
499
+ "recognizer": {
500
+ "matched": true,
501
+ "signals": [
502
+ {
503
+ "signal": "test ID \"menu\"",
504
+ "expected": "visible",
505
+ "visible": true
506
+ }
507
+ ]
508
+ },
509
+ "looksLike": [],
510
+ "businessEvents": null,
511
+ "checks": [
512
+ {
513
+ "check": "The screen shows \"Browsing the menu\"",
514
+ "passed": true,
515
+ "expected": "test ID \"menu\" visible",
516
+ "actual": "visible"
517
+ }
518
+ ],
519
+ "reachedBy": [
520
+ "journey-1",
521
+ "journey-2",
522
+ "journey-3",
523
+ "journey-4",
524
+ "journey-5",
525
+ "journey-6",
526
+ "journey-7",
527
+ "journey-8",
528
+ "journey-9"
529
+ ],
530
+ "notes": []
531
+ },
532
+ "Customizing the drink": {
533
+ "name": "Customizing the drink",
534
+ "chart": "Coffee order",
535
+ "description": "The customer sets the drink up before adding it to the cart.",
536
+ "snapshot": "customizing-the-drink",
537
+ "confidence": "confirmed",
538
+ "source": [],
539
+ "expectedEvents": [],
540
+ "status": "passed",
541
+ "screenshot": null,
542
+ "screenshotsByPath": {},
543
+ "recognizer": {
544
+ "matched": true,
545
+ "signals": [
546
+ {
547
+ "signal": "test ID \"customizing-the-drink\"",
548
+ "expected": "visible",
549
+ "visible": true
550
+ }
551
+ ]
552
+ },
553
+ "looksLike": [],
554
+ "businessEvents": null,
555
+ "checks": [],
556
+ "reachedBy": [
557
+ "journey-1",
558
+ "journey-2",
559
+ "journey-3",
560
+ "journey-4",
561
+ "journey-5",
562
+ "journey-6",
563
+ "journey-7",
564
+ "journey-8",
565
+ "journey-9"
566
+ ],
567
+ "notes": []
568
+ },
569
+ "Choosing a size": {
570
+ "name": "Choosing a size",
571
+ "chart": "Coffee order",
572
+ "description": "Small, medium and large buttons.",
573
+ "snapshot": "size",
574
+ "confidence": "confirmed",
575
+ "source": [],
576
+ "expectedEvents": [],
577
+ "status": "passed",
578
+ "screenshot": {
579
+ "png": "media/paths/journey-1/02.png",
580
+ "webp": "media/paths/journey-1/02.webp"
581
+ },
582
+ "screenshotsByPath": {
583
+ "journey-1": {
584
+ "png": "media/paths/journey-1/02.png",
585
+ "webp": "media/paths/journey-1/02.webp"
586
+ }
587
+ },
588
+ "recognizer": {
589
+ "matched": true,
590
+ "signals": [
591
+ {
592
+ "signal": "test ID \"size\"",
593
+ "expected": "visible",
594
+ "visible": true
595
+ }
596
+ ]
597
+ },
598
+ "looksLike": [],
599
+ "businessEvents": null,
600
+ "checks": [
601
+ {
602
+ "check": "The screen shows \"Choosing a size\"",
603
+ "passed": true,
604
+ "expected": "test ID \"size\" visible",
605
+ "actual": "visible"
606
+ }
607
+ ],
608
+ "reachedBy": [
609
+ "journey-1",
610
+ "journey-2",
611
+ "journey-3",
612
+ "journey-4",
613
+ "journey-5",
614
+ "journey-6",
615
+ "journey-7",
616
+ "journey-8",
617
+ "journey-9"
618
+ ],
619
+ "notes": []
620
+ },
621
+ "Choosing the milk": {
622
+ "name": "Choosing the milk",
623
+ "chart": "Coffee order",
624
+ "description": "A list of milks, with \"No milk\" first.",
625
+ "snapshot": "milk",
626
+ "confidence": "confirmed",
627
+ "source": [],
628
+ "expectedEvents": [],
629
+ "status": "passed",
630
+ "screenshot": {
631
+ "png": "media/paths/journey-1/03.png",
632
+ "webp": "media/paths/journey-1/03.webp"
633
+ },
634
+ "screenshotsByPath": {
635
+ "journey-1": {
636
+ "png": "media/paths/journey-1/03.png",
637
+ "webp": "media/paths/journey-1/03.webp"
638
+ }
639
+ },
640
+ "recognizer": {
641
+ "matched": true,
642
+ "signals": [
643
+ {
644
+ "signal": "test ID \"milk\"",
645
+ "expected": "visible",
646
+ "visible": true
647
+ }
648
+ ]
649
+ },
650
+ "looksLike": [],
651
+ "businessEvents": null,
652
+ "checks": [
653
+ {
654
+ "check": "The screen shows \"Choosing the milk\"",
655
+ "passed": true,
656
+ "expected": "test ID \"milk\" visible",
657
+ "actual": "visible"
658
+ }
659
+ ],
660
+ "reachedBy": [
661
+ "journey-1",
662
+ "journey-2",
663
+ "journey-3",
664
+ "journey-4",
665
+ "journey-5",
666
+ "journey-6",
667
+ "journey-7",
668
+ "journey-8",
669
+ "journey-9"
670
+ ],
671
+ "notes": []
672
+ },
673
+ "Ready to add the drink": {
674
+ "name": "Ready to add the drink",
675
+ "chart": "Coffee order",
676
+ "description": "A summary of the drink with an \"Add to cart\" button.",
677
+ "snapshot": "drink-summary",
678
+ "confidence": "confirmed",
679
+ "source": [],
680
+ "expectedEvents": [],
681
+ "status": "passed",
682
+ "screenshot": {
683
+ "png": "media/paths/journey-1/04.png",
684
+ "webp": "media/paths/journey-1/04.webp"
685
+ },
686
+ "screenshotsByPath": {
687
+ "journey-1": {
688
+ "png": "media/paths/journey-1/04.png",
689
+ "webp": "media/paths/journey-1/04.webp"
690
+ }
691
+ },
692
+ "recognizer": {
693
+ "matched": true,
694
+ "signals": [
695
+ {
696
+ "signal": "test ID \"drink-summary\"",
697
+ "expected": "visible",
698
+ "visible": true
699
+ }
700
+ ]
701
+ },
702
+ "looksLike": [],
703
+ "businessEvents": null,
704
+ "checks": [
705
+ {
706
+ "check": "The screen shows \"Ready to add the drink\"",
707
+ "passed": true,
708
+ "expected": "test ID \"drink-summary\" visible",
709
+ "actual": "visible"
710
+ }
711
+ ],
712
+ "reachedBy": [
713
+ "journey-1",
714
+ "journey-2",
715
+ "journey-3",
716
+ "journey-4",
717
+ "journey-5",
718
+ "journey-6",
719
+ "journey-7",
720
+ "journey-9"
721
+ ],
722
+ "notes": []
723
+ },
724
+ "Reviewing the cart": {
725
+ "name": "Reviewing the cart",
726
+ "chart": "Coffee order",
727
+ "description": "The drinks in the cart, the total, and a checkout button.",
728
+ "snapshot": "cart",
729
+ "confidence": "confirmed",
730
+ "source": [],
731
+ "expectedEvents": [],
732
+ "status": "passed",
733
+ "screenshot": {
734
+ "png": "media/paths/journey-1/05.png",
735
+ "webp": "media/paths/journey-1/05.webp"
736
+ },
737
+ "screenshotsByPath": {
738
+ "journey-1": {
739
+ "png": "media/paths/journey-1/05.png",
740
+ "webp": "media/paths/journey-1/05.webp"
741
+ }
742
+ },
743
+ "recognizer": {
744
+ "matched": true,
745
+ "signals": [
746
+ {
747
+ "signal": "test ID \"cart\"",
748
+ "expected": "visible",
749
+ "visible": true
750
+ }
751
+ ]
752
+ },
753
+ "looksLike": [],
754
+ "businessEvents": null,
755
+ "checks": [
756
+ {
757
+ "check": "The screen shows \"Reviewing the cart\"",
758
+ "passed": true,
759
+ "expected": "test ID \"cart\" visible",
760
+ "actual": "visible"
761
+ }
762
+ ],
763
+ "reachedBy": [
764
+ "journey-1",
765
+ "journey-2",
766
+ "journey-3",
767
+ "journey-4",
768
+ "journey-5",
769
+ "journey-6",
770
+ "journey-7",
771
+ "journey-9"
772
+ ],
773
+ "notes": []
774
+ },
775
+ "Checking out": {
776
+ "name": "Checking out",
777
+ "chart": "Coffee order",
778
+ "description": "Checkout runs as its own chart.",
779
+ "snapshot": "checking-out",
780
+ "confidence": "confirmed",
781
+ "source": [],
782
+ "expectedEvents": [],
783
+ "status": "passed",
784
+ "screenshot": null,
785
+ "screenshotsByPath": {},
786
+ "recognizer": {
787
+ "matched": true,
788
+ "signals": [
789
+ {
790
+ "signal": "test ID \"checking-out\"",
791
+ "expected": "visible",
792
+ "visible": true
793
+ }
794
+ ]
795
+ },
796
+ "looksLike": [],
797
+ "businessEvents": null,
798
+ "checks": [],
799
+ "reachedBy": [
800
+ "journey-1",
801
+ "journey-2",
802
+ "journey-3",
803
+ "journey-4",
804
+ "journey-5",
805
+ "journey-6",
806
+ "journey-7"
807
+ ],
808
+ "notes": []
809
+ },
810
+ "Order in progress": {
811
+ "name": "Order in progress",
812
+ "chart": "Coffee order",
813
+ "description": "The drink is made while the customer chooses how to hear about it.",
814
+ "snapshot": "order-in-progress",
815
+ "confidence": "confirmed",
816
+ "source": [],
817
+ "expectedEvents": [],
818
+ "status": "passed",
819
+ "screenshot": null,
820
+ "screenshotsByPath": {},
821
+ "recognizer": {
822
+ "matched": true,
823
+ "signals": [
824
+ {
825
+ "signal": "test ID \"order-in-progress\"",
826
+ "expected": "visible",
827
+ "visible": true
828
+ }
829
+ ]
830
+ },
831
+ "looksLike": [],
832
+ "businessEvents": null,
833
+ "checks": [],
834
+ "reachedBy": [
835
+ "journey-1",
836
+ "journey-2",
837
+ "journey-3",
838
+ "journey-4",
839
+ "journey-6",
840
+ "journey-7",
841
+ "generated-1"
842
+ ],
843
+ "notes": []
844
+ },
845
+ "Drink": {
846
+ "name": "Drink",
847
+ "chart": "Coffee order",
848
+ "description": "Where the drink is.",
849
+ "snapshot": "drink",
850
+ "confidence": "confirmed",
851
+ "source": [],
852
+ "expectedEvents": [],
853
+ "status": "passed",
854
+ "screenshot": null,
855
+ "screenshotsByPath": {},
856
+ "recognizer": {
857
+ "matched": true,
858
+ "signals": [
859
+ {
860
+ "signal": "test ID \"drink\"",
861
+ "expected": "visible",
862
+ "visible": true
863
+ }
864
+ ]
865
+ },
866
+ "looksLike": [],
867
+ "businessEvents": null,
868
+ "checks": [],
869
+ "reachedBy": [
870
+ "journey-1",
871
+ "journey-2",
872
+ "journey-3",
873
+ "journey-4",
874
+ "journey-6",
875
+ "journey-7"
876
+ ],
877
+ "notes": []
878
+ },
879
+ "Paid, waiting for the barista": {
880
+ "name": "Paid, waiting for the barista",
881
+ "chart": "Coffee order",
882
+ "description": "A card says the order is paid and in the queue.",
883
+ "snapshot": "order-queued",
884
+ "confidence": "confirmed",
885
+ "source": [],
886
+ "expectedEvents": [
887
+ "Order paid"
888
+ ],
889
+ "status": "passed",
890
+ "screenshot": {
891
+ "png": "media/paths/journey-1/06.png",
892
+ "webp": "media/paths/journey-1/06.webp"
893
+ },
894
+ "screenshotsByPath": {
895
+ "journey-1": {
896
+ "png": "media/paths/journey-1/06.png",
897
+ "webp": "media/paths/journey-1/06.webp"
898
+ }
899
+ },
900
+ "recognizer": {
901
+ "matched": true,
902
+ "signals": [
903
+ {
904
+ "signal": "test ID \"order-queued\"",
905
+ "expected": "visible",
906
+ "visible": true
907
+ }
908
+ ]
909
+ },
910
+ "looksLike": [],
911
+ "businessEvents": {
912
+ "expected": [
913
+ "Order paid"
914
+ ],
915
+ "observed": [
916
+ "Order paid"
917
+ ],
918
+ "missing": [],
919
+ "noSignal": [],
920
+ "events": [
921
+ {
922
+ "specversion": "1.0",
923
+ "id": "fa3a6af60ea0ca6cc648",
924
+ "source": "/fixture/orders",
925
+ "type": "com.example.order.paid",
926
+ "time": "2026-10-06T14:41:00.000Z",
927
+ "subject": "order-fixture-571dc1",
928
+ "datacontenttype": "application/json",
929
+ "data": {
930
+ "name": "Order paid"
931
+ }
932
+ }
933
+ ]
934
+ },
935
+ "checks": [
936
+ {
937
+ "check": "The screen shows \"Paid, waiting for the barista\"",
938
+ "passed": true,
939
+ "expected": "test ID \"order-queued\" visible",
940
+ "actual": "visible"
941
+ }
942
+ ],
943
+ "reachedBy": [
944
+ "journey-1",
945
+ "journey-2",
946
+ "journey-3",
947
+ "journey-4",
948
+ "journey-6",
949
+ "journey-7"
950
+ ],
951
+ "notes": []
952
+ },
953
+ "Drink being made": {
954
+ "name": "Drink being made",
955
+ "chart": "Coffee order",
956
+ "description": "A progress bar while the barista makes the drink.",
957
+ "snapshot": "order-making",
958
+ "confidence": "assumed",
959
+ "source": [],
960
+ "expectedEvents": [],
961
+ "status": "passed",
962
+ "screenshot": {
963
+ "png": "media/paths/journey-1/07.png",
964
+ "webp": "media/paths/journey-1/07.webp"
965
+ },
966
+ "screenshotsByPath": {
967
+ "journey-1": {
968
+ "png": "media/paths/journey-1/07.png",
969
+ "webp": "media/paths/journey-1/07.webp"
970
+ }
971
+ },
972
+ "recognizer": {
973
+ "matched": true,
974
+ "signals": [
975
+ {
976
+ "signal": "test ID \"order-making\"",
977
+ "expected": "visible",
978
+ "visible": true
979
+ }
980
+ ]
981
+ },
982
+ "looksLike": [],
983
+ "businessEvents": null,
984
+ "checks": [
985
+ {
986
+ "check": "The screen shows \"Drink being made\"",
987
+ "passed": true,
988
+ "expected": "test ID \"order-making\" visible",
989
+ "actual": "visible"
990
+ }
991
+ ],
992
+ "reachedBy": [
993
+ "journey-1",
994
+ "journey-6",
995
+ "journey-7"
996
+ ],
997
+ "notes": []
998
+ },
999
+ "Drink ready for pickup": {
1000
+ "name": "Drink ready for pickup",
1001
+ "chart": "Coffee order",
1002
+ "description": "A card says the drink is ready, with the pickup counter.",
1003
+ "snapshot": "order-ready",
1004
+ "confidence": "confirmed",
1005
+ "source": [],
1006
+ "expectedEvents": [
1007
+ "Customer notified"
1008
+ ],
1009
+ "status": "passed",
1010
+ "screenshot": {
1011
+ "png": "media/paths/journey-1/08.png",
1012
+ "webp": "media/paths/journey-1/08.webp"
1013
+ },
1014
+ "screenshotsByPath": {
1015
+ "journey-1": {
1016
+ "png": "media/paths/journey-1/08.png",
1017
+ "webp": "media/paths/journey-1/08.webp"
1018
+ }
1019
+ },
1020
+ "recognizer": {
1021
+ "matched": true,
1022
+ "signals": [
1023
+ {
1024
+ "signal": "test ID \"order-ready\"",
1025
+ "expected": "visible",
1026
+ "visible": true
1027
+ }
1028
+ ]
1029
+ },
1030
+ "looksLike": [],
1031
+ "businessEvents": {
1032
+ "expected": [
1033
+ "Customer notified"
1034
+ ],
1035
+ "observed": [
1036
+ "Customer notified"
1037
+ ],
1038
+ "missing": [],
1039
+ "noSignal": [],
1040
+ "events": [
1041
+ {
1042
+ "specversion": "1.0",
1043
+ "id": "2b441cb5e154b722a47f",
1044
+ "source": "/fixture/orders",
1045
+ "type": "com.example.customer.notified",
1046
+ "time": "2026-10-06T14:41:00.000Z",
1047
+ "subject": "order-fixture-571dc1",
1048
+ "datacontenttype": "application/json",
1049
+ "data": {
1050
+ "name": "Customer notified"
1051
+ }
1052
+ }
1053
+ ]
1054
+ },
1055
+ "checks": [
1056
+ {
1057
+ "check": "The screen shows \"Drink ready for pickup\"",
1058
+ "passed": true,
1059
+ "expected": "test ID \"order-ready\" visible",
1060
+ "actual": "visible"
1061
+ }
1062
+ ],
1063
+ "reachedBy": [
1064
+ "journey-1",
1065
+ "journey-6"
1066
+ ],
1067
+ "notes": []
1068
+ },
1069
+ "Updates": {
1070
+ "name": "Updates",
1071
+ "chart": "Coffee order",
1072
+ "description": "Whether the customer gets a notification at each step.",
1073
+ "snapshot": "updates",
1074
+ "confidence": "confirmed",
1075
+ "source": [],
1076
+ "expectedEvents": [],
1077
+ "status": "passed",
1078
+ "screenshot": null,
1079
+ "screenshotsByPath": {},
1080
+ "recognizer": {
1081
+ "matched": true,
1082
+ "signals": [
1083
+ {
1084
+ "signal": "test ID \"updates\"",
1085
+ "expected": "visible",
1086
+ "visible": true
1087
+ }
1088
+ ]
1089
+ },
1090
+ "looksLike": [],
1091
+ "businessEvents": null,
1092
+ "checks": [],
1093
+ "reachedBy": [
1094
+ "journey-1",
1095
+ "journey-2",
1096
+ "journey-3",
1097
+ "journey-4",
1098
+ "journey-6",
1099
+ "journey-7",
1100
+ "generated-1"
1101
+ ],
1102
+ "notes": []
1103
+ },
1104
+ "Updates on": {
1105
+ "name": "Updates on",
1106
+ "chart": "Coffee order",
1107
+ "description": "The updates switch is on.",
1108
+ "snapshot": "updates-on",
1109
+ "confidence": "confirmed",
1110
+ "source": [],
1111
+ "expectedEvents": [],
1112
+ "status": "passed",
1113
+ "screenshot": {
1114
+ "png": "media/paths/journey-1/09.png",
1115
+ "webp": "media/paths/journey-1/09.webp"
1116
+ },
1117
+ "screenshotsByPath": {
1118
+ "journey-1": {
1119
+ "png": "media/paths/journey-1/09.png",
1120
+ "webp": "media/paths/journey-1/09.webp"
1121
+ }
1122
+ },
1123
+ "recognizer": {
1124
+ "matched": true,
1125
+ "signals": [
1126
+ {
1127
+ "signal": "test ID \"updates-on\"",
1128
+ "expected": "visible",
1129
+ "visible": true
1130
+ }
1131
+ ]
1132
+ },
1133
+ "looksLike": [],
1134
+ "businessEvents": null,
1135
+ "checks": [
1136
+ {
1137
+ "check": "The screen shows \"Updates on\"",
1138
+ "passed": true,
1139
+ "expected": "test ID \"updates-on\" visible",
1140
+ "actual": "visible"
1141
+ }
1142
+ ],
1143
+ "reachedBy": [
1144
+ "journey-1",
1145
+ "journey-2",
1146
+ "journey-3",
1147
+ "journey-4",
1148
+ "journey-6",
1149
+ "journey-7",
1150
+ "generated-1"
1151
+ ],
1152
+ "notes": []
1153
+ },
1154
+ "Updates off": {
1155
+ "name": "Updates off",
1156
+ "chart": "Coffee order",
1157
+ "description": "The updates switch is off.",
1158
+ "snapshot": "updates-off",
1159
+ "confidence": "confirmed",
1160
+ "source": [],
1161
+ "expectedEvents": [],
1162
+ "status": "passed",
1163
+ "screenshot": {
1164
+ "png": "media/paths/journey-7/01.png",
1165
+ "webp": "media/paths/journey-7/01.webp"
1166
+ },
1167
+ "screenshotsByPath": {
1168
+ "journey-7": {
1169
+ "png": "media/paths/journey-7/01.png",
1170
+ "webp": "media/paths/journey-7/01.webp"
1171
+ }
1172
+ },
1173
+ "recognizer": {
1174
+ "matched": true,
1175
+ "signals": [
1176
+ {
1177
+ "signal": "test ID \"updates-off\"",
1178
+ "expected": "visible",
1179
+ "visible": true
1180
+ }
1181
+ ]
1182
+ },
1183
+ "looksLike": [],
1184
+ "businessEvents": null,
1185
+ "checks": [
1186
+ {
1187
+ "check": "The screen shows \"Updates off\"",
1188
+ "passed": true,
1189
+ "expected": "test ID \"updates-off\" visible",
1190
+ "actual": "visible"
1191
+ }
1192
+ ],
1193
+ "reachedBy": [
1194
+ "journey-7",
1195
+ "generated-1"
1196
+ ],
1197
+ "notes": []
1198
+ },
1199
+ "Told the drink was thrown away": {
1200
+ "name": "Told the drink was thrown away",
1201
+ "chart": "Coffee order",
1202
+ "description": "A message says the drink waited too long and was refunded.",
1203
+ "snapshot": "order-expired",
1204
+ "confidence": "assumed",
1205
+ "source": [],
1206
+ "expectedEvents": [
1207
+ "Order refunded"
1208
+ ],
1209
+ "status": "passed",
1210
+ "screenshot": {
1211
+ "png": "media/paths/journey-6/01.png",
1212
+ "webp": "media/paths/journey-6/01.webp"
1213
+ },
1214
+ "screenshotsByPath": {
1215
+ "journey-6": {
1216
+ "png": "media/paths/journey-6/01.png",
1217
+ "webp": "media/paths/journey-6/01.webp"
1218
+ }
1219
+ },
1220
+ "recognizer": {
1221
+ "matched": true,
1222
+ "signals": [
1223
+ {
1224
+ "signal": "test ID \"order-expired\"",
1225
+ "expected": "visible",
1226
+ "visible": true
1227
+ }
1228
+ ]
1229
+ },
1230
+ "looksLike": [],
1231
+ "businessEvents": {
1232
+ "expected": [
1233
+ "Order refunded"
1234
+ ],
1235
+ "observed": [
1236
+ "Order refunded"
1237
+ ],
1238
+ "missing": [],
1239
+ "noSignal": [],
1240
+ "events": [
1241
+ {
1242
+ "specversion": "1.0",
1243
+ "id": "93ce523cd7dad90725ff",
1244
+ "source": "/fixture/orders",
1245
+ "type": "com.example.order.refunded",
1246
+ "time": "2026-10-06T14:41:00.000Z",
1247
+ "subject": "order-fixture-571dc1",
1248
+ "datacontenttype": "application/json",
1249
+ "data": {
1250
+ "name": "Order refunded"
1251
+ }
1252
+ }
1253
+ ]
1254
+ },
1255
+ "checks": [
1256
+ {
1257
+ "check": "The screen shows \"Told the drink was thrown away\"",
1258
+ "passed": true,
1259
+ "expected": "test ID \"order-expired\" visible",
1260
+ "actual": "visible"
1261
+ }
1262
+ ],
1263
+ "reachedBy": [
1264
+ "journey-6"
1265
+ ],
1266
+ "notes": []
1267
+ },
1268
+ "Order complete": {
1269
+ "name": "Order complete",
1270
+ "chart": "Coffee order",
1271
+ "description": "A thank-you screen with the receipt.",
1272
+ "snapshot": "order-complete",
1273
+ "confidence": "confirmed",
1274
+ "source": [],
1275
+ "expectedEvents": [
1276
+ "Order completed"
1277
+ ],
1278
+ "status": "passed",
1279
+ "screenshot": {
1280
+ "png": "media/paths/journey-1/10.png",
1281
+ "webp": "media/paths/journey-1/10.webp"
1282
+ },
1283
+ "screenshotsByPath": {
1284
+ "journey-1": {
1285
+ "png": "media/paths/journey-1/10.png",
1286
+ "webp": "media/paths/journey-1/10.webp"
1287
+ }
1288
+ },
1289
+ "recognizer": {
1290
+ "matched": true,
1291
+ "signals": [
1292
+ {
1293
+ "signal": "test ID \"order-complete\"",
1294
+ "expected": "visible",
1295
+ "visible": true
1296
+ }
1297
+ ]
1298
+ },
1299
+ "looksLike": [],
1300
+ "businessEvents": {
1301
+ "expected": [
1302
+ "Order completed"
1303
+ ],
1304
+ "observed": [
1305
+ "Order completed"
1306
+ ],
1307
+ "missing": [],
1308
+ "noSignal": [],
1309
+ "events": [
1310
+ {
1311
+ "specversion": "1.0",
1312
+ "id": "d9e4c71df569fd6948c4",
1313
+ "source": "/fixture/orders",
1314
+ "type": "com.example.order.completed",
1315
+ "time": "2026-10-06T14:41:00.000Z",
1316
+ "subject": "order-fixture-571dc1",
1317
+ "datacontenttype": "application/json",
1318
+ "data": {
1319
+ "name": "Order completed"
1320
+ }
1321
+ }
1322
+ ]
1323
+ },
1324
+ "checks": [
1325
+ {
1326
+ "check": "The screen shows \"Order complete\"",
1327
+ "passed": true,
1328
+ "expected": "test ID \"order-complete\" visible",
1329
+ "actual": "visible"
1330
+ }
1331
+ ],
1332
+ "reachedBy": [
1333
+ "journey-1"
1334
+ ],
1335
+ "notes": []
1336
+ },
1337
+ "Choosing how to pay": {
1338
+ "name": "Choosing how to pay",
1339
+ "chart": "Checkout",
1340
+ "description": "Card and wallet buttons, and the order total.",
1341
+ "snapshot": "pay-options",
1342
+ "confidence": "confirmed",
1343
+ "source": [],
1344
+ "expectedEvents": [],
1345
+ "status": "passed",
1346
+ "screenshot": {
1347
+ "png": "media/paths/journey-1/11.png",
1348
+ "webp": "media/paths/journey-1/11.webp"
1349
+ },
1350
+ "screenshotsByPath": {
1351
+ "journey-1": {
1352
+ "png": "media/paths/journey-1/11.png",
1353
+ "webp": "media/paths/journey-1/11.webp"
1354
+ }
1355
+ },
1356
+ "recognizer": {
1357
+ "matched": true,
1358
+ "signals": [
1359
+ {
1360
+ "signal": "test ID \"pay-options\"",
1361
+ "expected": "visible",
1362
+ "visible": true
1363
+ }
1364
+ ]
1365
+ },
1366
+ "looksLike": [],
1367
+ "businessEvents": null,
1368
+ "checks": [
1369
+ {
1370
+ "check": "The screen shows \"Choosing how to pay\"",
1371
+ "passed": true,
1372
+ "expected": "test ID \"pay-options\" visible",
1373
+ "actual": "visible"
1374
+ }
1375
+ ],
1376
+ "reachedBy": [
1377
+ "journey-1",
1378
+ "journey-2",
1379
+ "journey-3",
1380
+ "journey-4",
1381
+ "journey-5",
1382
+ "journey-6",
1383
+ "journey-7",
1384
+ "generated-2"
1385
+ ],
1386
+ "notes": []
1387
+ },
1388
+ "Entering card details": {
1389
+ "name": "Entering card details",
1390
+ "chart": "Checkout",
1391
+ "description": "A form for the card number, expiry and code.",
1392
+ "snapshot": "card-form",
1393
+ "confidence": "confirmed",
1394
+ "source": [],
1395
+ "expectedEvents": [],
1396
+ "status": "passed",
1397
+ "screenshot": {
1398
+ "png": "media/paths/journey-1/12.png",
1399
+ "webp": "media/paths/journey-1/12.webp"
1400
+ },
1401
+ "screenshotsByPath": {
1402
+ "journey-1": {
1403
+ "png": "media/paths/journey-1/12.png",
1404
+ "webp": "media/paths/journey-1/12.webp"
1405
+ }
1406
+ },
1407
+ "recognizer": {
1408
+ "matched": true,
1409
+ "signals": [
1410
+ {
1411
+ "signal": "test ID \"card-form\"",
1412
+ "expected": "visible",
1413
+ "visible": true
1414
+ }
1415
+ ]
1416
+ },
1417
+ "looksLike": [],
1418
+ "businessEvents": null,
1419
+ "checks": [
1420
+ {
1421
+ "check": "The screen shows \"Entering card details\"",
1422
+ "passed": true,
1423
+ "expected": "test ID \"card-form\" visible",
1424
+ "actual": "visible"
1425
+ }
1426
+ ],
1427
+ "reachedBy": [
1428
+ "journey-1",
1429
+ "journey-3",
1430
+ "journey-4",
1431
+ "journey-6",
1432
+ "generated-2"
1433
+ ],
1434
+ "notes": []
1435
+ },
1436
+ "Confirming with the wallet": {
1437
+ "name": "Confirming with the wallet",
1438
+ "chart": "Checkout",
1439
+ "description": "The wallet sheet asks the customer to confirm the payment.",
1440
+ "snapshot": "wallet-sheet",
1441
+ "confidence": "confirmed",
1442
+ "source": [],
1443
+ "expectedEvents": [],
1444
+ "status": "passed",
1445
+ "screenshot": {
1446
+ "png": "media/paths/journey-2/01.png",
1447
+ "webp": "media/paths/journey-2/01.webp"
1448
+ },
1449
+ "screenshotsByPath": {
1450
+ "journey-2": {
1451
+ "png": "media/paths/journey-2/01.png",
1452
+ "webp": "media/paths/journey-2/01.webp"
1453
+ }
1454
+ },
1455
+ "recognizer": {
1456
+ "matched": true,
1457
+ "signals": [
1458
+ {
1459
+ "signal": "test ID \"wallet-sheet\"",
1460
+ "expected": "visible",
1461
+ "visible": true
1462
+ }
1463
+ ]
1464
+ },
1465
+ "looksLike": [],
1466
+ "businessEvents": null,
1467
+ "checks": [
1468
+ {
1469
+ "check": "The screen shows \"Confirming with the wallet\"",
1470
+ "passed": true,
1471
+ "expected": "test ID \"wallet-sheet\" visible",
1472
+ "actual": "visible"
1473
+ }
1474
+ ],
1475
+ "reachedBy": [
1476
+ "journey-2",
1477
+ "journey-3",
1478
+ "journey-7",
1479
+ "generated-2"
1480
+ ],
1481
+ "notes": []
1482
+ },
1483
+ "Waiting for the payment": {
1484
+ "name": "Waiting for the payment",
1485
+ "chart": "Checkout",
1486
+ "description": "A spinner while the payment provider answers.",
1487
+ "snapshot": "paying",
1488
+ "confidence": "confirmed",
1489
+ "source": [],
1490
+ "expectedEvents": [
1491
+ "Payment requested"
1492
+ ],
1493
+ "status": "passed",
1494
+ "screenshot": {
1495
+ "png": "media/paths/journey-1/13.png",
1496
+ "webp": "media/paths/journey-1/13.webp"
1497
+ },
1498
+ "screenshotsByPath": {
1499
+ "journey-1": {
1500
+ "png": "media/paths/journey-1/13.png",
1501
+ "webp": "media/paths/journey-1/13.webp"
1502
+ }
1503
+ },
1504
+ "recognizer": {
1505
+ "matched": true,
1506
+ "signals": [
1507
+ {
1508
+ "signal": "test ID \"paying\"",
1509
+ "expected": "visible",
1510
+ "visible": true
1511
+ }
1512
+ ]
1513
+ },
1514
+ "looksLike": [],
1515
+ "businessEvents": {
1516
+ "expected": [
1517
+ "Payment requested"
1518
+ ],
1519
+ "observed": [
1520
+ "Payment requested"
1521
+ ],
1522
+ "missing": [],
1523
+ "noSignal": [],
1524
+ "events": [
1525
+ {
1526
+ "specversion": "1.0",
1527
+ "id": "7cb996cc3f5a72fce3c5",
1528
+ "source": "/fixture/orders",
1529
+ "type": "com.example.payment.requested",
1530
+ "time": "2026-10-06T14:41:00.000Z",
1531
+ "subject": "order-fixture-571dc1",
1532
+ "datacontenttype": "application/json",
1533
+ "data": {
1534
+ "name": "Payment requested"
1535
+ }
1536
+ }
1537
+ ]
1538
+ },
1539
+ "checks": [
1540
+ {
1541
+ "check": "The screen shows \"Waiting for the payment\"",
1542
+ "passed": true,
1543
+ "expected": "test ID \"paying\" visible",
1544
+ "actual": "visible"
1545
+ }
1546
+ ],
1547
+ "reachedBy": [
1548
+ "journey-1",
1549
+ "journey-2",
1550
+ "journey-3",
1551
+ "journey-4",
1552
+ "journey-6",
1553
+ "journey-7"
1554
+ ],
1555
+ "notes": []
1556
+ },
1557
+ "Told the payment is slow": {
1558
+ "name": "Told the payment is slow",
1559
+ "chart": "Checkout",
1560
+ "description": "A message says the payment is taking longer than usual, with \"Check again\".",
1561
+ "snapshot": "paying-slow",
1562
+ "confidence": "assumed",
1563
+ "source": [],
1564
+ "expectedEvents": [],
1565
+ "status": "passed",
1566
+ "screenshot": {
1567
+ "png": "media/paths/journey-4/01.png",
1568
+ "webp": "media/paths/journey-4/01.webp"
1569
+ },
1570
+ "screenshotsByPath": {
1571
+ "journey-4": {
1572
+ "png": "media/paths/journey-4/01.png",
1573
+ "webp": "media/paths/journey-4/01.webp"
1574
+ }
1575
+ },
1576
+ "recognizer": {
1577
+ "matched": true,
1578
+ "signals": [
1579
+ {
1580
+ "signal": "test ID \"paying-slow\"",
1581
+ "expected": "visible",
1582
+ "visible": true
1583
+ }
1584
+ ]
1585
+ },
1586
+ "looksLike": [],
1587
+ "businessEvents": null,
1588
+ "checks": [
1589
+ {
1590
+ "check": "The screen shows \"Told the payment is slow\"",
1591
+ "passed": true,
1592
+ "expected": "test ID \"paying-slow\" visible",
1593
+ "actual": "visible"
1594
+ }
1595
+ ],
1596
+ "reachedBy": [
1597
+ "journey-4"
1598
+ ],
1599
+ "notes": []
1600
+ },
1601
+ "Told the payment was declined": {
1602
+ "name": "Told the payment was declined",
1603
+ "chart": "Checkout",
1604
+ "description": "A message says the payment was declined, with \"Try another way\".",
1605
+ "snapshot": "payment-declined",
1606
+ "confidence": "confirmed",
1607
+ "source": [],
1608
+ "expectedEvents": [
1609
+ "Payment declined"
1610
+ ],
1611
+ "status": "passed",
1612
+ "screenshot": {
1613
+ "png": "media/paths/journey-3/01.png",
1614
+ "webp": "media/paths/journey-3/01.webp"
1615
+ },
1616
+ "screenshotsByPath": {
1617
+ "journey-3": {
1618
+ "png": "media/paths/journey-3/01.png",
1619
+ "webp": "media/paths/journey-3/01.webp"
1620
+ }
1621
+ },
1622
+ "recognizer": {
1623
+ "matched": true,
1624
+ "signals": [
1625
+ {
1626
+ "signal": "test ID \"payment-declined\"",
1627
+ "expected": "visible",
1628
+ "visible": true
1629
+ }
1630
+ ]
1631
+ },
1632
+ "looksLike": [],
1633
+ "businessEvents": {
1634
+ "expected": [
1635
+ "Payment declined"
1636
+ ],
1637
+ "observed": [
1638
+ "Payment declined"
1639
+ ],
1640
+ "missing": [],
1641
+ "noSignal": [],
1642
+ "events": [
1643
+ {
1644
+ "specversion": "1.0",
1645
+ "id": "7ba4035a20dbd80834ca",
1646
+ "source": "/fixture/orders",
1647
+ "type": "com.example.payment.declined",
1648
+ "time": "2026-10-06T14:41:00.000Z",
1649
+ "subject": "order-fixture-571dc1",
1650
+ "datacontenttype": "application/json",
1651
+ "data": {
1652
+ "name": "Payment declined"
1653
+ }
1654
+ }
1655
+ ]
1656
+ },
1657
+ "checks": [
1658
+ {
1659
+ "check": "The screen shows \"Told the payment was declined\"",
1660
+ "passed": true,
1661
+ "expected": "test ID \"payment-declined\" visible",
1662
+ "actual": "visible"
1663
+ }
1664
+ ],
1665
+ "reachedBy": [
1666
+ "journey-3"
1667
+ ],
1668
+ "notes": []
1669
+ },
1670
+ "Paid": {
1671
+ "name": "Paid",
1672
+ "chart": "Checkout",
1673
+ "description": "A check mark confirms the payment.",
1674
+ "snapshot": "paid",
1675
+ "confidence": "confirmed",
1676
+ "source": [],
1677
+ "expectedEvents": [
1678
+ "Payment captured"
1679
+ ],
1680
+ "status": "passed",
1681
+ "screenshot": {
1682
+ "png": "media/paths/journey-1/14.png",
1683
+ "webp": "media/paths/journey-1/14.webp"
1684
+ },
1685
+ "screenshotsByPath": {
1686
+ "journey-1": {
1687
+ "png": "media/paths/journey-1/14.png",
1688
+ "webp": "media/paths/journey-1/14.webp"
1689
+ }
1690
+ },
1691
+ "recognizer": {
1692
+ "matched": true,
1693
+ "signals": [
1694
+ {
1695
+ "signal": "test ID \"paid\"",
1696
+ "expected": "visible",
1697
+ "visible": true
1698
+ }
1699
+ ]
1700
+ },
1701
+ "looksLike": [],
1702
+ "businessEvents": {
1703
+ "expected": [
1704
+ "Payment captured"
1705
+ ],
1706
+ "observed": [
1707
+ "Payment captured"
1708
+ ],
1709
+ "missing": [],
1710
+ "noSignal": [],
1711
+ "events": [
1712
+ {
1713
+ "specversion": "1.0",
1714
+ "id": "3556a91551ce991b18f6",
1715
+ "source": "/fixture/orders",
1716
+ "type": "com.example.payment.captured",
1717
+ "time": "2026-10-06T14:41:00.000Z",
1718
+ "subject": "order-fixture-571dc1",
1719
+ "datacontenttype": "application/json",
1720
+ "data": {
1721
+ "name": "Payment captured"
1722
+ }
1723
+ }
1724
+ ]
1725
+ },
1726
+ "checks": [
1727
+ {
1728
+ "check": "The screen shows \"Paid\"",
1729
+ "passed": true,
1730
+ "expected": "test ID \"paid\" visible",
1731
+ "actual": "visible"
1732
+ }
1733
+ ],
1734
+ "reachedBy": [
1735
+ "journey-1",
1736
+ "journey-2",
1737
+ "journey-3",
1738
+ "journey-4",
1739
+ "journey-6",
1740
+ "journey-7"
1741
+ ],
1742
+ "notes": []
1743
+ },
1744
+ "Checkout abandoned": {
1745
+ "name": "Checkout abandoned",
1746
+ "chart": "Checkout",
1747
+ "description": "Checkout closes and the cart is kept.",
1748
+ "snapshot": "checkout-closed",
1749
+ "confidence": "confirmed",
1750
+ "source": [],
1751
+ "expectedEvents": [],
1752
+ "status": "passed",
1753
+ "screenshot": {
1754
+ "png": "media/paths/journey-5/01.png",
1755
+ "webp": "media/paths/journey-5/01.webp"
1756
+ },
1757
+ "screenshotsByPath": {
1758
+ "journey-5": {
1759
+ "png": "media/paths/journey-5/01.png",
1760
+ "webp": "media/paths/journey-5/01.webp"
1761
+ }
1762
+ },
1763
+ "recognizer": {
1764
+ "matched": true,
1765
+ "signals": [
1766
+ {
1767
+ "signal": "test ID \"checkout-closed\"",
1768
+ "expected": "visible",
1769
+ "visible": true
1770
+ }
1771
+ ]
1772
+ },
1773
+ "looksLike": [],
1774
+ "businessEvents": null,
1775
+ "checks": [
1776
+ {
1777
+ "check": "The screen shows \"Checkout abandoned\"",
1778
+ "passed": true,
1779
+ "expected": "test ID \"checkout-closed\" visible",
1780
+ "actual": "visible"
1781
+ }
1782
+ ],
1783
+ "reachedBy": [
1784
+ "journey-5"
1785
+ ],
1786
+ "notes": []
1787
+ }
1788
+ },
1789
+ "transitions": {
1790
+ "Browsing the menu :: Picks a drink": {
1791
+ "id": "Browsing the menu :: Picks a drink",
1792
+ "source": "Browsing the menu",
1793
+ "target": "Customizing the drink",
1794
+ "event": "Picks a drink",
1795
+ "kind": "user",
1796
+ "how": "The user picks a drink in the app.",
1797
+ "status": "passed",
1798
+ "clip": {
1799
+ "video": "media/clips/journey-1/01.mp4",
1800
+ "poster": "media/clips/journey-1/01.poster.webp",
1801
+ "durationMs": 2500,
1802
+ "captions": "media/captions/001.vtt"
1803
+ },
1804
+ "timeline": [
1805
+ {
1806
+ "atMs": 700,
1807
+ "kind": "tap",
1808
+ "label": "Pick a drink",
1809
+ "x": 71,
1810
+ "y": 579
1811
+ },
1812
+ {
1813
+ "atMs": 2100,
1814
+ "kind": "screen",
1815
+ "label": "Now: Customizing the drink"
1816
+ }
1817
+ ],
1818
+ "reason": null,
1819
+ "reachedBy": [
1820
+ "journey-1",
1821
+ "journey-2",
1822
+ "journey-3",
1823
+ "journey-4",
1824
+ "journey-5",
1825
+ "journey-6",
1826
+ "journey-7",
1827
+ "journey-8",
1828
+ "journey-9"
1829
+ ]
1830
+ },
1831
+ "Choosing a size :: Picks a size": {
1832
+ "id": "Choosing a size :: Picks a size",
1833
+ "source": "Choosing a size",
1834
+ "target": "Choosing the milk",
1835
+ "event": "Picks a size",
1836
+ "kind": "user",
1837
+ "how": "The user picks a size in the app.",
1838
+ "status": "passed",
1839
+ "clip": {
1840
+ "video": "media/clips/journey-1/01.mp4",
1841
+ "poster": "media/clips/journey-1/01.poster.webp",
1842
+ "durationMs": 2500,
1843
+ "captions": "media/captions/002.vtt"
1844
+ },
1845
+ "timeline": [
1846
+ {
1847
+ "atMs": 700,
1848
+ "kind": "tap",
1849
+ "label": "Pick a size",
1850
+ "x": 82,
1851
+ "y": 750
1852
+ },
1853
+ {
1854
+ "atMs": 2100,
1855
+ "kind": "screen",
1856
+ "label": "Now: Choosing the milk"
1857
+ }
1858
+ ],
1859
+ "reason": null,
1860
+ "reachedBy": [
1861
+ "journey-1",
1862
+ "journey-2",
1863
+ "journey-3",
1864
+ "journey-4",
1865
+ "journey-5",
1866
+ "journey-6",
1867
+ "journey-7",
1868
+ "journey-8",
1869
+ "journey-9"
1870
+ ]
1871
+ },
1872
+ "Choosing the milk :: Picks a milk": {
1873
+ "id": "Choosing the milk :: Picks a milk",
1874
+ "source": "Choosing the milk",
1875
+ "target": "Ready to add the drink",
1876
+ "event": "Picks a milk",
1877
+ "kind": "user",
1878
+ "how": "The user picks a milk in the app.",
1879
+ "status": "passed",
1880
+ "clip": {
1881
+ "video": "media/clips/journey-1/01.mp4",
1882
+ "poster": "media/clips/journey-1/01.poster.webp",
1883
+ "durationMs": 2500,
1884
+ "captions": "media/captions/003.vtt"
1885
+ },
1886
+ "timeline": [
1887
+ {
1888
+ "atMs": 700,
1889
+ "kind": "tap",
1890
+ "label": "Pick a milk",
1891
+ "x": 321,
1892
+ "y": 731
1893
+ },
1894
+ {
1895
+ "atMs": 2100,
1896
+ "kind": "screen",
1897
+ "label": "Now: Ready to add the drink"
1898
+ }
1899
+ ],
1900
+ "reason": null,
1901
+ "reachedBy": [
1902
+ "journey-1",
1903
+ "journey-2",
1904
+ "journey-3",
1905
+ "journey-4",
1906
+ "journey-5",
1907
+ "journey-6",
1908
+ "journey-7",
1909
+ "journey-9"
1910
+ ]
1911
+ },
1912
+ "Ready to add the drink :: Adds the drink to the cart": {
1913
+ "id": "Ready to add the drink :: Adds the drink to the cart",
1914
+ "source": "Ready to add the drink",
1915
+ "target": "Reviewing the cart",
1916
+ "event": "Adds the drink to the cart",
1917
+ "kind": "user",
1918
+ "how": "The user adds the drink to the cart in the app.",
1919
+ "status": "passed",
1920
+ "clip": {
1921
+ "video": "media/clips/journey-1/01.mp4",
1922
+ "poster": "media/clips/journey-1/01.poster.webp",
1923
+ "durationMs": 2500,
1924
+ "captions": "media/captions/004.vtt"
1925
+ },
1926
+ "timeline": [
1927
+ {
1928
+ "atMs": 700,
1929
+ "kind": "tap",
1930
+ "label": "Add the drink to the",
1931
+ "x": 342,
1932
+ "y": 687
1933
+ },
1934
+ {
1935
+ "atMs": 2100,
1936
+ "kind": "screen",
1937
+ "label": "Now: Reviewing the cart"
1938
+ }
1939
+ ],
1940
+ "reason": null,
1941
+ "reachedBy": [
1942
+ "journey-1",
1943
+ "journey-2",
1944
+ "journey-3",
1945
+ "journey-4",
1946
+ "journey-5",
1947
+ "journey-6",
1948
+ "journey-7",
1949
+ "journey-9"
1950
+ ]
1951
+ },
1952
+ "Customizing the drink :: Goes back to the menu": {
1953
+ "id": "Customizing the drink :: Goes back to the menu",
1954
+ "source": "Customizing the drink",
1955
+ "target": "Browsing the menu",
1956
+ "event": "Goes back to the menu",
1957
+ "kind": "user",
1958
+ "how": "The user goes back to the menu in the app.",
1959
+ "status": "passed",
1960
+ "clip": {
1961
+ "video": "media/clips/journey-1/01.mp4",
1962
+ "poster": "media/clips/journey-1/01.poster.webp",
1963
+ "durationMs": 2500,
1964
+ "captions": "media/captions/005.vtt"
1965
+ },
1966
+ "timeline": [
1967
+ {
1968
+ "atMs": 700,
1969
+ "kind": "tap",
1970
+ "label": "Go back to the menu",
1971
+ "x": 120,
1972
+ "y": 777
1973
+ },
1974
+ {
1975
+ "atMs": 2100,
1976
+ "kind": "screen",
1977
+ "label": "Now: Browsing the menu"
1978
+ }
1979
+ ],
1980
+ "reason": null,
1981
+ "reachedBy": [
1982
+ "journey-8"
1983
+ ]
1984
+ },
1985
+ "Reviewing the cart :: Removes the last drink": {
1986
+ "id": "Reviewing the cart :: Removes the last drink",
1987
+ "source": "Reviewing the cart",
1988
+ "target": "Browsing the menu",
1989
+ "event": "Removes the last drink",
1990
+ "kind": "user",
1991
+ "how": "The user removes the last drink in the app.",
1992
+ "status": "passed",
1993
+ "clip": {
1994
+ "video": "media/clips/journey-1/01.mp4",
1995
+ "poster": "media/clips/journey-1/01.poster.webp",
1996
+ "durationMs": 2500,
1997
+ "captions": "media/captions/006.vtt"
1998
+ },
1999
+ "timeline": [
2000
+ {
2001
+ "atMs": 700,
2002
+ "kind": "tap",
2003
+ "label": "Remove the last drink",
2004
+ "x": 284,
2005
+ "y": 563
2006
+ },
2007
+ {
2008
+ "atMs": 1700,
2009
+ "kind": "toast",
2010
+ "label": "Removed from the cart."
2011
+ },
2012
+ {
2013
+ "atMs": 2100,
2014
+ "kind": "screen",
2015
+ "label": "Now: Browsing the menu"
2016
+ }
2017
+ ],
2018
+ "reason": null,
2019
+ "reachedBy": [
2020
+ "journey-9"
2021
+ ]
2022
+ },
2023
+ "Reviewing the cart :: Starts checkout": {
2024
+ "id": "Reviewing the cart :: Starts checkout",
2025
+ "source": "Reviewing the cart",
2026
+ "target": "Checking out",
2027
+ "event": "Starts checkout",
2028
+ "kind": "user",
2029
+ "how": "The user starts checkout in the app.",
2030
+ "status": "passed",
2031
+ "clip": {
2032
+ "video": "media/clips/journey-1/01.mp4",
2033
+ "poster": "media/clips/journey-1/01.poster.webp",
2034
+ "durationMs": 2500,
2035
+ "captions": "media/captions/007.vtt"
2036
+ },
2037
+ "timeline": [
2038
+ {
2039
+ "atMs": 700,
2040
+ "kind": "tap",
2041
+ "label": "Start checkout",
2042
+ "x": 57,
2043
+ "y": 738
2044
+ },
2045
+ {
2046
+ "atMs": 2100,
2047
+ "kind": "screen",
2048
+ "label": "Now: Checking out"
2049
+ }
2050
+ ],
2051
+ "reason": null,
2052
+ "reachedBy": [
2053
+ "journey-1",
2054
+ "journey-2",
2055
+ "journey-3",
2056
+ "journey-4",
2057
+ "journey-5",
2058
+ "journey-6",
2059
+ "journey-7"
2060
+ ]
2061
+ },
2062
+ "Paid, waiting for the barista :: Barista starts the drink": {
2063
+ "id": "Paid, waiting for the barista :: Barista starts the drink",
2064
+ "source": "Paid, waiting for the barista",
2065
+ "target": "Drink being made",
2066
+ "event": "Barista starts the drink",
2067
+ "kind": "system",
2068
+ "how": "The fixture sends POST /api/orders/order-fixture-0008/status as Barista display.",
2069
+ "status": "passed",
2070
+ "clip": {
2071
+ "video": "media/clips/journey-1/03.mp4",
2072
+ "poster": "media/clips/journey-1/03.poster.webp",
2073
+ "durationMs": 2500,
2074
+ "captions": "media/captions/008.vtt"
2075
+ },
2076
+ "timeline": [
2077
+ {
2078
+ "atMs": 400,
2079
+ "kind": "note",
2080
+ "label": "The user waits on this screen"
2081
+ },
2082
+ {
2083
+ "atMs": 900,
2084
+ "kind": "system",
2085
+ "label": "Barista starts the drink",
2086
+ "system": {
2087
+ "source": "Barista display",
2088
+ "endpoint": "POST /api/orders/order-fixture-0008/status",
2089
+ "eventType": "order.started",
2090
+ "payload": {
2091
+ "status": "started"
2092
+ },
2093
+ "responseStatus": 200
2094
+ }
2095
+ },
2096
+ {
2097
+ "atMs": 1900,
2098
+ "kind": "screen",
2099
+ "label": "Now: Drink being made"
2100
+ }
2101
+ ],
2102
+ "reason": null,
2103
+ "reachedBy": [
2104
+ "journey-1",
2105
+ "journey-6",
2106
+ "journey-7"
2107
+ ]
2108
+ },
2109
+ "Drink being made :: Barista finishes the drink": {
2110
+ "id": "Drink being made :: Barista finishes the drink",
2111
+ "source": "Drink being made",
2112
+ "target": "Drink ready for pickup",
2113
+ "event": "Barista finishes the drink",
2114
+ "kind": "system",
2115
+ "how": "The fixture sends POST /api/orders/order-fixture-0009/status as Barista display.",
2116
+ "status": "passed",
2117
+ "clip": {
2118
+ "video": "media/clips/journey-1/03.mp4",
2119
+ "poster": "media/clips/journey-1/03.poster.webp",
2120
+ "durationMs": 2500,
2121
+ "captions": "media/captions/009.vtt"
2122
+ },
2123
+ "timeline": [
2124
+ {
2125
+ "atMs": 400,
2126
+ "kind": "note",
2127
+ "label": "The user waits on this screen"
2128
+ },
2129
+ {
2130
+ "atMs": 900,
2131
+ "kind": "system",
2132
+ "label": "Barista finishes the drink",
2133
+ "system": {
2134
+ "source": "Barista display",
2135
+ "endpoint": "POST /api/orders/order-fixture-0009/status",
2136
+ "eventType": "order.finished",
2137
+ "payload": {
2138
+ "status": "finished"
2139
+ },
2140
+ "responseStatus": 200
2141
+ }
2142
+ },
2143
+ {
2144
+ "atMs": 1300,
2145
+ "kind": "notification",
2146
+ "label": "Your drink is ready",
2147
+ "notification": {
2148
+ "channel": "push",
2149
+ "title": "Your drink is ready",
2150
+ "body": "Pick it up at the counter."
2151
+ }
2152
+ },
2153
+ {
2154
+ "atMs": 1900,
2155
+ "kind": "screen",
2156
+ "label": "Now: Drink ready for pickup"
2157
+ }
2158
+ ],
2159
+ "reason": null,
2160
+ "reachedBy": [
2161
+ "journey-1",
2162
+ "journey-6"
2163
+ ]
2164
+ },
2165
+ "Drink ready for pickup :: Picks up the drink": {
2166
+ "id": "Drink ready for pickup :: Picks up the drink",
2167
+ "source": "Drink ready for pickup",
2168
+ "target": "Order complete",
2169
+ "event": "Picks up the drink",
2170
+ "kind": "user",
2171
+ "how": "The user picks up the drink in the app.",
2172
+ "status": "passed",
2173
+ "clip": {
2174
+ "video": "media/clips/journey-1/01.mp4",
2175
+ "poster": "media/clips/journey-1/01.poster.webp",
2176
+ "durationMs": 2500,
2177
+ "captions": "media/captions/010.vtt"
2178
+ },
2179
+ "timeline": [
2180
+ {
2181
+ "atMs": 700,
2182
+ "kind": "tap",
2183
+ "label": "Pick up the drink",
2184
+ "x": 164,
2185
+ "y": 641
2186
+ },
2187
+ {
2188
+ "atMs": 2100,
2189
+ "kind": "screen",
2190
+ "label": "Now: Order complete"
2191
+ }
2192
+ ],
2193
+ "reason": null,
2194
+ "reachedBy": [
2195
+ "journey-1"
2196
+ ]
2197
+ },
2198
+ "Drink ready for pickup :: Drink sits ready for ten minutes": {
2199
+ "id": "Drink ready for pickup :: Drink sits ready for ten minutes",
2200
+ "source": "Drink ready for pickup",
2201
+ "target": "Told the drink was thrown away",
2202
+ "event": "Drink sits ready for ten minutes",
2203
+ "kind": "time",
2204
+ "how": "The test clock jumps forward; nothing in the app is touched.",
2205
+ "status": "passed",
2206
+ "clip": {
2207
+ "video": "media/clips/journey-1/04.mp4",
2208
+ "poster": "media/clips/journey-1/04.poster.webp",
2209
+ "durationMs": 2500,
2210
+ "captions": "media/captions/011.vtt"
2211
+ },
2212
+ "timeline": [
2213
+ {
2214
+ "atMs": 300,
2215
+ "kind": "time",
2216
+ "label": "Drink sits ready for ten minutes",
2217
+ "time": {
2218
+ "from": "2026-10-07T00:40:00.000Z",
2219
+ "to": "2026-10-07T00:50:00.000Z",
2220
+ "fired": [
2221
+ {
2222
+ "at": "2026-10-07T00:45:00.000Z",
2223
+ "label": "Pickup reminder is sent"
2224
+ },
2225
+ {
2226
+ "at": "2026-10-07T00:50:00.000Z",
2227
+ "label": "Unclaimed order check runs"
2228
+ }
2229
+ ]
2230
+ }
2231
+ },
2232
+ {
2233
+ "atMs": 1100,
2234
+ "kind": "notification",
2235
+ "label": "Your order was refunded",
2236
+ "notification": {
2237
+ "channel": "email",
2238
+ "title": "Your order was refunded",
2239
+ "body": "The drink waited too long, so we refunded it."
2240
+ }
2241
+ },
2242
+ {
2243
+ "atMs": 1900,
2244
+ "kind": "screen",
2245
+ "label": "Now: Told the drink was thrown away"
2246
+ }
2247
+ ],
2248
+ "reason": null,
2249
+ "reachedBy": [
2250
+ "journey-6"
2251
+ ]
2252
+ },
2253
+ "Updates on :: Turns off updates": {
2254
+ "id": "Updates on :: Turns off updates",
2255
+ "source": "Updates on",
2256
+ "target": "Updates off",
2257
+ "event": "Turns off updates",
2258
+ "kind": "user",
2259
+ "how": "The user turns off updates in the app.",
2260
+ "status": "passed",
2261
+ "clip": {
2262
+ "video": "media/clips/journey-1/01.mp4",
2263
+ "poster": "media/clips/journey-1/01.poster.webp",
2264
+ "durationMs": 2500,
2265
+ "captions": "media/captions/012.vtt"
2266
+ },
2267
+ "timeline": [
2268
+ {
2269
+ "atMs": 700,
2270
+ "kind": "tap",
2271
+ "label": "Turn off updates",
2272
+ "x": 272,
2273
+ "y": 771
2274
+ },
2275
+ {
2276
+ "atMs": 2100,
2277
+ "kind": "screen",
2278
+ "label": "Now: Updates off"
2279
+ }
2280
+ ],
2281
+ "reason": null,
2282
+ "reachedBy": [
2283
+ "journey-7"
2284
+ ]
2285
+ },
2286
+ "Updates off :: Turns on updates": {
2287
+ "id": "Updates off :: Turns on updates",
2288
+ "source": "Updates off",
2289
+ "target": "Updates on",
2290
+ "event": "Turns on updates",
2291
+ "kind": "user",
2292
+ "how": "The user turns on updates in the app.",
2293
+ "status": "passed",
2294
+ "clip": {
2295
+ "video": "media/clips/journey-1/01.mp4",
2296
+ "poster": "media/clips/journey-1/01.poster.webp",
2297
+ "durationMs": 2500,
2298
+ "captions": "media/captions/013.vtt"
2299
+ },
2300
+ "timeline": [
2301
+ {
2302
+ "atMs": 700,
2303
+ "kind": "tap",
2304
+ "label": "Turn on updates",
2305
+ "x": 185,
2306
+ "y": 736
2307
+ },
2308
+ {
2309
+ "atMs": 2100,
2310
+ "kind": "screen",
2311
+ "label": "Now: Updates on"
2312
+ }
2313
+ ],
2314
+ "reason": null,
2315
+ "reachedBy": [
2316
+ "generated-1"
2317
+ ]
2318
+ },
2319
+ "Told the drink was thrown away :: Orders again": {
2320
+ "id": "Told the drink was thrown away :: Orders again",
2321
+ "source": "Told the drink was thrown away",
2322
+ "target": "Browsing the menu",
2323
+ "event": "Orders again",
2324
+ "kind": "user",
2325
+ "how": "The user orders again in the app.",
2326
+ "status": "passed",
2327
+ "clip": {
2328
+ "video": "media/clips/journey-1/01.mp4",
2329
+ "poster": "media/clips/journey-1/01.poster.webp",
2330
+ "durationMs": 2500,
2331
+ "captions": "media/captions/014.vtt"
2332
+ },
2333
+ "timeline": [
2334
+ {
2335
+ "atMs": 700,
2336
+ "kind": "tap",
2337
+ "label": "Order again",
2338
+ "x": 278,
2339
+ "y": 646
2340
+ },
2341
+ {
2342
+ "atMs": 2100,
2343
+ "kind": "screen",
2344
+ "label": "Now: Browsing the menu"
2345
+ }
2346
+ ],
2347
+ "reason": null,
2348
+ "reachedBy": [
2349
+ "journey-6"
2350
+ ]
2351
+ },
2352
+ "Choosing how to pay :: Picks card": {
2353
+ "id": "Choosing how to pay :: Picks card",
2354
+ "source": "Choosing how to pay",
2355
+ "target": "Entering card details",
2356
+ "event": "Picks card",
2357
+ "kind": "user",
2358
+ "how": "The user picks card in the app.",
2359
+ "status": "passed",
2360
+ "clip": {
2361
+ "video": "media/clips/journey-1/01.mp4",
2362
+ "poster": "media/clips/journey-1/01.poster.webp",
2363
+ "durationMs": 2500,
2364
+ "captions": "media/captions/015.vtt"
2365
+ },
2366
+ "timeline": [
2367
+ {
2368
+ "atMs": 700,
2369
+ "kind": "tap",
2370
+ "label": "Pick card",
2371
+ "x": 331,
2372
+ "y": 749
2373
+ },
2374
+ {
2375
+ "atMs": 2100,
2376
+ "kind": "screen",
2377
+ "label": "Now: Entering card details"
2378
+ }
2379
+ ],
2380
+ "reason": null,
2381
+ "reachedBy": [
2382
+ "journey-1",
2383
+ "journey-3",
2384
+ "journey-4",
2385
+ "journey-6"
2386
+ ]
2387
+ },
2388
+ "Choosing how to pay :: Picks wallet": {
2389
+ "id": "Choosing how to pay :: Picks wallet",
2390
+ "source": "Choosing how to pay",
2391
+ "target": "Confirming with the wallet",
2392
+ "event": "Picks wallet",
2393
+ "kind": "user",
2394
+ "how": "The user picks wallet in the app.",
2395
+ "status": "passed",
2396
+ "clip": {
2397
+ "video": "media/clips/journey-1/01.mp4",
2398
+ "poster": "media/clips/journey-1/01.poster.webp",
2399
+ "durationMs": 2500,
2400
+ "captions": "media/captions/016.vtt"
2401
+ },
2402
+ "timeline": [
2403
+ {
2404
+ "atMs": 700,
2405
+ "kind": "tap",
2406
+ "label": "Pick wallet",
2407
+ "x": 82,
2408
+ "y": 568
2409
+ },
2410
+ {
2411
+ "atMs": 2100,
2412
+ "kind": "screen",
2413
+ "label": "Now: Confirming with the wallet"
2414
+ }
2415
+ ],
2416
+ "reason": null,
2417
+ "reachedBy": [
2418
+ "journey-2",
2419
+ "journey-3",
2420
+ "journey-7"
2421
+ ]
2422
+ },
2423
+ "Choosing how to pay :: Closes checkout": {
2424
+ "id": "Choosing how to pay :: Closes checkout",
2425
+ "source": "Choosing how to pay",
2426
+ "target": "Checkout abandoned",
2427
+ "event": "Closes checkout",
2428
+ "kind": "user",
2429
+ "how": "The user closes checkout in the app.",
2430
+ "status": "passed",
2431
+ "clip": {
2432
+ "video": "media/clips/journey-1/01.mp4",
2433
+ "poster": "media/clips/journey-1/01.poster.webp",
2434
+ "durationMs": 2500,
2435
+ "captions": "media/captions/017.vtt"
2436
+ },
2437
+ "timeline": [
2438
+ {
2439
+ "atMs": 700,
2440
+ "kind": "tap",
2441
+ "label": "Close checkout",
2442
+ "x": 325,
2443
+ "y": 570
2444
+ },
2445
+ {
2446
+ "atMs": 2100,
2447
+ "kind": "screen",
2448
+ "label": "Now: Checkout abandoned"
2449
+ }
2450
+ ],
2451
+ "reason": null,
2452
+ "reachedBy": [
2453
+ "journey-5"
2454
+ ]
2455
+ },
2456
+ "Entering card details :: Submits the card": {
2457
+ "id": "Entering card details :: Submits the card",
2458
+ "source": "Entering card details",
2459
+ "target": "Waiting for the payment",
2460
+ "event": "Submits the card",
2461
+ "kind": "user",
2462
+ "how": "The user submits the card in the app.",
2463
+ "status": "passed",
2464
+ "clip": {
2465
+ "video": "media/clips/journey-1/02.mp4",
2466
+ "poster": "media/clips/journey-1/02.poster.webp",
2467
+ "durationMs": 2500,
2468
+ "captions": "media/captions/018.vtt"
2469
+ },
2470
+ "timeline": [
2471
+ {
2472
+ "atMs": 300,
2473
+ "kind": "tap",
2474
+ "label": "Card number",
2475
+ "x": 195,
2476
+ "y": 308
2477
+ },
2478
+ {
2479
+ "atMs": 650,
2480
+ "kind": "type",
2481
+ "label": "Card number",
2482
+ "text": "4242 4242 4242 4242"
2483
+ },
2484
+ {
2485
+ "atMs": 1500,
2486
+ "kind": "tap",
2487
+ "label": "Submit the card",
2488
+ "x": 59,
2489
+ "y": 631
2490
+ },
2491
+ {
2492
+ "atMs": 2100,
2493
+ "kind": "screen",
2494
+ "label": "Now: Waiting for the payment"
2495
+ }
2496
+ ],
2497
+ "reason": null,
2498
+ "reachedBy": [
2499
+ "journey-1",
2500
+ "journey-3",
2501
+ "journey-4",
2502
+ "journey-6"
2503
+ ]
2504
+ },
2505
+ "Entering card details :: Goes back to the payment options": {
2506
+ "id": "Entering card details :: Goes back to the payment options",
2507
+ "source": "Entering card details",
2508
+ "target": "Choosing how to pay",
2509
+ "event": "Goes back to the payment options",
2510
+ "kind": "user",
2511
+ "how": "The user goes back to the payment options in the app.",
2512
+ "status": "passed",
2513
+ "clip": {
2514
+ "video": "media/clips/journey-1/01.mp4",
2515
+ "poster": "media/clips/journey-1/01.poster.webp",
2516
+ "durationMs": 2500,
2517
+ "captions": "media/captions/019.vtt"
2518
+ },
2519
+ "timeline": [
2520
+ {
2521
+ "atMs": 700,
2522
+ "kind": "tap",
2523
+ "label": "Go back to the payment",
2524
+ "x": 291,
2525
+ "y": 579
2526
+ },
2527
+ {
2528
+ "atMs": 2100,
2529
+ "kind": "screen",
2530
+ "label": "Now: Choosing how to pay"
2531
+ }
2532
+ ],
2533
+ "reason": null,
2534
+ "reachedBy": [
2535
+ "generated-2"
2536
+ ]
2537
+ },
2538
+ "Confirming with the wallet :: Confirms with the wallet": {
2539
+ "id": "Confirming with the wallet :: Confirms with the wallet",
2540
+ "source": "Confirming with the wallet",
2541
+ "target": "Waiting for the payment",
2542
+ "event": "Confirms with the wallet",
2543
+ "kind": "user",
2544
+ "how": "The user confirms with the wallet in the app.",
2545
+ "status": "passed",
2546
+ "clip": {
2547
+ "video": "media/clips/journey-1/01.mp4",
2548
+ "poster": "media/clips/journey-1/01.poster.webp",
2549
+ "durationMs": 2500,
2550
+ "captions": "media/captions/020.vtt"
2551
+ },
2552
+ "timeline": [
2553
+ {
2554
+ "atMs": 700,
2555
+ "kind": "tap",
2556
+ "label": "Confirm with the wallet",
2557
+ "x": 179,
2558
+ "y": 586
2559
+ },
2560
+ {
2561
+ "atMs": 2100,
2562
+ "kind": "screen",
2563
+ "label": "Now: Waiting for the payment"
2564
+ }
2565
+ ],
2566
+ "reason": null,
2567
+ "reachedBy": [
2568
+ "journey-2",
2569
+ "journey-3",
2570
+ "journey-7"
2571
+ ]
2572
+ },
2573
+ "Confirming with the wallet :: Cancels the wallet": {
2574
+ "id": "Confirming with the wallet :: Cancels the wallet",
2575
+ "source": "Confirming with the wallet",
2576
+ "target": "Choosing how to pay",
2577
+ "event": "Cancels the wallet",
2578
+ "kind": "user",
2579
+ "how": "The user cancels the wallet in the app.",
2580
+ "status": "passed",
2581
+ "clip": {
2582
+ "video": "media/clips/journey-1/01.mp4",
2583
+ "poster": "media/clips/journey-1/01.poster.webp",
2584
+ "durationMs": 2500,
2585
+ "captions": "media/captions/021.vtt"
2586
+ },
2587
+ "timeline": [
2588
+ {
2589
+ "atMs": 700,
2590
+ "kind": "tap",
2591
+ "label": "Cancel the wallet",
2592
+ "x": 286,
2593
+ "y": 704
2594
+ },
2595
+ {
2596
+ "atMs": 2100,
2597
+ "kind": "screen",
2598
+ "label": "Now: Choosing how to pay"
2599
+ }
2600
+ ],
2601
+ "reason": null,
2602
+ "reachedBy": [
2603
+ "generated-2"
2604
+ ]
2605
+ },
2606
+ "Waiting for the payment :: Payment provider approves the payment": {
2607
+ "id": "Waiting for the payment :: Payment provider approves the payment",
2608
+ "source": "Waiting for the payment",
2609
+ "target": "Paid",
2610
+ "event": "Payment provider approves the payment",
2611
+ "kind": "system",
2612
+ "how": "The fixture sends POST /webhooks/payments as Payment provider webhook.",
2613
+ "status": "passed",
2614
+ "clip": {
2615
+ "video": "media/clips/journey-1/03.mp4",
2616
+ "poster": "media/clips/journey-1/03.poster.webp",
2617
+ "durationMs": 2500,
2618
+ "captions": "media/captions/022.vtt"
2619
+ },
2620
+ "timeline": [
2621
+ {
2622
+ "atMs": 400,
2623
+ "kind": "note",
2624
+ "label": "The user waits on this screen"
2625
+ },
2626
+ {
2627
+ "atMs": 900,
2628
+ "kind": "system",
2629
+ "label": "Payment provider approves the payment",
2630
+ "system": {
2631
+ "source": "Payment provider webhook",
2632
+ "endpoint": "POST /webhooks/payments",
2633
+ "eventType": "payment.approved",
2634
+ "payload": {
2635
+ "type": "payment.approved",
2636
+ "data": {
2637
+ "paymentId": "pay_fixture_0022",
2638
+ "status": "approved"
2639
+ }
2640
+ },
2641
+ "responseStatus": 200
2642
+ }
2643
+ },
2644
+ {
2645
+ "atMs": 1300,
2646
+ "kind": "notification",
2647
+ "label": "Approved",
2648
+ "notification": {
2649
+ "channel": "push",
2650
+ "title": "Approved",
2651
+ "body": "Next: paid."
2652
+ }
2653
+ },
2654
+ {
2655
+ "atMs": 1900,
2656
+ "kind": "screen",
2657
+ "label": "Now: Paid"
2658
+ }
2659
+ ],
2660
+ "reason": null,
2661
+ "reachedBy": [
2662
+ "journey-1",
2663
+ "journey-2",
2664
+ "journey-3",
2665
+ "journey-4",
2666
+ "journey-6",
2667
+ "journey-7"
2668
+ ]
2669
+ },
2670
+ "Waiting for the payment :: Payment provider declines the payment": {
2671
+ "id": "Waiting for the payment :: Payment provider declines the payment",
2672
+ "source": "Waiting for the payment",
2673
+ "target": "Told the payment was declined",
2674
+ "event": "Payment provider declines the payment",
2675
+ "kind": "system",
2676
+ "how": "The fixture sends POST /webhooks/payments as Payment provider webhook.",
2677
+ "status": "passed",
2678
+ "clip": {
2679
+ "video": "media/clips/journey-1/03.mp4",
2680
+ "poster": "media/clips/journey-1/03.poster.webp",
2681
+ "durationMs": 2500,
2682
+ "captions": "media/captions/023.vtt"
2683
+ },
2684
+ "timeline": [
2685
+ {
2686
+ "atMs": 400,
2687
+ "kind": "note",
2688
+ "label": "The user waits on this screen"
2689
+ },
2690
+ {
2691
+ "atMs": 900,
2692
+ "kind": "system",
2693
+ "label": "Payment provider declines the payment",
2694
+ "system": {
2695
+ "source": "Payment provider webhook",
2696
+ "endpoint": "POST /webhooks/payments",
2697
+ "eventType": "payment.declined",
2698
+ "payload": {
2699
+ "type": "payment.declined",
2700
+ "data": {
2701
+ "paymentId": "pay_fixture_0023",
2702
+ "status": "declined"
2703
+ }
2704
+ },
2705
+ "responseStatus": 200
2706
+ }
2707
+ },
2708
+ {
2709
+ "atMs": 1300,
2710
+ "kind": "notification",
2711
+ "label": "Payment declined",
2712
+ "notification": {
2713
+ "channel": "in-app",
2714
+ "title": "Payment declined",
2715
+ "body": "Try another way to pay."
2716
+ }
2717
+ },
2718
+ {
2719
+ "atMs": 1900,
2720
+ "kind": "screen",
2721
+ "label": "Now: Told the payment was declined"
2722
+ }
2723
+ ],
2724
+ "reason": null,
2725
+ "reachedBy": [
2726
+ "journey-3"
2727
+ ]
2728
+ },
2729
+ "Waiting for the payment :: Payment takes longer than a minute": {
2730
+ "id": "Waiting for the payment :: Payment takes longer than a minute",
2731
+ "source": "Waiting for the payment",
2732
+ "target": "Told the payment is slow",
2733
+ "event": "Payment takes longer than a minute",
2734
+ "kind": "time",
2735
+ "how": "The test clock jumps forward; nothing in the app is touched.",
2736
+ "status": "passed",
2737
+ "clip": {
2738
+ "video": "media/clips/journey-1/04.mp4",
2739
+ "poster": "media/clips/journey-1/04.poster.webp",
2740
+ "durationMs": 2500,
2741
+ "captions": "media/captions/024.vtt"
2742
+ },
2743
+ "timeline": [
2744
+ {
2745
+ "atMs": 300,
2746
+ "kind": "time",
2747
+ "label": "Payment takes longer than a minute",
2748
+ "time": {
2749
+ "from": "2026-10-07T13:40:00.000Z",
2750
+ "to": "2026-10-07T13:41:10.000Z",
2751
+ "fired": [
2752
+ {
2753
+ "at": "2026-10-07T13:41:10.000Z",
2754
+ "label": "Payment status check runs"
2755
+ }
2756
+ ]
2757
+ }
2758
+ },
2759
+ {
2760
+ "atMs": 1100,
2761
+ "kind": "notification",
2762
+ "label": "Still waiting on your payment",
2763
+ "notification": {
2764
+ "channel": "in-app",
2765
+ "title": "Still waiting on your payment",
2766
+ "body": "This can take a little longer."
2767
+ }
2768
+ },
2769
+ {
2770
+ "atMs": 1900,
2771
+ "kind": "screen",
2772
+ "label": "Now: Told the payment is slow"
2773
+ }
2774
+ ],
2775
+ "reason": null,
2776
+ "reachedBy": [
2777
+ "journey-4"
2778
+ ]
2779
+ },
2780
+ "Told the payment is slow :: Checks the payment again": {
2781
+ "id": "Told the payment is slow :: Checks the payment again",
2782
+ "source": "Told the payment is slow",
2783
+ "target": "Waiting for the payment",
2784
+ "event": "Checks the payment again",
2785
+ "kind": "user",
2786
+ "how": "The user checks the payment again in the app.",
2787
+ "status": "passed",
2788
+ "clip": {
2789
+ "video": "media/clips/journey-1/01.mp4",
2790
+ "poster": "media/clips/journey-1/01.poster.webp",
2791
+ "durationMs": 2500,
2792
+ "captions": "media/captions/025.vtt"
2793
+ },
2794
+ "timeline": [
2795
+ {
2796
+ "atMs": 700,
2797
+ "kind": "tap",
2798
+ "label": "Check the payment again",
2799
+ "x": 244,
2800
+ "y": 621
2801
+ },
2802
+ {
2803
+ "atMs": 2100,
2804
+ "kind": "screen",
2805
+ "label": "Now: Waiting for the payment"
2806
+ }
2807
+ ],
2808
+ "reason": null,
2809
+ "reachedBy": [
2810
+ "journey-4"
2811
+ ]
2812
+ },
2813
+ "Told the payment was declined :: Tries another way to pay": {
2814
+ "id": "Told the payment was declined :: Tries another way to pay",
2815
+ "source": "Told the payment was declined",
2816
+ "target": "Choosing how to pay",
2817
+ "event": "Tries another way to pay",
2818
+ "kind": "user",
2819
+ "how": "The user tries another way to pay in the app.",
2820
+ "status": "passed",
2821
+ "clip": {
2822
+ "video": "media/clips/journey-1/01.mp4",
2823
+ "poster": "media/clips/journey-1/01.poster.webp",
2824
+ "durationMs": 2500,
2825
+ "captions": "media/captions/026.vtt"
2826
+ },
2827
+ "timeline": [
2828
+ {
2829
+ "atMs": 700,
2830
+ "kind": "tap",
2831
+ "label": "Try another way to pay",
2832
+ "x": 195,
2833
+ "y": 565
2834
+ },
2835
+ {
2836
+ "atMs": 2100,
2837
+ "kind": "screen",
2838
+ "label": "Now: Choosing how to pay"
2839
+ }
2840
+ ],
2841
+ "reason": null,
2842
+ "reachedBy": [
2843
+ "journey-3"
2844
+ ]
2845
+ },
2846
+ "Paid :: Payment goes through": {
2847
+ "id": "Paid :: Payment goes through",
2848
+ "source": "Paid",
2849
+ "target": "Order in progress",
2850
+ "event": "Payment goes through",
2851
+ "kind": "hand-off",
2852
+ "how": "The child chart reached an end, so the parent chart moves on.",
2853
+ "status": "passed",
2854
+ "clip": {
2855
+ "video": "media/clips/journey-1/03.mp4",
2856
+ "poster": "media/clips/journey-1/03.poster.webp",
2857
+ "durationMs": 2500,
2858
+ "captions": "media/captions/027.vtt"
2859
+ },
2860
+ "timeline": [
2861
+ {
2862
+ "atMs": 200,
2863
+ "kind": "note",
2864
+ "label": "Checkout is done and hands back with \"Payment goes through\""
2865
+ },
2866
+ {
2867
+ "atMs": 700,
2868
+ "kind": "screen",
2869
+ "label": "Now: Order in progress"
2870
+ }
2871
+ ],
2872
+ "reason": null,
2873
+ "reachedBy": [
2874
+ "journey-1",
2875
+ "journey-2",
2876
+ "journey-3",
2877
+ "journey-4",
2878
+ "journey-6",
2879
+ "journey-7"
2880
+ ]
2881
+ },
2882
+ "Checkout abandoned :: Leaves checkout": {
2883
+ "id": "Checkout abandoned :: Leaves checkout",
2884
+ "source": "Checkout abandoned",
2885
+ "target": "Reviewing the cart",
2886
+ "event": "Leaves checkout",
2887
+ "kind": "hand-off",
2888
+ "how": "The child chart reached an end, so the parent chart moves on.",
2889
+ "status": "passed",
2890
+ "clip": {
2891
+ "video": "media/clips/journey-1/03.mp4",
2892
+ "poster": "media/clips/journey-1/03.poster.webp",
2893
+ "durationMs": 2500,
2894
+ "captions": "media/captions/028.vtt"
2895
+ },
2896
+ "timeline": [
2897
+ {
2898
+ "atMs": 200,
2899
+ "kind": "note",
2900
+ "label": "Checkout is done and hands back with \"Leaves checkout\""
2901
+ },
2902
+ {
2903
+ "atMs": 700,
2904
+ "kind": "screen",
2905
+ "label": "Now: Reviewing the cart"
2906
+ }
2907
+ ],
2908
+ "reason": null,
2909
+ "reachedBy": [
2910
+ "journey-5"
2911
+ ]
2912
+ }
2913
+ },
2914
+ "paths": [
2915
+ {
2916
+ "id": "journey-1",
2917
+ "name": "Orders a drink and pays by card",
2918
+ "kind": "journey",
2919
+ "description": "The everyday order, from the menu to picking the drink up.",
2920
+ "status": "passed",
2921
+ "attempts": [
2922
+ {
2923
+ "status": "passed",
2924
+ "error": null,
2925
+ "stoppedAt": null,
2926
+ "trace": null
2927
+ }
2928
+ ],
2929
+ "steps": [
2930
+ {
2931
+ "transition": "Browsing the menu :: Picks a drink",
2932
+ "event": "Picks a drink",
2933
+ "status": "passed",
2934
+ "reason": null
2935
+ },
2936
+ {
2937
+ "transition": "Choosing a size :: Picks a size",
2938
+ "event": "Picks a size",
2939
+ "status": "passed",
2940
+ "reason": null
2941
+ },
2942
+ {
2943
+ "transition": "Choosing the milk :: Picks a milk",
2944
+ "event": "Picks a milk",
2945
+ "status": "passed",
2946
+ "reason": null
2947
+ },
2948
+ {
2949
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
2950
+ "event": "Adds the drink to the cart",
2951
+ "status": "passed",
2952
+ "reason": null
2953
+ },
2954
+ {
2955
+ "transition": "Reviewing the cart :: Starts checkout",
2956
+ "event": "Starts checkout",
2957
+ "status": "passed",
2958
+ "reason": null
2959
+ },
2960
+ {
2961
+ "transition": "Choosing how to pay :: Picks card",
2962
+ "event": "Picks card",
2963
+ "status": "passed",
2964
+ "reason": null
2965
+ },
2966
+ {
2967
+ "transition": "Entering card details :: Submits the card",
2968
+ "event": "Submits the card",
2969
+ "status": "passed",
2970
+ "reason": null
2971
+ },
2972
+ {
2973
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
2974
+ "event": "Payment provider approves the payment",
2975
+ "status": "passed",
2976
+ "reason": null
2977
+ },
2978
+ {
2979
+ "transition": "Paid :: Payment goes through",
2980
+ "event": "Payment goes through",
2981
+ "status": "passed",
2982
+ "reason": null
2983
+ },
2984
+ {
2985
+ "transition": "Paid, waiting for the barista :: Barista starts the drink",
2986
+ "event": "Barista starts the drink",
2987
+ "status": "passed",
2988
+ "reason": null
2989
+ },
2990
+ {
2991
+ "transition": "Drink being made :: Barista finishes the drink",
2992
+ "event": "Barista finishes the drink",
2993
+ "status": "passed",
2994
+ "reason": null
2995
+ },
2996
+ {
2997
+ "transition": "Drink ready for pickup :: Picks up the drink",
2998
+ "event": "Picks up the drink",
2999
+ "status": "passed",
3000
+ "reason": null
3001
+ }
3002
+ ],
3003
+ "stoppedAt": null
3004
+ },
3005
+ {
3006
+ "id": "journey-2",
3007
+ "name": "Pays with a wallet",
3008
+ "kind": "journey",
3009
+ "description": "The wallet confirms the payment instead of a card.",
3010
+ "status": "passed",
3011
+ "attempts": [
3012
+ {
3013
+ "status": "passed",
3014
+ "error": null,
3015
+ "stoppedAt": null,
3016
+ "trace": null
3017
+ }
3018
+ ],
3019
+ "steps": [
3020
+ {
3021
+ "transition": "Browsing the menu :: Picks a drink",
3022
+ "event": "Picks a drink",
3023
+ "status": "passed",
3024
+ "reason": null
3025
+ },
3026
+ {
3027
+ "transition": "Choosing a size :: Picks a size",
3028
+ "event": "Picks a size",
3029
+ "status": "passed",
3030
+ "reason": null
3031
+ },
3032
+ {
3033
+ "transition": "Choosing the milk :: Picks a milk",
3034
+ "event": "Picks a milk",
3035
+ "status": "passed",
3036
+ "reason": null
3037
+ },
3038
+ {
3039
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3040
+ "event": "Adds the drink to the cart",
3041
+ "status": "passed",
3042
+ "reason": null
3043
+ },
3044
+ {
3045
+ "transition": "Reviewing the cart :: Starts checkout",
3046
+ "event": "Starts checkout",
3047
+ "status": "passed",
3048
+ "reason": null
3049
+ },
3050
+ {
3051
+ "transition": "Choosing how to pay :: Picks wallet",
3052
+ "event": "Picks wallet",
3053
+ "status": "passed",
3054
+ "reason": null
3055
+ },
3056
+ {
3057
+ "transition": "Confirming with the wallet :: Confirms with the wallet",
3058
+ "event": "Confirms with the wallet",
3059
+ "status": "passed",
3060
+ "reason": null
3061
+ },
3062
+ {
3063
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
3064
+ "event": "Payment provider approves the payment",
3065
+ "status": "passed",
3066
+ "reason": null
3067
+ },
3068
+ {
3069
+ "transition": "Paid :: Payment goes through",
3070
+ "event": "Payment goes through",
3071
+ "status": "passed",
3072
+ "reason": null
3073
+ }
3074
+ ],
3075
+ "stoppedAt": null
3076
+ },
3077
+ {
3078
+ "id": "journey-3",
3079
+ "name": "Card declined, then a wallet works",
3080
+ "kind": "journey",
3081
+ "description": "The card is declined and the wallet goes through.",
3082
+ "status": "passed",
3083
+ "attempts": [
3084
+ {
3085
+ "status": "passed",
3086
+ "error": null,
3087
+ "stoppedAt": null,
3088
+ "trace": null
3089
+ }
3090
+ ],
3091
+ "steps": [
3092
+ {
3093
+ "transition": "Browsing the menu :: Picks a drink",
3094
+ "event": "Picks a drink",
3095
+ "status": "passed",
3096
+ "reason": null
3097
+ },
3098
+ {
3099
+ "transition": "Choosing a size :: Picks a size",
3100
+ "event": "Picks a size",
3101
+ "status": "passed",
3102
+ "reason": null
3103
+ },
3104
+ {
3105
+ "transition": "Choosing the milk :: Picks a milk",
3106
+ "event": "Picks a milk",
3107
+ "status": "passed",
3108
+ "reason": null
3109
+ },
3110
+ {
3111
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3112
+ "event": "Adds the drink to the cart",
3113
+ "status": "passed",
3114
+ "reason": null
3115
+ },
3116
+ {
3117
+ "transition": "Reviewing the cart :: Starts checkout",
3118
+ "event": "Starts checkout",
3119
+ "status": "passed",
3120
+ "reason": null
3121
+ },
3122
+ {
3123
+ "transition": "Choosing how to pay :: Picks card",
3124
+ "event": "Picks card",
3125
+ "status": "passed",
3126
+ "reason": null
3127
+ },
3128
+ {
3129
+ "transition": "Entering card details :: Submits the card",
3130
+ "event": "Submits the card",
3131
+ "status": "passed",
3132
+ "reason": null
3133
+ },
3134
+ {
3135
+ "transition": "Waiting for the payment :: Payment provider declines the payment",
3136
+ "event": "Payment provider declines the payment",
3137
+ "status": "passed",
3138
+ "reason": null
3139
+ },
3140
+ {
3141
+ "transition": "Told the payment was declined :: Tries another way to pay",
3142
+ "event": "Tries another way to pay",
3143
+ "status": "passed",
3144
+ "reason": null
3145
+ },
3146
+ {
3147
+ "transition": "Choosing how to pay :: Picks wallet",
3148
+ "event": "Picks wallet",
3149
+ "status": "passed",
3150
+ "reason": null
3151
+ },
3152
+ {
3153
+ "transition": "Confirming with the wallet :: Confirms with the wallet",
3154
+ "event": "Confirms with the wallet",
3155
+ "status": "passed",
3156
+ "reason": null
3157
+ },
3158
+ {
3159
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
3160
+ "event": "Payment provider approves the payment",
3161
+ "status": "passed",
3162
+ "reason": null
3163
+ },
3164
+ {
3165
+ "transition": "Paid :: Payment goes through",
3166
+ "event": "Payment goes through",
3167
+ "status": "passed",
3168
+ "reason": null
3169
+ }
3170
+ ],
3171
+ "stoppedAt": null
3172
+ },
3173
+ {
3174
+ "id": "journey-4",
3175
+ "name": "Slow payment",
3176
+ "kind": "journey",
3177
+ "description": "The payment provider takes more than a minute to answer.",
3178
+ "status": "passed",
3179
+ "attempts": [
3180
+ {
3181
+ "status": "passed",
3182
+ "error": null,
3183
+ "stoppedAt": null,
3184
+ "trace": null
3185
+ }
3186
+ ],
3187
+ "steps": [
3188
+ {
3189
+ "transition": "Browsing the menu :: Picks a drink",
3190
+ "event": "Picks a drink",
3191
+ "status": "passed",
3192
+ "reason": null
3193
+ },
3194
+ {
3195
+ "transition": "Choosing a size :: Picks a size",
3196
+ "event": "Picks a size",
3197
+ "status": "passed",
3198
+ "reason": null
3199
+ },
3200
+ {
3201
+ "transition": "Choosing the milk :: Picks a milk",
3202
+ "event": "Picks a milk",
3203
+ "status": "passed",
3204
+ "reason": null
3205
+ },
3206
+ {
3207
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3208
+ "event": "Adds the drink to the cart",
3209
+ "status": "passed",
3210
+ "reason": null
3211
+ },
3212
+ {
3213
+ "transition": "Reviewing the cart :: Starts checkout",
3214
+ "event": "Starts checkout",
3215
+ "status": "passed",
3216
+ "reason": null
3217
+ },
3218
+ {
3219
+ "transition": "Choosing how to pay :: Picks card",
3220
+ "event": "Picks card",
3221
+ "status": "passed",
3222
+ "reason": null
3223
+ },
3224
+ {
3225
+ "transition": "Entering card details :: Submits the card",
3226
+ "event": "Submits the card",
3227
+ "status": "passed",
3228
+ "reason": null
3229
+ },
3230
+ {
3231
+ "transition": "Waiting for the payment :: Payment takes longer than a minute",
3232
+ "event": "Payment takes longer than a minute",
3233
+ "status": "passed",
3234
+ "reason": null
3235
+ },
3236
+ {
3237
+ "transition": "Told the payment is slow :: Checks the payment again",
3238
+ "event": "Checks the payment again",
3239
+ "status": "passed",
3240
+ "reason": null
3241
+ },
3242
+ {
3243
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
3244
+ "event": "Payment provider approves the payment",
3245
+ "status": "passed",
3246
+ "reason": null
3247
+ },
3248
+ {
3249
+ "transition": "Paid :: Payment goes through",
3250
+ "event": "Payment goes through",
3251
+ "status": "passed",
3252
+ "reason": null
3253
+ }
3254
+ ],
3255
+ "stoppedAt": null
3256
+ },
3257
+ {
3258
+ "id": "journey-5",
3259
+ "name": "Leaves checkout and comes back",
3260
+ "kind": "journey",
3261
+ "description": "The customer closes checkout, then starts it again.",
3262
+ "status": "passed",
3263
+ "attempts": [
3264
+ {
3265
+ "status": "passed",
3266
+ "error": null,
3267
+ "stoppedAt": null,
3268
+ "trace": null
3269
+ }
3270
+ ],
3271
+ "steps": [
3272
+ {
3273
+ "transition": "Browsing the menu :: Picks a drink",
3274
+ "event": "Picks a drink",
3275
+ "status": "passed",
3276
+ "reason": null
3277
+ },
3278
+ {
3279
+ "transition": "Choosing a size :: Picks a size",
3280
+ "event": "Picks a size",
3281
+ "status": "passed",
3282
+ "reason": null
3283
+ },
3284
+ {
3285
+ "transition": "Choosing the milk :: Picks a milk",
3286
+ "event": "Picks a milk",
3287
+ "status": "passed",
3288
+ "reason": null
3289
+ },
3290
+ {
3291
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3292
+ "event": "Adds the drink to the cart",
3293
+ "status": "passed",
3294
+ "reason": null
3295
+ },
3296
+ {
3297
+ "transition": "Reviewing the cart :: Starts checkout",
3298
+ "event": "Starts checkout",
3299
+ "status": "passed",
3300
+ "reason": null
3301
+ },
3302
+ {
3303
+ "transition": "Choosing how to pay :: Closes checkout",
3304
+ "event": "Closes checkout",
3305
+ "status": "passed",
3306
+ "reason": null
3307
+ },
3308
+ {
3309
+ "transition": "Checkout abandoned :: Leaves checkout",
3310
+ "event": "Leaves checkout",
3311
+ "status": "passed",
3312
+ "reason": null
3313
+ },
3314
+ {
3315
+ "transition": "Reviewing the cart :: Starts checkout",
3316
+ "event": "Starts checkout",
3317
+ "status": "passed",
3318
+ "reason": null
3319
+ }
3320
+ ],
3321
+ "stoppedAt": null
3322
+ },
3323
+ {
3324
+ "id": "journey-6",
3325
+ "name": "Drink left too long",
3326
+ "kind": "journey",
3327
+ "description": "Nobody picks the drink up, so it is thrown away and refunded.",
3328
+ "status": "passed",
3329
+ "attempts": [
3330
+ {
3331
+ "status": "passed",
3332
+ "error": null,
3333
+ "stoppedAt": null,
3334
+ "trace": null
3335
+ }
3336
+ ],
3337
+ "steps": [
3338
+ {
3339
+ "transition": "Browsing the menu :: Picks a drink",
3340
+ "event": "Picks a drink",
3341
+ "status": "passed",
3342
+ "reason": null
3343
+ },
3344
+ {
3345
+ "transition": "Choosing a size :: Picks a size",
3346
+ "event": "Picks a size",
3347
+ "status": "passed",
3348
+ "reason": null
3349
+ },
3350
+ {
3351
+ "transition": "Choosing the milk :: Picks a milk",
3352
+ "event": "Picks a milk",
3353
+ "status": "passed",
3354
+ "reason": null
3355
+ },
3356
+ {
3357
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3358
+ "event": "Adds the drink to the cart",
3359
+ "status": "passed",
3360
+ "reason": null
3361
+ },
3362
+ {
3363
+ "transition": "Reviewing the cart :: Starts checkout",
3364
+ "event": "Starts checkout",
3365
+ "status": "passed",
3366
+ "reason": null
3367
+ },
3368
+ {
3369
+ "transition": "Choosing how to pay :: Picks card",
3370
+ "event": "Picks card",
3371
+ "status": "passed",
3372
+ "reason": null
3373
+ },
3374
+ {
3375
+ "transition": "Entering card details :: Submits the card",
3376
+ "event": "Submits the card",
3377
+ "status": "passed",
3378
+ "reason": null
3379
+ },
3380
+ {
3381
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
3382
+ "event": "Payment provider approves the payment",
3383
+ "status": "passed",
3384
+ "reason": null
3385
+ },
3386
+ {
3387
+ "transition": "Paid :: Payment goes through",
3388
+ "event": "Payment goes through",
3389
+ "status": "passed",
3390
+ "reason": null
3391
+ },
3392
+ {
3393
+ "transition": "Paid, waiting for the barista :: Barista starts the drink",
3394
+ "event": "Barista starts the drink",
3395
+ "status": "passed",
3396
+ "reason": null
3397
+ },
3398
+ {
3399
+ "transition": "Drink being made :: Barista finishes the drink",
3400
+ "event": "Barista finishes the drink",
3401
+ "status": "passed",
3402
+ "reason": null
3403
+ },
3404
+ {
3405
+ "transition": "Drink ready for pickup :: Drink sits ready for ten minutes",
3406
+ "event": "Drink sits ready for ten minutes",
3407
+ "status": "passed",
3408
+ "reason": null
3409
+ },
3410
+ {
3411
+ "transition": "Told the drink was thrown away :: Orders again",
3412
+ "event": "Orders again",
3413
+ "status": "passed",
3414
+ "reason": null
3415
+ }
3416
+ ],
3417
+ "stoppedAt": null
3418
+ },
3419
+ {
3420
+ "id": "journey-7",
3421
+ "name": "Turns off updates while waiting",
3422
+ "kind": "journey",
3423
+ "description": "Updates go off while the drink is in the queue; the drink is still made.",
3424
+ "status": "passed",
3425
+ "attempts": [
3426
+ {
3427
+ "status": "passed",
3428
+ "error": null,
3429
+ "stoppedAt": null,
3430
+ "trace": null
3431
+ }
3432
+ ],
3433
+ "steps": [
3434
+ {
3435
+ "transition": "Browsing the menu :: Picks a drink",
3436
+ "event": "Picks a drink",
3437
+ "status": "passed",
3438
+ "reason": null
3439
+ },
3440
+ {
3441
+ "transition": "Choosing a size :: Picks a size",
3442
+ "event": "Picks a size",
3443
+ "status": "passed",
3444
+ "reason": null
3445
+ },
3446
+ {
3447
+ "transition": "Choosing the milk :: Picks a milk",
3448
+ "event": "Picks a milk",
3449
+ "status": "passed",
3450
+ "reason": null
3451
+ },
3452
+ {
3453
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3454
+ "event": "Adds the drink to the cart",
3455
+ "status": "passed",
3456
+ "reason": null
3457
+ },
3458
+ {
3459
+ "transition": "Reviewing the cart :: Starts checkout",
3460
+ "event": "Starts checkout",
3461
+ "status": "passed",
3462
+ "reason": null
3463
+ },
3464
+ {
3465
+ "transition": "Choosing how to pay :: Picks wallet",
3466
+ "event": "Picks wallet",
3467
+ "status": "passed",
3468
+ "reason": null
3469
+ },
3470
+ {
3471
+ "transition": "Confirming with the wallet :: Confirms with the wallet",
3472
+ "event": "Confirms with the wallet",
3473
+ "status": "passed",
3474
+ "reason": null
3475
+ },
3476
+ {
3477
+ "transition": "Waiting for the payment :: Payment provider approves the payment",
3478
+ "event": "Payment provider approves the payment",
3479
+ "status": "passed",
3480
+ "reason": null
3481
+ },
3482
+ {
3483
+ "transition": "Paid :: Payment goes through",
3484
+ "event": "Payment goes through",
3485
+ "status": "passed",
3486
+ "reason": null
3487
+ },
3488
+ {
3489
+ "transition": "Updates on :: Turns off updates",
3490
+ "event": "Turns off updates",
3491
+ "status": "passed",
3492
+ "reason": null
3493
+ },
3494
+ {
3495
+ "transition": "Paid, waiting for the barista :: Barista starts the drink",
3496
+ "event": "Barista starts the drink",
3497
+ "status": "passed",
3498
+ "reason": null
3499
+ }
3500
+ ],
3501
+ "stoppedAt": null
3502
+ },
3503
+ {
3504
+ "id": "journey-8",
3505
+ "name": "Changes their mind about the drink",
3506
+ "kind": "journey",
3507
+ "description": "The customer backs out while choosing the drink.",
3508
+ "status": "passed",
3509
+ "attempts": [
3510
+ {
3511
+ "status": "passed",
3512
+ "error": null,
3513
+ "stoppedAt": null,
3514
+ "trace": null
3515
+ }
3516
+ ],
3517
+ "steps": [
3518
+ {
3519
+ "transition": "Browsing the menu :: Picks a drink",
3520
+ "event": "Picks a drink",
3521
+ "status": "passed",
3522
+ "reason": null
3523
+ },
3524
+ {
3525
+ "transition": "Choosing a size :: Picks a size",
3526
+ "event": "Picks a size",
3527
+ "status": "passed",
3528
+ "reason": null
3529
+ },
3530
+ {
3531
+ "transition": "Customizing the drink :: Goes back to the menu",
3532
+ "event": "Goes back to the menu",
3533
+ "status": "passed",
3534
+ "reason": null
3535
+ }
3536
+ ],
3537
+ "stoppedAt": null
3538
+ },
3539
+ {
3540
+ "id": "journey-9",
3541
+ "name": "Empties the cart",
3542
+ "kind": "journey",
3543
+ "description": "The only drink is removed from the cart.",
3544
+ "status": "passed",
3545
+ "attempts": [
3546
+ {
3547
+ "status": "passed",
3548
+ "error": null,
3549
+ "stoppedAt": null,
3550
+ "trace": null
3551
+ }
3552
+ ],
3553
+ "steps": [
3554
+ {
3555
+ "transition": "Browsing the menu :: Picks a drink",
3556
+ "event": "Picks a drink",
3557
+ "status": "passed",
3558
+ "reason": null
3559
+ },
3560
+ {
3561
+ "transition": "Choosing a size :: Picks a size",
3562
+ "event": "Picks a size",
3563
+ "status": "passed",
3564
+ "reason": null
3565
+ },
3566
+ {
3567
+ "transition": "Choosing the milk :: Picks a milk",
3568
+ "event": "Picks a milk",
3569
+ "status": "passed",
3570
+ "reason": null
3571
+ },
3572
+ {
3573
+ "transition": "Ready to add the drink :: Adds the drink to the cart",
3574
+ "event": "Adds the drink to the cart",
3575
+ "status": "passed",
3576
+ "reason": null
3577
+ },
3578
+ {
3579
+ "transition": "Reviewing the cart :: Removes the last drink",
3580
+ "event": "Removes the last drink",
3581
+ "status": "passed",
3582
+ "reason": null
3583
+ }
3584
+ ],
3585
+ "stoppedAt": null
3586
+ },
3587
+ {
3588
+ "id": "generated-1",
3589
+ "name": "Every other event in Coffee order",
3590
+ "kind": "generated",
3591
+ "description": "Generated to reach the 1 events in \"Coffee order\" that no named journey takes.",
3592
+ "status": "passed",
3593
+ "attempts": [
3594
+ {
3595
+ "status": "passed",
3596
+ "error": null,
3597
+ "stoppedAt": null,
3598
+ "trace": null
3599
+ }
3600
+ ],
3601
+ "steps": [
3602
+ {
3603
+ "transition": "Updates off :: Turns on updates",
3604
+ "event": "Turns on updates",
3605
+ "status": "passed",
3606
+ "reason": null
3607
+ }
3608
+ ],
3609
+ "stoppedAt": null
3610
+ },
3611
+ {
3612
+ "id": "generated-2",
3613
+ "name": "Every other event in Checkout",
3614
+ "kind": "generated",
3615
+ "description": "Generated to reach the 2 events in \"Checkout\" that no named journey takes.",
3616
+ "status": "passed",
3617
+ "attempts": [
3618
+ {
3619
+ "status": "passed",
3620
+ "error": null,
3621
+ "stoppedAt": null,
3622
+ "trace": null
3623
+ }
3624
+ ],
3625
+ "steps": [
3626
+ {
3627
+ "transition": "Entering card details :: Goes back to the payment options",
3628
+ "event": "Goes back to the payment options",
3629
+ "status": "passed",
3630
+ "reason": null
3631
+ },
3632
+ {
3633
+ "transition": "Confirming with the wallet :: Cancels the wallet",
3634
+ "event": "Cancels the wallet",
3635
+ "status": "passed",
3636
+ "reason": null
3637
+ }
3638
+ ],
3639
+ "stoppedAt": null
3640
+ }
3641
+ ],
3642
+ "coverage": {
3643
+ "Coffee order": {
3644
+ "states": {
3645
+ "total": 17,
3646
+ "passed": 17,
3647
+ "failed": 0,
3648
+ "flaky": 0,
3649
+ "notReached": 0
3650
+ },
3651
+ "transitions": {
3652
+ "total": 14,
3653
+ "passed": 14,
3654
+ "failed": 0,
3655
+ "flaky": 0,
3656
+ "notReached": 0
3657
+ }
3658
+ },
3659
+ "Checkout": {
3660
+ "states": {
3661
+ "total": 8,
3662
+ "passed": 8,
3663
+ "failed": 0,
3664
+ "flaky": 0,
3665
+ "notReached": 0
3666
+ },
3667
+ "transitions": {
3668
+ "total": 14,
3669
+ "passed": 14,
3670
+ "failed": 0,
3671
+ "flaky": 0,
3672
+ "notReached": 0
3673
+ }
3674
+ },
3675
+ "overall": {
3676
+ "states": {
3677
+ "total": 25,
3678
+ "passed": 25,
3679
+ "failed": 0,
3680
+ "flaky": 0,
3681
+ "notReached": 0
3682
+ },
3683
+ "transitions": {
3684
+ "total": 28,
3685
+ "passed": 28,
3686
+ "failed": 0,
3687
+ "flaky": 0,
3688
+ "notReached": 0
3689
+ }
3690
+ }
3691
+ },
3692
+ "privacy": {
3693
+ "passed": true,
3694
+ "findings": []
3695
+ },
3696
+ "reports": {
3697
+ "junit": "junit.xml",
3698
+ "ctrf": "ctrf.json",
3699
+ "mermaid": "chart.mmd"
3700
+ }
3701
+ }