@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.
- package/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +649 -2
- package/dist/bun/src/driver.d.ts +67 -0
- package/dist/bun/src/driver.js +90 -0
- package/dist/bun/src/index.d.ts +2 -0
- package/dist/bun/src/index.js +2 -0
- package/dist/core/src/cli.d.ts +1 -0
- package/dist/core/src/cli.js +177 -0
- package/dist/core/src/config.d.ts +477 -0
- package/dist/core/src/config.js +100 -0
- package/dist/core/src/events/cloudevents.d.ts +56 -0
- package/dist/core/src/events/cloudevents.js +152 -0
- package/dist/core/src/graph.d.ts +113 -0
- package/dist/core/src/graph.js +221 -0
- package/dist/core/src/index.d.ts +17 -0
- package/dist/core/src/index.js +17 -0
- package/dist/core/src/lint.d.ts +53 -0
- package/dist/core/src/lint.js +138 -0
- package/dist/core/src/plan.d.ts +109 -0
- package/dist/core/src/plan.js +324 -0
- package/dist/core/src/privacy.d.ts +8 -0
- package/dist/core/src/privacy.js +42 -0
- package/dist/core/src/report/formats.d.ts +69 -0
- package/dist/core/src/report/formats.js +109 -0
- package/dist/core/src/report/markdown.d.ts +8 -0
- package/dist/core/src/report/markdown.js +140 -0
- package/dist/core/src/run/clients.d.ts +42 -0
- package/dist/core/src/run/clients.js +250 -0
- package/dist/core/src/run/execute.d.ts +854 -0
- package/dist/core/src/run/execute.js +877 -0
- package/dist/core/src/run/frames.d.ts +16 -0
- package/dist/core/src/run/frames.js +52 -0
- package/dist/core/src/run/http.d.ts +41 -0
- package/dist/core/src/run/http.js +71 -0
- package/dist/core/src/run/types.d.ts +248 -0
- package/dist/core/src/run/types.js +39 -0
- package/dist/core/src/signals.d.ts +110 -0
- package/dist/core/src/signals.js +121 -0
- package/dist/core/src/spec/compose.d.ts +28 -0
- package/dist/core/src/spec/compose.js +71 -0
- package/dist/core/src/spec/index.d.ts +5 -0
- package/dist/core/src/spec/index.js +5 -0
- package/dist/core/src/spec/load.d.ts +8 -0
- package/dist/core/src/spec/load.js +46 -0
- package/dist/core/src/spec/parse.d.ts +5 -0
- package/dist/core/src/spec/parse.js +32 -0
- package/dist/core/src/spec/scxml.d.ts +19 -0
- package/dist/core/src/spec/scxml.js +239 -0
- package/dist/core/src/spec/types.d.ts +96 -0
- package/dist/core/src/spec/types.js +25 -0
- package/dist/detox/src/index.d.ts +75 -0
- package/dist/detox/src/index.js +110 -0
- package/dist/playwright/src/driver.d.ts +44 -0
- package/dist/playwright/src/driver.js +82 -0
- package/dist/playwright/src/index.d.ts +3 -0
- package/dist/playwright/src/index.js +3 -0
- package/dist/playwright/src/media.d.ts +68 -0
- package/dist/playwright/src/media.js +283 -0
- package/dist/playwright/src/signals.d.ts +34 -0
- package/dist/playwright/src/signals.js +56 -0
- package/dist/reports/src/browser-navigation.d.ts +2 -0
- package/dist/reports/src/browser-navigation.js +28 -0
- package/dist/reports/src/bundle.d.ts +24 -0
- package/dist/reports/src/bundle.js +114 -0
- package/dist/reports/src/catalog.d.ts +37 -0
- package/dist/reports/src/catalog.js +127 -0
- package/dist/reports/src/clock.d.ts +14 -0
- package/dist/reports/src/clock.js +4 -0
- package/dist/reports/src/completion-order.d.ts +10 -0
- package/dist/reports/src/completion-order.js +76 -0
- package/dist/reports/src/evidence-live.d.ts +40 -0
- package/dist/reports/src/evidence-live.js +118 -0
- package/dist/reports/src/evidence-types.d.ts +90 -0
- package/dist/reports/src/evidence-types.js +15 -0
- package/dist/reports/src/evidence-view.d.ts +68 -0
- package/dist/reports/src/evidence-view.js +113 -0
- package/dist/reports/src/explorer-types.d.ts +56 -0
- package/dist/reports/src/explorer-types.js +0 -0
- package/dist/reports/src/explorer-versions.d.ts +4 -0
- package/dist/reports/src/explorer-versions.js +21 -0
- package/dist/reports/src/export-evidence.d.ts +11 -0
- package/dist/reports/src/export-evidence.js +94 -0
- package/dist/reports/src/fetcher.d.ts +50 -0
- package/dist/reports/src/fetcher.js +205 -0
- package/dist/reports/src/format-date.d.ts +1 -0
- package/dist/reports/src/format-date.js +10 -0
- package/dist/reports/src/format.d.ts +16 -0
- package/dist/reports/src/format.js +71 -0
- package/dist/reports/src/frames.d.ts +46 -0
- package/dist/reports/src/frames.js +245 -0
- package/dist/reports/src/hash.d.ts +17 -0
- package/dist/reports/src/hash.js +43 -0
- package/dist/reports/src/html-frame.d.ts +13 -0
- package/dist/reports/src/html-frame.js +63 -0
- package/dist/reports/src/http.d.ts +3 -0
- package/dist/reports/src/http.js +0 -0
- package/dist/reports/src/junit.d.ts +23 -0
- package/dist/reports/src/junit.js +119 -0
- package/dist/reports/src/keyboard.d.ts +16 -0
- package/dist/reports/src/keyboard.js +135 -0
- package/dist/reports/src/keys.d.ts +53 -0
- package/dist/reports/src/keys.js +122 -0
- package/dist/reports/src/layer-catalog.d.ts +5 -0
- package/dist/reports/src/layer-catalog.js +39 -0
- package/dist/reports/src/layer-merge.d.ts +43 -0
- package/dist/reports/src/layer-merge.js +154 -0
- package/dist/reports/src/layer-source.d.ts +6 -0
- package/dist/reports/src/layer-source.js +32 -0
- package/dist/reports/src/layer-store.d.ts +10 -0
- package/dist/reports/src/layer-store.js +36 -0
- package/dist/reports/src/layer-types.d.ts +32 -0
- package/dist/reports/src/layer-types.js +0 -0
- package/dist/reports/src/layers-route.d.ts +20 -0
- package/dist/reports/src/layers-route.js +259 -0
- package/dist/reports/src/namespace-guard.d.ts +11 -0
- package/dist/reports/src/namespace-guard.js +40 -0
- package/dist/reports/src/navigation.d.ts +8 -0
- package/dist/reports/src/navigation.js +0 -0
- package/dist/reports/src/object-io.d.ts +9 -0
- package/dist/reports/src/object-io.js +41 -0
- package/dist/reports/src/object-store.d.ts +67 -0
- package/dist/reports/src/object-store.js +32 -0
- package/dist/reports/src/performance-part.d.ts +9 -0
- package/dist/reports/src/performance-part.js +42 -0
- package/dist/reports/src/performance.d.ts +13 -0
- package/dist/reports/src/performance.js +45 -0
- package/dist/reports/src/persist.d.ts +10 -0
- package/dist/reports/src/persist.js +38 -0
- package/dist/reports/src/phone.d.ts +5 -0
- package/dist/reports/src/phone.js +18 -0
- package/dist/reports/src/protocol.d.ts +78 -0
- package/dist/reports/src/protocol.js +36 -0
- package/dist/reports/src/publication.d.ts +4 -0
- package/dist/reports/src/publication.js +35 -0
- package/dist/reports/src/publish.d.ts +52 -0
- package/dist/reports/src/publish.js +189 -0
- package/dist/reports/src/read.d.ts +62 -0
- package/dist/reports/src/read.js +214 -0
- package/dist/reports/src/recording-bundle.d.ts +22 -0
- package/dist/reports/src/recording-bundle.js +4 -0
- package/dist/reports/src/recording-keys.d.ts +9 -0
- package/dist/reports/src/recording-keys.js +50 -0
- package/dist/reports/src/remote-report.d.ts +39 -0
- package/dist/reports/src/remote-report.js +304 -0
- package/dist/reports/src/report-loader.d.ts +22 -0
- package/dist/reports/src/report-loader.js +0 -0
- package/dist/reports/src/report-parts.d.ts +10 -0
- package/dist/reports/src/report-parts.js +112 -0
- package/dist/reports/src/report-types.d.ts +194 -0
- package/dist/reports/src/report-types.js +29 -0
- package/dist/reports/src/reports-explorer-route.d.ts +90 -0
- package/dist/reports/src/reports-explorer-route.js +65 -0
- package/dist/reports/src/reports-list-route.d.ts +23 -0
- package/dist/reports/src/reports-list-route.js +55 -0
- package/dist/reports/src/reports-route.d.ts +267 -0
- package/dist/reports/src/reports-route.js +204 -0
- package/dist/reports/src/reports-store.d.ts +11 -0
- package/dist/reports/src/reports-store.js +28 -0
- package/dist/reports/src/resilient-cache.d.ts +3 -0
- package/dist/reports/src/resilient-cache.js +33 -0
- package/dist/reports/src/retention.d.ts +9 -0
- package/dist/reports/src/retention.js +16 -0
- package/dist/reports/src/scenario.d.ts +15 -0
- package/dist/reports/src/scenario.js +35 -0
- package/dist/reports/src/snapshot-bundle.d.ts +18 -0
- package/dist/reports/src/snapshot-bundle.js +94 -0
- package/dist/reports/src/snapshot-surface.d.ts +29 -0
- package/dist/reports/src/snapshot-surface.js +339 -0
- package/dist/reports/src/source-content.d.ts +30 -0
- package/dist/reports/src/source-content.js +63 -0
- package/dist/reports/src/source-entries.d.ts +4 -0
- package/dist/reports/src/source-entries.js +34 -0
- package/dist/reports/src/source-part.d.ts +4 -0
- package/dist/reports/src/source-part.js +66 -0
- package/dist/reports/src/source-reader.d.ts +6 -0
- package/dist/reports/src/source-reader.js +17 -0
- package/dist/reports/src/spec-evidence.d.ts +6 -0
- package/dist/reports/src/spec-evidence.js +20 -0
- package/dist/reports/src/spec-inventory.d.ts +14 -0
- package/dist/reports/src/spec-inventory.js +75 -0
- package/dist/reports/src/status.d.ts +4 -0
- package/dist/reports/src/status.js +8 -0
- package/dist/reports/src/store-prefix.d.ts +21 -0
- package/dist/reports/src/store-prefix.js +53 -0
- package/dist/reports/src/test-catalog-entity.d.ts +3 -0
- package/dist/reports/src/test-catalog-entity.js +34 -0
- package/dist/reports/src/types.d.ts +5 -0
- package/dist/reports/src/types.js +0 -0
- package/dist/reports/src/use-report-nav.d.ts +25 -0
- package/dist/reports/src/use-report-nav.js +181 -0
- package/dist/schema/src/common.d.ts +57 -0
- package/dist/schema/src/common.js +32 -0
- package/dist/schema/src/index.d.ts +5 -0
- package/dist/schema/src/index.js +5 -0
- package/dist/schema/src/manifest.d.ts +457 -0
- package/dist/schema/src/manifest.js +247 -0
- package/dist/schema/src/report-sources.d.ts +68 -0
- package/dist/schema/src/report-sources.js +53 -0
- package/dist/schema/src/runs-index.d.ts +52 -0
- package/dist/schema/src/runs-index.js +24 -0
- package/dist/schema/src/spec.d.ts +245 -0
- package/dist/schema/src/spec.js +133 -0
- package/dist/vitest/src/index.d.ts +22 -0
- package/dist/vitest/src/index.js +33 -0
- package/dist/webdriver/src/driver.d.ts +69 -0
- package/dist/webdriver/src/driver.js +230 -0
- package/dist/webdriver/src/index.d.ts +11 -0
- package/dist/webdriver/src/index.js +10 -0
- package/dist/webdriver/src/protocol.d.ts +60 -0
- package/dist/webdriver/src/protocol.js +146 -0
- package/package.json +181 -4
- package/packages/bun/README.md +69 -0
- package/packages/core/README.md +78 -0
- package/packages/core/bin/atlas.mjs +8 -0
- package/packages/detox/README.md +73 -0
- package/packages/playwright/README.md +77 -0
- package/packages/reports/README.md +47 -0
- package/packages/reports/STORAGE.md +73 -0
- package/packages/schema/README.md +23 -0
- package/packages/schema/schemas/atlas-change.schema.json +34 -0
- package/packages/schema/schemas/atlas.schema.json +32 -0
- package/packages/schema/schemas/cloud-event.schema.json +40 -0
- package/packages/schema/schemas/journeys.schema.json +17 -0
- package/packages/schema/schemas/manifest.schema.json +160 -0
- package/packages/schema/schemas/path-record.schema.json +151 -0
- package/packages/schema/schemas/report-sources.schema.json +95 -0
- package/packages/schema/schemas/run-info.schema.json +176 -0
- package/packages/schema/schemas/run-summary.schema.json +206 -0
- package/packages/schema/schemas/runs-index.schema.json +23 -0
- package/packages/schema/schemas/state-node.schema.json +238 -0
- package/packages/schema/schemas/state-record.schema.json +354 -0
- package/packages/schema/schemas/timeline-entry.schema.json +124 -0
- package/packages/schema/schemas/transition-record.schema.json +125 -0
- package/packages/visualizer/README.md +154 -0
- package/packages/visualizer/bin/atlas-visualizer.mjs +176 -0
- package/packages/visualizer/example/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/example/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/example/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/example/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/example/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +245 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +12 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +2003 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +17 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +17 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +17 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +13 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/failed-01.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
- package/packages/visualizer/fixtures/failures/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/fixtures/failures/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/chart.mmd +67 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/ctrf.json +247 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/junit.xml +12 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-02T09-10-00-000Z-fast/manifest.json +1875 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/chart.mmd +67 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/ctrf.json +244 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/junit.xml +12 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/manifest.json +1977 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/001.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/002.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/003.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/004.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/005.vtt +17 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/captions/006.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-04T16-20-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +472 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +16 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +3701 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/006.vtt +13 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/007.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/008.vtt +13 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/009.vtt +17 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/010.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/011.vtt +13 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/012.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/013.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/014.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/015.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/016.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/017.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/018.vtt +17 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/019.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/020.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/021.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/022.vtt +17 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/023.vtt +17 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/024.vtt +13 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/025.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/026.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/027.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/028.vtt +9 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.mp4 +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/04.poster.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/06.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/07.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/08.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/09.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/10.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/11.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/12.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/13.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/14.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-4/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-5/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-6/01.webp +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.png +0 -0
- package/packages/visualizer/fixtures/full/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-7/01.webp +0 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/fixtures/full/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/ctrf.json +1280 -0
- package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/junit.xml +26 -0
- package/packages/visualizer/fixtures/large/runs/2026-10-06T14-40-00-000Z-fast/manifest.json +28393 -0
- package/packages/visualizer/fixtures/large/specs/accounts/sign-up/identity-check.machine.yaml +397 -0
- package/packages/visualizer/fixtures/large/specs/accounts/sign-up/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/large/specs/accounts/sign-up/machine.yaml +830 -0
- package/packages/visualizer/fixtures/large/specs/atlas.yaml +65 -0
- package/packages/visualizer/fixtures/large/specs/billing/invoices/journeys.yaml +132 -0
- package/packages/visualizer/fixtures/large/specs/billing/invoices/machine.yaml +830 -0
- package/packages/visualizer/fixtures/large/specs/billing/invoices/refund-handling.scxml +288 -0
- package/packages/visualizer/fixtures/large/specs/catalog/browsing/journeys.yaml +126 -0
- package/packages/visualizer/fixtures/large/specs/catalog/browsing/machine.yaml +831 -0
- package/packages/visualizer/fixtures/large/specs/catalog/browsing/product-comparison.machine.yaml +395 -0
- package/packages/visualizer/fixtures/large/specs/orders/checkout/journeys.yaml +120 -0
- package/packages/visualizer/fixtures/large/specs/orders/checkout/machine.yaml +724 -0
- package/packages/visualizer/fixtures/large/specs/orders/checkout/open-questions.md +16 -0
- package/packages/visualizer/fixtures/large/specs/orders/checkout/payment.scxml +288 -0
- package/packages/visualizer/fixtures/large/specs/shipping/deliveries/delivery-scheduling.machine.yaml +397 -0
- package/packages/visualizer/fixtures/large/specs/shipping/deliveries/journeys.yaml +132 -0
- package/packages/visualizer/fixtures/large/specs/shipping/deliveries/known-issues.md +13 -0
- package/packages/visualizer/fixtures/large/specs/shipping/deliveries/machine.yaml +830 -0
- package/packages/visualizer/fixtures/large/specs/support/tickets/escalation.machine.yaml +395 -0
- package/packages/visualizer/fixtures/large/specs/support/tickets/journeys.yaml +123 -0
- package/packages/visualizer/fixtures/large/specs/support/tickets/machine.yaml +720 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T10-00-00-000Z-showcase/manifest.json +68 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/ctrf.json +50 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/junit.xml +6 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T11-00-00-000Z-showcase/manifest.json +1281 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/ctrf.json +50 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/junit.xml +6 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T12-00-00-000Z-showcase/manifest.json +1232 -0
- package/packages/visualizer/fixtures/malformed/runs/2026-10-06T13-00-00-000Z-showcase/manifest.json +1244 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/journeys.yaml +134 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/loyalty.scxml +4 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/machine.yaml +156 -0
- package/packages/visualizer/fixtures/malformed/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/chart.mmd +67 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +149 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +9 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1718 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +17 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +17 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +9 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/005.vtt +9 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.mp4 +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/03.poster.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/05.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-3/01.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/00-start-01.webp +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/partial/runs/2026-10-06T15-05-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/fixtures/partial/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/ctrf.json +79 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/junit.xml +7 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/manifest.json +1504 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/001.vtt +9 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/002.vtt +9 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/003.vtt +9 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/captions/004.vtt +17 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.mp4 +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/01.poster.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.mp4 +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/clips/journey-1/02.poster.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.png +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/01.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.png +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/02.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.png +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/03.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.png +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-1/04.webp +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.png +0 -0
- package/packages/visualizer/fixtures/removed/runs/2026-10-06T14-40-00-000Z-showcase/media/paths/journey-2/01.webp +0 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/fixtures/removed/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/fixtures/spec-only/runs/.gitkeep +0 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/checkout.scxml +82 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/journeys.yaml +129 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/known-issues.md +14 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/machine.yaml +158 -0
- package/packages/visualizer/fixtures/spec-only/specs/coffee/ordering/open-questions.md +25 -0
- package/packages/visualizer/index.html +13 -0
- package/packages/visualizer/scripts/make-fixtures.ts +1490 -0
- package/packages/visualizer/scripts/publish-data.ts +22 -0
- package/packages/visualizer/src/app/AppShell.tsx +56 -0
- package/packages/visualizer/src/app/atlas-context.tsx +23 -0
- package/packages/visualizer/src/app/gazetteer.module.css +97 -0
- package/packages/visualizer/src/app/gazetteer.tsx +105 -0
- package/packages/visualizer/src/app/report-sources.tsx +122 -0
- package/packages/visualizer/src/app/router.tsx +69 -0
- package/packages/visualizer/src/app/search-query.tsx +14 -0
- package/packages/visualizer/src/components/DataIssues.module.css +136 -0
- package/packages/visualizer/src/components/DataIssues.tsx +70 -0
- package/packages/visualizer/src/components/Header.module.css +189 -0
- package/packages/visualizer/src/components/Header.tsx +127 -0
- package/packages/visualizer/src/components/Legend.module.css +84 -0
- package/packages/visualizer/src/components/Legend.tsx +50 -0
- package/packages/visualizer/src/components/Screen.module.css +312 -0
- package/packages/visualizer/src/components/Screen.tsx +141 -0
- package/packages/visualizer/src/components/Status.module.css +116 -0
- package/packages/visualizer/src/components/Status.tsx +60 -0
- package/packages/visualizer/src/components/icons.tsx +156 -0
- package/packages/visualizer/src/components/labels.tsx +22 -0
- package/packages/visualizer/src/data/adapters/adapter.ts +112 -0
- package/packages/visualizer/src/data/adapters/context.tsx +11 -0
- package/packages/visualizer/src/data/adapters/index.ts +29 -0
- package/packages/visualizer/src/data/adapters/report-backend.test.ts +96 -0
- package/packages/visualizer/src/data/adapters/report-backend.ts +42 -0
- package/packages/visualizer/src/data/fixtures.test.ts +407 -0
- package/packages/visualizer/src/data/model/build.ts +418 -0
- package/packages/visualizer/src/data/model/event-kind.test.ts +59 -0
- package/packages/visualizer/src/data/model/event-kind.ts +54 -0
- package/packages/visualizer/src/data/model/index.ts +3 -0
- package/packages/visualizer/src/data/model/journeys.test.ts +159 -0
- package/packages/visualizer/src/data/model/journeys.ts +29 -0
- package/packages/visualizer/src/data/model/simulation.test.ts +115 -0
- package/packages/visualizer/src/data/model/simulation.ts +187 -0
- package/packages/visualizer/src/data/model/status.test.ts +34 -0
- package/packages/visualizer/src/data/model/status.ts +43 -0
- package/packages/visualizer/src/data/model/types.ts +280 -0
- package/packages/visualizer/src/data/parse/issues.test.ts +82 -0
- package/packages/visualizer/src/data/parse/issues.ts +114 -0
- package/packages/visualizer/src/data/parse/manifest.ts +173 -0
- package/packages/visualizer/src/data/parse/markdown.test.ts +119 -0
- package/packages/visualizer/src/data/parse/markdown.ts +133 -0
- package/packages/visualizer/src/data/parse/spec.test.ts +106 -0
- package/packages/visualizer/src/data/parse/spec.ts +557 -0
- package/packages/visualizer/src/data/parse/structured.ts +44 -0
- package/packages/visualizer/src/data/queries.ts +369 -0
- package/packages/visualizer/src/data/testing/load-fixture.ts +63 -0
- package/packages/visualizer/src/evidence/api.ts +41 -0
- package/packages/visualizer/src/evidence/check-detail.tsx +257 -0
- package/packages/visualizer/src/evidence/decision-table.tsx +68 -0
- package/packages/visualizer/src/evidence/document-page.tsx +40 -0
- package/packages/visualizer/src/evidence/evidence-context.tsx +159 -0
- package/packages/visualizer/src/evidence/evidence.module.css +877 -0
- package/packages/visualizer/src/evidence/feature-page.tsx +88 -0
- package/packages/visualizer/src/evidence/format.ts +56 -0
- package/packages/visualizer/src/evidence/gherkin.ts +98 -0
- package/packages/visualizer/src/evidence/marks.tsx +118 -0
- package/packages/visualizer/src/evidence/model-page.tsx +60 -0
- package/packages/visualizer/src/evidence/model-trace.tsx +57 -0
- package/packages/visualizer/src/evidence/overview.tsx +134 -0
- package/packages/visualizer/src/evidence/quint.ts +45 -0
- package/packages/visualizer/src/evidence/recording-page.tsx +69 -0
- package/packages/visualizer/src/evidence/recording.module.css +464 -0
- package/packages/visualizer/src/evidence/recording.tsx +197 -0
- package/packages/visualizer/src/evidence/snapshot.tsx +108 -0
- package/packages/visualizer/src/evidence/sources-panel.tsx +134 -0
- package/packages/visualizer/src/evidence/sources.module.css +168 -0
- package/packages/visualizer/src/evidence/spec-header.tsx +64 -0
- package/packages/visualizer/src/evidence/spec-index.tsx +82 -0
- package/packages/visualizer/src/evidence/spec-page.tsx +92 -0
- package/packages/visualizer/src/evidence/spec-snapshot.tsx +26 -0
- package/packages/visualizer/src/layout/graph.test.ts +113 -0
- package/packages/visualizer/src/layout/graph.ts +324 -0
- package/packages/visualizer/src/layout/layout.ts +237 -0
- package/packages/visualizer/src/layout/use-chart-layout.ts +18 -0
- package/packages/visualizer/src/main.tsx +31 -0
- package/packages/visualizer/src/map/ChartMap.tsx +252 -0
- package/packages/visualizer/src/map/EventEdge.tsx +138 -0
- package/packages/visualizer/src/map/map.module.css +546 -0
- package/packages/visualizer/src/map/nodes.tsx +145 -0
- package/packages/visualizer/src/map/path.ts +24 -0
- package/packages/visualizer/src/reachable.test.ts +54 -0
- package/packages/visualizer/src/spec-kind.test.ts +27 -0
- package/packages/visualizer/src/spec-kind.ts +56 -0
- package/packages/visualizer/src/state/ui-store.ts +44 -0
- package/packages/visualizer/src/styles/global.css +105 -0
- package/packages/visualizer/src/styles/tokens.css +80 -0
- package/packages/visualizer/src/views/ChartPage.tsx +52 -0
- package/packages/visualizer/src/views/ProductPage.tsx +35 -0
- package/packages/visualizer/src/views/SidePanel.tsx +339 -0
- package/packages/visualizer/src/views/views.module.css +546 -0
- package/packages/visualizer/vite/atlas-dev-plugin.ts +169 -0
- package/packages/visualizer/vite/atlas-files.test.ts +119 -0
- package/packages/visualizer/vite/atlas-files.ts +199 -0
- package/packages/visualizer/vite/publish.test.ts +52 -0
- package/packages/visualizer/vite/publish.ts +99 -0
- package/packages/visualizer/vite/reports-dev-plugin.ts +82 -0
- package/packages/visualizer/vite.config.ts +13 -0
- package/packages/vitest/README.md +58 -0
- package/packages/webdriver/README.md +77 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { createServer } from 'node:net';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { recordFrames } from '../../core/src/index.js';
|
|
6
|
+
import { DOM_PROBE, describeSignal, signatureScreen, toWire } from '../../core/src/signals.js';
|
|
7
|
+
import { waitForServer, WebDriverSession } from './protocol.js';
|
|
8
|
+
function inferMode(capabilities) {
|
|
9
|
+
if (capabilities.browserName)
|
|
10
|
+
return 'web';
|
|
11
|
+
const native = ['appium:app', 'appium:bundleId', 'appium:appPackage', 'appium:appActivity'].some((k) => k in capabilities);
|
|
12
|
+
return native || /^(ios|android)$/i.test(String(capabilities.platformName ?? '')) ? 'native' : 'web';
|
|
13
|
+
}
|
|
14
|
+
const xpathLiteral = (value) => {
|
|
15
|
+
if (!value.includes("'"))
|
|
16
|
+
return `'${value}'`;
|
|
17
|
+
if (!value.includes('"'))
|
|
18
|
+
return `"${value}"`;
|
|
19
|
+
return `concat(${value
|
|
20
|
+
.split("'")
|
|
21
|
+
.map((part) => `'${part}'`)
|
|
22
|
+
.join(`, "'", `)})`;
|
|
23
|
+
};
|
|
24
|
+
/** iOS (XCUITest) and Android (UiAutomator2) element types for the common roles. */
|
|
25
|
+
const NATIVE_ROLES = {
|
|
26
|
+
button: ['XCUIElementTypeButton', 'android.widget.Button', 'android.widget.ImageButton'],
|
|
27
|
+
textbox: ['XCUIElementTypeTextField', 'XCUIElementTypeSecureTextField', 'XCUIElementTypeTextView', 'android.widget.EditText'],
|
|
28
|
+
checkbox: ['XCUIElementTypeSwitch', 'android.widget.CheckBox', 'android.widget.Switch'],
|
|
29
|
+
switch: ['XCUIElementTypeSwitch', 'android.widget.Switch'],
|
|
30
|
+
link: ['XCUIElementTypeLink'],
|
|
31
|
+
img: ['XCUIElementTypeImage', 'android.widget.ImageView'],
|
|
32
|
+
heading: []
|
|
33
|
+
};
|
|
34
|
+
const TEXT_ATTRIBUTES = ['label', 'name', 'value', 'text', 'content-desc'];
|
|
35
|
+
/** A signal as a native locator: test IDs are accessibility identifiers, text is any label, value or text. */
|
|
36
|
+
export function nativeLocator(signal) {
|
|
37
|
+
const name = describeSignal(signal);
|
|
38
|
+
if ('testId' in signal)
|
|
39
|
+
return { using: 'accessibility id', value: signal.testId, name };
|
|
40
|
+
if ('css' in signal)
|
|
41
|
+
throw new Error(`${name}: CSS selectors only work in web sessions`);
|
|
42
|
+
const match = 'label' in signal ? signal.label : 'role' in signal ? signal.name : signal.text;
|
|
43
|
+
const exact = 'exact' in signal && signal.exact === true;
|
|
44
|
+
if (match instanceof RegExp)
|
|
45
|
+
return null;
|
|
46
|
+
const types = 'role' in signal ? (NATIVE_ROLES[signal.role] ?? []) : [];
|
|
47
|
+
const typeTest = types.length ? `(${types.map((t) => `self::${t}`).join(' or ')})` : '';
|
|
48
|
+
const attributes = 'label' in signal ? ['label', 'name', 'content-desc', 'hint'] : TEXT_ATTRIBUTES;
|
|
49
|
+
const textTest = match === undefined ? '' : `(${attributes.map((a) => (exact ? `@${a}=${xpathLiteral(match)}` : `contains(@${a}, ${xpathLiteral(match)})`)).join(' or ')})`;
|
|
50
|
+
const tests = [typeTest, textTest].filter(Boolean).join(' and ');
|
|
51
|
+
return { using: 'xpath', value: `//*${tests ? `[${tests}]` : ''}`, name };
|
|
52
|
+
}
|
|
53
|
+
/** Elements of an Appium page source whose text attributes match a pattern and that are shown. */
|
|
54
|
+
function sourceMatches(source, pattern) {
|
|
55
|
+
const results = [];
|
|
56
|
+
for (const tag of source.matchAll(/<([\w.]+)((?:\s+[\w:-]+="[^"]*")*)\s*\/?>/g)) {
|
|
57
|
+
const attributes = Object.fromEntries([...(tag[2] ?? '').matchAll(/([\w:-]+)="([^"]*)"/g)].map((m) => [m[1], m[2]]));
|
|
58
|
+
if (attributes.visible === 'false' || attributes.displayed === 'false')
|
|
59
|
+
continue;
|
|
60
|
+
if (TEXT_ATTRIBUTES.some((a) => attributes[a] !== undefined && pattern.test(attributes[a])))
|
|
61
|
+
results.push(attributes);
|
|
62
|
+
}
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
const isLocator = (target) => 'using' in target;
|
|
66
|
+
const describe = (target) => (isLocator(target) ? (target.name ?? `${target.using} ${target.value}`) : describeSignal(target));
|
|
67
|
+
async function freePort() {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
const probe = createServer();
|
|
70
|
+
probe.once('error', reject);
|
|
71
|
+
probe.listen(0, '127.0.0.1', () => {
|
|
72
|
+
const address = probe.address();
|
|
73
|
+
const port = typeof address === 'object' && address ? address.port : 0;
|
|
74
|
+
probe.close(() => resolve(port));
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function contextFor(session, mode, baseUrl, timeline, timeoutMs) {
|
|
79
|
+
const resolve = async (target) => {
|
|
80
|
+
if (isLocator(target)) {
|
|
81
|
+
for (const element of await session.findElements(target))
|
|
82
|
+
if (await session.isDisplayed(element).catch(() => false))
|
|
83
|
+
return element;
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (mode === 'web') {
|
|
87
|
+
const found = (await session.execute(`return (${DOM_PROBE})(arguments[0], arguments[1], true)`, [toWire(target), true]));
|
|
88
|
+
return found?.visible ? session.elementId(found.element) : null;
|
|
89
|
+
}
|
|
90
|
+
const locator = nativeLocator(target);
|
|
91
|
+
if (locator)
|
|
92
|
+
return resolve(locator);
|
|
93
|
+
const pattern = 'label' in target ? target.label : 'role' in target ? target.name : 'text' in target ? target.text : undefined;
|
|
94
|
+
if (!(pattern instanceof RegExp))
|
|
95
|
+
return null;
|
|
96
|
+
const [first] = sourceMatches(await session.source(), pattern);
|
|
97
|
+
const key = first && TEXT_ATTRIBUTES.find((a) => first[a] !== undefined && pattern.test(first[a]));
|
|
98
|
+
return key ? resolve({ using: 'xpath', value: `//*[@${key}=${xpathLiteral(first[key])}]` }) : null;
|
|
99
|
+
};
|
|
100
|
+
const waitFor = async (target) => {
|
|
101
|
+
const deadline = Date.now() + timeoutMs;
|
|
102
|
+
for (;;) {
|
|
103
|
+
const element = await resolve(target).catch(() => null);
|
|
104
|
+
if (element)
|
|
105
|
+
return element;
|
|
106
|
+
if (Date.now() > deadline)
|
|
107
|
+
throw new Error(`${describe(target)} is not on screen`);
|
|
108
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const centre = async (element) => {
|
|
112
|
+
const r = await session.rect(element).catch(() => null);
|
|
113
|
+
return r ? { x: r.x + r.width / 2, y: r.y + r.height / 2 } : {};
|
|
114
|
+
};
|
|
115
|
+
return {
|
|
116
|
+
session,
|
|
117
|
+
mode,
|
|
118
|
+
baseUrl,
|
|
119
|
+
goto: (url) => session.navigate(baseUrl ? new URL(url, baseUrl).href : url),
|
|
120
|
+
find: resolve,
|
|
121
|
+
isVisible: async (target) => Boolean(await resolve(target)),
|
|
122
|
+
user: {
|
|
123
|
+
async tap(target, label) {
|
|
124
|
+
const element = await waitFor(target);
|
|
125
|
+
timeline.add({ kind: 'tap', label, ...(await centre(element)) });
|
|
126
|
+
await session.click(element);
|
|
127
|
+
},
|
|
128
|
+
async type(target, text, label) {
|
|
129
|
+
const element = await waitFor(target);
|
|
130
|
+
timeline.add({ kind: 'type', label, text, ...(await centre(element)) });
|
|
131
|
+
await session.click(element).catch(() => undefined);
|
|
132
|
+
await session.sendKeys(element, text);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Drive anything that speaks W3C WebDriver: Safari (safaridriver ships with macOS), Chrome,
|
|
139
|
+
* Firefox and Edge, or a native iOS or Android app through Appium. Signals resolve in the DOM
|
|
140
|
+
* for web sessions and in the accessibility tree for native ones (test IDs are accessibility
|
|
141
|
+
* identifiers), so one implementation style covers both. Screenshots and the page source are
|
|
142
|
+
* standard; clips are encoded from screenshots, or come from Appium's screen recorder.
|
|
143
|
+
*/
|
|
144
|
+
export function webdriverDriver(options) {
|
|
145
|
+
const mode = options.mode ?? inferMode(options.capabilities);
|
|
146
|
+
const timeoutMs = options.actionTimeoutMs ?? 15_000;
|
|
147
|
+
let server = null;
|
|
148
|
+
let starting = null;
|
|
149
|
+
let shared = null;
|
|
150
|
+
const serverUrl = () => (starting ??= startServer());
|
|
151
|
+
const startServer = async () => {
|
|
152
|
+
if (server)
|
|
153
|
+
return server.url;
|
|
154
|
+
if (options.url) {
|
|
155
|
+
server = { url: options.url, process: null };
|
|
156
|
+
return server.url;
|
|
157
|
+
}
|
|
158
|
+
if (!options.server)
|
|
159
|
+
throw new Error('webdriverDriver needs `url` (a running WebDriver server) or `server` (a command to start one)');
|
|
160
|
+
const port = options.server.port ?? (await freePort());
|
|
161
|
+
const defaults = /chromedriver|msedgedriver/.test(options.server.command) ? ['--port={port}'] : ['--port', '{port}'];
|
|
162
|
+
const args = (options.server.args ?? defaults).map((a) => a.replaceAll('{port}', String(port)));
|
|
163
|
+
const child = spawn(options.server.command, args, { stdio: 'ignore' });
|
|
164
|
+
const url = `http://127.0.0.1:${port}`;
|
|
165
|
+
const exited = new Promise((_, reject) => {
|
|
166
|
+
child.once('error', (e) => reject(new Error(`Could not start ${options.server.command}: ${e.message}`)));
|
|
167
|
+
child.once('exit', (code) => reject(new Error(`${options.server.command} exited with code ${code}`)));
|
|
168
|
+
});
|
|
169
|
+
await Promise.race([waitForServer(url, options.server.readyTimeoutMs ?? 30_000), exited]);
|
|
170
|
+
server = { url, process: child };
|
|
171
|
+
return url;
|
|
172
|
+
};
|
|
173
|
+
const startSession = async () => WebDriverSession.create(await serverUrl(), options.capabilities);
|
|
174
|
+
return {
|
|
175
|
+
name: options.name ?? (mode === 'native' ? `webdriver:${String(options.capabilities.platformName ?? 'native').toLowerCase()}` : `webdriver:${String(options.capabilities.browserName ?? 'browser')}`),
|
|
176
|
+
pacing: options.pacing ?? { before: 400, after: 900 },
|
|
177
|
+
concurrency: options.session === 'per-run' ? 1 : (options.concurrency ?? 1),
|
|
178
|
+
async open({ timeline }) {
|
|
179
|
+
const session = options.session === 'per-run' ? (shared ??= await startSession()) : await startSession();
|
|
180
|
+
const baseUrl = typeof options.baseUrl === 'function' ? await options.baseUrl() : options.baseUrl;
|
|
181
|
+
return contextFor(session, mode, baseUrl, timeline, timeoutMs);
|
|
182
|
+
},
|
|
183
|
+
async close(ctx) {
|
|
184
|
+
if (options.session !== 'per-run')
|
|
185
|
+
await ctx.session.delete().catch(() => undefined);
|
|
186
|
+
},
|
|
187
|
+
async screenshot(ctx, file) {
|
|
188
|
+
const png = await ctx.session.screenshot();
|
|
189
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
190
|
+
writeFileSync(file, png);
|
|
191
|
+
return { png: file };
|
|
192
|
+
},
|
|
193
|
+
...(options.recording === 'none'
|
|
194
|
+
? {}
|
|
195
|
+
: {
|
|
196
|
+
async record(ctx, workDirectory) {
|
|
197
|
+
if (options.recording !== 'appium')
|
|
198
|
+
return recordFrames(() => ctx.session.screenshot(), workDirectory);
|
|
199
|
+
await ctx.session.command('POST', '/appium/start_recording_screen', { options: { forceRestart: true } });
|
|
200
|
+
const started = Date.now();
|
|
201
|
+
return {
|
|
202
|
+
async stop(output) {
|
|
203
|
+
const video = await ctx.session.command('POST', '/appium/stop_recording_screen', {}).catch(() => null);
|
|
204
|
+
if (!video)
|
|
205
|
+
return null;
|
|
206
|
+
mkdirSync(path.dirname(output), { recursive: true });
|
|
207
|
+
writeFileSync(output, Buffer.from(String(video), 'base64'));
|
|
208
|
+
return { video: output, durationMs: Date.now() - started };
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}),
|
|
213
|
+
async text(ctx) {
|
|
214
|
+
if (ctx.mode === 'web')
|
|
215
|
+
return String(await ctx.session.execute('return document.body ? document.body.innerText : ""'));
|
|
216
|
+
return sourceMatches(await ctx.session.source(), /\S/)
|
|
217
|
+
.map((a) => TEXT_ATTRIBUTES.map((k) => a[k]).find(Boolean))
|
|
218
|
+
.join('\n');
|
|
219
|
+
},
|
|
220
|
+
async dispose() {
|
|
221
|
+
await shared?.delete().catch(() => undefined);
|
|
222
|
+
shared = null;
|
|
223
|
+
server?.process?.kill();
|
|
224
|
+
server = null;
|
|
225
|
+
starting = null;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/** A state recognised from signals or locators: every `all` visible and no `none` visible. */
|
|
230
|
+
export const screen = signatureScreen(async (ctx, target) => Boolean(await ctx.find(target)), describe);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Locator } from './protocol.js';
|
|
2
|
+
export { webdriverDriver, screen, nativeLocator, type Mode, type Target, type WebDriverContext, type WebDriverDriverOptions, type WebDriverServer } from './driver.js';
|
|
3
|
+
export { WebDriverSession, WebDriverError, waitForServer, ELEMENT_KEY, type Locator, type Rect } from './protocol.js';
|
|
4
|
+
export { css, label, role, testId, text, describeSignal, type Signal } from '../../core/src/signals.js';
|
|
5
|
+
/** Appium: an accessibility identifier (iOS) or content description (Android); React Native's `testID`. */
|
|
6
|
+
export declare const accessibilityId: (value: string) => Locator;
|
|
7
|
+
export declare const xpath: (value: string) => Locator;
|
|
8
|
+
/** Appium iOS: an NSPredicate over the element tree, e.g. `label == "Book" AND type == "XCUIElementTypeButton"`. */
|
|
9
|
+
export declare const iosPredicate: (value: string) => Locator;
|
|
10
|
+
/** Appium Android: a UiSelector expression, e.g. `new UiSelector().text("Book")`. */
|
|
11
|
+
export declare const androidUiAutomator: (value: string) => Locator;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { webdriverDriver, screen, nativeLocator } from './driver.js';
|
|
2
|
+
export { WebDriverSession, WebDriverError, waitForServer, ELEMENT_KEY } from './protocol.js';
|
|
3
|
+
export { css, label, role, testId, text, describeSignal } from '../../core/src/signals.js';
|
|
4
|
+
/** Appium: an accessibility identifier (iOS) or content description (Android); React Native's `testID`. */
|
|
5
|
+
export const accessibilityId = (value) => ({ using: 'accessibility id', value, name: `accessibility id "${value}"` });
|
|
6
|
+
export const xpath = (value) => ({ using: 'xpath', value, name: `xpath ${value}` });
|
|
7
|
+
/** Appium iOS: an NSPredicate over the element tree, e.g. `label == "Book" AND type == "XCUIElementTypeButton"`. */
|
|
8
|
+
export const iosPredicate = (value) => ({ using: '-ios predicate string', value, name: `predicate ${value}` });
|
|
9
|
+
/** Appium Android: a UiSelector expression, e.g. `new UiSelector().text("Book")`. */
|
|
10
|
+
export const androidUiAutomator = (value) => ({ using: '-android uiautomator', value, name: `uiautomator ${value}` });
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A dependency-free client for the W3C WebDriver protocol (https://www.w3.org/TR/webdriver2/), the
|
|
3
|
+
* standard every browser driver speaks (safaridriver, chromedriver, geckodriver, msedgedriver) and
|
|
4
|
+
* Appium extends for native iOS and Android apps.
|
|
5
|
+
*/
|
|
6
|
+
/** The W3C web element identifier key. */
|
|
7
|
+
export declare const ELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf";
|
|
8
|
+
/**
|
|
9
|
+
* A location strategy and value. W3C strategies: `css selector`, `xpath`, `link text`,
|
|
10
|
+
* `partial link text`, `tag name`. Appium adds `accessibility id`, `id`, `class name`,
|
|
11
|
+
* `-ios predicate string`, `-ios class chain` and `-android uiautomator`.
|
|
12
|
+
*/
|
|
13
|
+
export type Locator = {
|
|
14
|
+
using: string;
|
|
15
|
+
value: string;
|
|
16
|
+
name?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare class WebDriverError extends Error {
|
|
19
|
+
readonly code: string;
|
|
20
|
+
readonly status: number;
|
|
21
|
+
constructor(code: string, message: string, status: number);
|
|
22
|
+
}
|
|
23
|
+
export type Rect = {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
};
|
|
29
|
+
export declare class WebDriverSession {
|
|
30
|
+
readonly serverUrl: string;
|
|
31
|
+
readonly id: string;
|
|
32
|
+
readonly capabilities: Record<string, unknown>;
|
|
33
|
+
timeoutMs: number;
|
|
34
|
+
constructor(serverUrl: string, id: string, capabilities: Record<string, unknown>, timeoutMs?: number);
|
|
35
|
+
/** New Session: `capabilities` go in `alwaysMatch`. */
|
|
36
|
+
static create(serverUrl: string, capabilities: Record<string, unknown>, timeoutMs?: number): Promise<WebDriverSession>;
|
|
37
|
+
/** Any session command, for what this client does not wrap (extensions such as `appium/...`). */
|
|
38
|
+
command(method: 'GET' | 'POST' | 'DELETE', path: string, body?: unknown): Promise<unknown>;
|
|
39
|
+
navigate(url: string): Promise<void>;
|
|
40
|
+
currentUrl(): Promise<string>;
|
|
41
|
+
refresh(): Promise<void>;
|
|
42
|
+
back(): Promise<void>;
|
|
43
|
+
findElements(locator: Locator): Promise<string[]>;
|
|
44
|
+
isDisplayed(element: string): Promise<boolean>;
|
|
45
|
+
rect(element: string): Promise<Rect>;
|
|
46
|
+
click(element: string): Promise<void>;
|
|
47
|
+
clear(element: string): Promise<void>;
|
|
48
|
+
sendKeys(element: string, text: string): Promise<void>;
|
|
49
|
+
elementText(element: string): Promise<string>;
|
|
50
|
+
/** Execute Script (web contexts); element references in the result come back as element ids. */
|
|
51
|
+
execute(script: string, args?: unknown[]): Promise<unknown>;
|
|
52
|
+
elementId(value: unknown): string | null;
|
|
53
|
+
source(): Promise<string>;
|
|
54
|
+
screenshot(): Promise<Buffer<ArrayBuffer>>;
|
|
55
|
+
/** A tap at viewport coordinates through W3C Actions (a touch pointer). */
|
|
56
|
+
tapAt(x: number, y: number): Promise<void>;
|
|
57
|
+
delete(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
/** Wait until a WebDriver server answers `GET /status` as ready. */
|
|
60
|
+
export declare function waitForServer(serverUrl: string, timeoutMs?: number): Promise<void>;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A dependency-free client for the W3C WebDriver protocol (https://www.w3.org/TR/webdriver2/), the
|
|
3
|
+
* standard every browser driver speaks (safaridriver, chromedriver, geckodriver, msedgedriver) and
|
|
4
|
+
* Appium extends for native iOS and Android apps.
|
|
5
|
+
*/
|
|
6
|
+
/** The W3C web element identifier key. */
|
|
7
|
+
export const ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';
|
|
8
|
+
export class WebDriverError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
status;
|
|
11
|
+
constructor(code, message, status) {
|
|
12
|
+
super(`${code}: ${message}`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.status = status;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const elementIdOf = (value) => value && typeof value === 'object' && ELEMENT_KEY in value ? String(value[ELEMENT_KEY]) : null;
|
|
18
|
+
async function call(url, method, body, timeoutMs) {
|
|
19
|
+
const response = await fetch(url, {
|
|
20
|
+
method,
|
|
21
|
+
headers: body === undefined ? {} : { 'content-type': 'application/json; charset=utf-8' },
|
|
22
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
23
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) })
|
|
24
|
+
});
|
|
25
|
+
const text = await response.text();
|
|
26
|
+
let parsed = {};
|
|
27
|
+
try {
|
|
28
|
+
parsed = text ? JSON.parse(text) : {};
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new WebDriverError('invalid response', `${method} ${url} answered ${response.status} with non-JSON`, response.status);
|
|
32
|
+
}
|
|
33
|
+
const value = parsed.value;
|
|
34
|
+
if (!response.ok || (value && typeof value === 'object' && 'error' in value)) {
|
|
35
|
+
const error = (value ?? {});
|
|
36
|
+
throw new WebDriverError(error.error ?? 'unknown error', error.message ?? `${method} ${url} answered ${response.status}`, response.status);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
export class WebDriverSession {
|
|
41
|
+
serverUrl;
|
|
42
|
+
id;
|
|
43
|
+
capabilities;
|
|
44
|
+
timeoutMs;
|
|
45
|
+
constructor(serverUrl, id, capabilities, timeoutMs = 60_000) {
|
|
46
|
+
this.serverUrl = serverUrl.replace(/\/$/, '');
|
|
47
|
+
this.id = id;
|
|
48
|
+
this.capabilities = capabilities;
|
|
49
|
+
this.timeoutMs = timeoutMs;
|
|
50
|
+
}
|
|
51
|
+
/** New Session: `capabilities` go in `alwaysMatch`. */
|
|
52
|
+
static async create(serverUrl, capabilities, timeoutMs = 120_000) {
|
|
53
|
+
const value = (await call(`${serverUrl.replace(/\/$/, '')}/session`, 'POST', { capabilities: { alwaysMatch: capabilities } }, timeoutMs));
|
|
54
|
+
return new WebDriverSession(serverUrl, value.sessionId, value.capabilities ?? {});
|
|
55
|
+
}
|
|
56
|
+
/** Any session command, for what this client does not wrap (extensions such as `appium/...`). */
|
|
57
|
+
command(method, path, body) {
|
|
58
|
+
return call(`${this.serverUrl}/session/${this.id}${path}`, method, method === 'POST' ? (body ?? {}) : undefined, this.timeoutMs);
|
|
59
|
+
}
|
|
60
|
+
async navigate(url) {
|
|
61
|
+
await this.command('POST', '/url', { url });
|
|
62
|
+
}
|
|
63
|
+
async currentUrl() {
|
|
64
|
+
return String(await this.command('GET', '/url'));
|
|
65
|
+
}
|
|
66
|
+
async refresh() {
|
|
67
|
+
await this.command('POST', '/refresh');
|
|
68
|
+
}
|
|
69
|
+
async back() {
|
|
70
|
+
await this.command('POST', '/back');
|
|
71
|
+
}
|
|
72
|
+
async findElements(locator) {
|
|
73
|
+
const value = await this.command('POST', '/elements', { using: locator.using, value: locator.value });
|
|
74
|
+
return Array.isArray(value) ? value.map(elementIdOf).filter((id) => Boolean(id)) : [];
|
|
75
|
+
}
|
|
76
|
+
async isDisplayed(element) {
|
|
77
|
+
return Boolean(await this.command('GET', `/element/${element}/displayed`));
|
|
78
|
+
}
|
|
79
|
+
async rect(element) {
|
|
80
|
+
return (await this.command('GET', `/element/${element}/rect`));
|
|
81
|
+
}
|
|
82
|
+
async click(element) {
|
|
83
|
+
await this.command('POST', `/element/${element}/click`);
|
|
84
|
+
}
|
|
85
|
+
async clear(element) {
|
|
86
|
+
await this.command('POST', `/element/${element}/clear`);
|
|
87
|
+
}
|
|
88
|
+
async sendKeys(element, text) {
|
|
89
|
+
await this.command('POST', `/element/${element}/value`, { text });
|
|
90
|
+
}
|
|
91
|
+
async elementText(element) {
|
|
92
|
+
return String(await this.command('GET', `/element/${element}/text`));
|
|
93
|
+
}
|
|
94
|
+
/** Execute Script (web contexts); element references in the result come back as element ids. */
|
|
95
|
+
async execute(script, args = []) {
|
|
96
|
+
return this.command('POST', '/execute/sync', { script, args });
|
|
97
|
+
}
|
|
98
|
+
elementId(value) {
|
|
99
|
+
return elementIdOf(value);
|
|
100
|
+
}
|
|
101
|
+
async source() {
|
|
102
|
+
return String(await this.command('GET', '/source'));
|
|
103
|
+
}
|
|
104
|
+
async screenshot() {
|
|
105
|
+
return Buffer.from(String(await this.command('GET', '/screenshot')), 'base64');
|
|
106
|
+
}
|
|
107
|
+
/** A tap at viewport coordinates through W3C Actions (a touch pointer). */
|
|
108
|
+
async tapAt(x, y) {
|
|
109
|
+
await this.command('POST', '/actions', {
|
|
110
|
+
actions: [
|
|
111
|
+
{
|
|
112
|
+
type: 'pointer',
|
|
113
|
+
id: 'finger',
|
|
114
|
+
parameters: { pointerType: 'touch' },
|
|
115
|
+
actions: [
|
|
116
|
+
{ type: 'pointerMove', duration: 0, x: Math.round(x), y: Math.round(y) },
|
|
117
|
+
{ type: 'pointerDown', button: 0 },
|
|
118
|
+
{ type: 'pause', duration: 50 },
|
|
119
|
+
{ type: 'pointerUp', button: 0 }
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async delete() {
|
|
126
|
+
await call(`${this.serverUrl}/session/${this.id}`, 'DELETE', undefined, this.timeoutMs);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/** Wait until a WebDriver server answers `GET /status` as ready. */
|
|
130
|
+
export async function waitForServer(serverUrl, timeoutMs = 30_000) {
|
|
131
|
+
const deadline = Date.now() + timeoutMs;
|
|
132
|
+
let last = 'no answer';
|
|
133
|
+
while (Date.now() < deadline) {
|
|
134
|
+
try {
|
|
135
|
+
const value = (await call(`${serverUrl.replace(/\/$/, '')}/status`, 'GET', undefined, 2_000));
|
|
136
|
+
if (value?.ready !== false)
|
|
137
|
+
return;
|
|
138
|
+
last = value.message ?? 'not ready';
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
last = error instanceof Error ? error.message : String(error);
|
|
142
|
+
}
|
|
143
|
+
await new Promise((r) => setTimeout(r, 250));
|
|
144
|
+
}
|
|
145
|
+
throw new Error(`The WebDriver server at ${serverUrl} did not become ready: ${last}`);
|
|
146
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,183 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crvouga/atlas",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Atlas: executable statecharts. Spec a product's flows as statecharts, run them against the real app with any driver, and browse what happened.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": [
|
|
8
|
+
"./packages/visualizer/**",
|
|
9
|
+
"**/*.css"
|
|
10
|
+
],
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/crvouga/atlas.git"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/crvouga/atlas#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/crvouga/atlas/issues"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"statecharts",
|
|
21
|
+
"scxml",
|
|
22
|
+
"xstate",
|
|
23
|
+
"model-based-testing",
|
|
24
|
+
"e2e",
|
|
25
|
+
"playwright",
|
|
26
|
+
"webdriver",
|
|
27
|
+
"visualizer"
|
|
28
|
+
],
|
|
29
|
+
"packageManager": "bun@1.4.2",
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22.18.0",
|
|
32
|
+
"bun": ">=1.2.0"
|
|
33
|
+
},
|
|
34
|
+
"bin": {
|
|
35
|
+
"atlas": "./packages/core/bin/atlas.mjs",
|
|
36
|
+
"atlas-visualizer": "./packages/visualizer/bin/atlas-visualizer.mjs"
|
|
37
|
+
},
|
|
38
|
+
"exports": {
|
|
39
|
+
".": {
|
|
40
|
+
"types": "./dist/core/src/index.d.ts",
|
|
41
|
+
"default": "./dist/core/src/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./spec": {
|
|
44
|
+
"types": "./dist/core/src/spec/index.d.ts",
|
|
45
|
+
"default": "./dist/core/src/spec/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./signals": {
|
|
48
|
+
"types": "./dist/core/src/signals.d.ts",
|
|
49
|
+
"default": "./dist/core/src/signals.js"
|
|
50
|
+
},
|
|
51
|
+
"./cli": {
|
|
52
|
+
"types": "./dist/core/src/cli.d.ts",
|
|
53
|
+
"default": "./dist/core/src/cli.js"
|
|
54
|
+
},
|
|
55
|
+
"./playwright": {
|
|
56
|
+
"types": "./dist/playwright/src/index.d.ts",
|
|
57
|
+
"default": "./dist/playwright/src/index.js"
|
|
58
|
+
},
|
|
59
|
+
"./bun": {
|
|
60
|
+
"types": "./dist/bun/src/index.d.ts",
|
|
61
|
+
"default": "./dist/bun/src/index.js"
|
|
62
|
+
},
|
|
63
|
+
"./webdriver": {
|
|
64
|
+
"types": "./dist/webdriver/src/index.d.ts",
|
|
65
|
+
"default": "./dist/webdriver/src/index.js"
|
|
66
|
+
},
|
|
67
|
+
"./detox": {
|
|
68
|
+
"types": "./dist/detox/src/index.d.ts",
|
|
69
|
+
"default": "./dist/detox/src/index.js"
|
|
70
|
+
},
|
|
71
|
+
"./vitest": {
|
|
72
|
+
"types": "./dist/vitest/src/index.d.ts",
|
|
73
|
+
"default": "./dist/vitest/src/index.js"
|
|
74
|
+
},
|
|
75
|
+
"./schema": {
|
|
76
|
+
"types": "./dist/schema/src/index.d.ts",
|
|
77
|
+
"default": "./dist/schema/src/index.js"
|
|
78
|
+
},
|
|
79
|
+
"./reports/*": {
|
|
80
|
+
"types": "./dist/reports/src/*.d.ts",
|
|
81
|
+
"default": "./dist/reports/src/*.js"
|
|
82
|
+
},
|
|
83
|
+
"./schemas/*": "./packages/schema/schemas/*"
|
|
84
|
+
},
|
|
85
|
+
"publishConfig": {
|
|
86
|
+
"access": "public",
|
|
87
|
+
"provenance": true
|
|
88
|
+
},
|
|
89
|
+
"files": [
|
|
90
|
+
"dist",
|
|
91
|
+
"packages/core/bin",
|
|
92
|
+
"packages/schema/schemas",
|
|
93
|
+
"packages/visualizer/bin",
|
|
94
|
+
"packages/visualizer/example",
|
|
95
|
+
"packages/visualizer/fixtures",
|
|
96
|
+
"packages/visualizer/index.html",
|
|
97
|
+
"packages/visualizer/scripts",
|
|
98
|
+
"packages/visualizer/src",
|
|
99
|
+
"packages/visualizer/vite",
|
|
100
|
+
"packages/visualizer/vite.config.ts",
|
|
101
|
+
"packages/*/README.md",
|
|
102
|
+
"packages/reports/STORAGE.md",
|
|
103
|
+
"CHANGELOG.md"
|
|
104
|
+
],
|
|
105
|
+
"scripts": {
|
|
106
|
+
"build": "bun scripts/build-package.ts",
|
|
107
|
+
"test": "bun test && bun test --cwd packages/visualizer --preload ./tests/preload.ts tests",
|
|
108
|
+
"type-check": "for dir in packages/* scripts examples/todo; do tsc --noEmit -p \"$dir\" || exit 1; done",
|
|
109
|
+
"schemas": "bun packages/schema/scripts/emit-json-schemas.ts",
|
|
110
|
+
"viz:dev": "cd packages/visualizer && INIT_CWD=\"$OLDPWD\" bun --bun vite --configLoader runner",
|
|
111
|
+
"viz:build": "cd packages/visualizer && INIT_CWD=\"$OLDPWD\" bun --bun vite build --configLoader runner",
|
|
112
|
+
"viz:publish-data": "bun packages/visualizer/scripts/publish-data.ts",
|
|
113
|
+
"viz:fixtures": "bun packages/visualizer/scripts/make-fixtures.ts",
|
|
114
|
+
"example:start": "bun examples/todo/server.ts",
|
|
115
|
+
"example:lint": "bun --cwd examples/todo ../../packages/core/bin/atlas.mjs lint --require-implementations",
|
|
116
|
+
"example:plan": "bun --cwd examples/todo ../../packages/core/bin/atlas.mjs plan",
|
|
117
|
+
"example:fast": "bun --cwd examples/todo ../../packages/core/bin/atlas.mjs run --mode fast",
|
|
118
|
+
"example:run": "bun --cwd examples/todo ../../packages/core/bin/atlas.mjs run --mode showcase",
|
|
119
|
+
"example:clients": "bun --cwd examples/todo ../../packages/core/bin/atlas.mjs run --config clients/atlas.config.ts --mode showcase",
|
|
120
|
+
"example:clients:bun": "ATLAS_DESKTOP=bun bun --cwd examples/todo ../../packages/core/bin/atlas.mjs run --config clients/atlas.config.ts --mode showcase",
|
|
121
|
+
"atlas:run": "status=0; bun run example:clients || status=$?; bun run example:run || status=$?; exit $status",
|
|
122
|
+
"atlas:viz": "bun packages/visualizer/bin/atlas-visualizer.mjs dev --specs examples/todo/specs --runs examples/todo/atlas-runs",
|
|
123
|
+
"release:plan": "bun scripts/release/plan.ts",
|
|
124
|
+
"release:publish": "bun scripts/release/publish.ts",
|
|
125
|
+
"release:smoke": "bun scripts/release/consumer-smoke.ts",
|
|
126
|
+
"release:seed": "bun scripts/release/seed.ts",
|
|
127
|
+
"health": "bun scripts/health/cli.ts",
|
|
128
|
+
"prepare": "husky"
|
|
129
|
+
},
|
|
130
|
+
"dependencies": {
|
|
131
|
+
"@cucumber/gherkin": "^42.0.1",
|
|
132
|
+
"@cucumber/messages": "^34.2.1",
|
|
133
|
+
"@radix-ui/react-collapsible": "^1.1.21",
|
|
134
|
+
"@radix-ui/react-dialog": "^1.2.0",
|
|
135
|
+
"@radix-ui/react-dropdown-menu": "^2.1.25",
|
|
136
|
+
"@radix-ui/react-popover": "^1.2.0",
|
|
137
|
+
"@radix-ui/react-tabs": "^1.1.22",
|
|
138
|
+
"@radix-ui/react-tooltip": "^1.3.0",
|
|
139
|
+
"@tanstack/query-persist-client-core": "^5.104.0",
|
|
140
|
+
"@tanstack/react-query": "^5.101.4",
|
|
141
|
+
"@tanstack/react-router": "^1.170.41",
|
|
142
|
+
"@tanstack/solid-query": "^5.104.0",
|
|
143
|
+
"@vitejs/plugin-react": "5.2.0",
|
|
144
|
+
"@xyflow/react": "^12.11.5",
|
|
145
|
+
"cmdk": "^1.1.1",
|
|
146
|
+
"elkjs": "0.12.0",
|
|
147
|
+
"fast-xml-parser": "5.11.0",
|
|
148
|
+
"hono": "^4.13.9",
|
|
149
|
+
"react": "^19.3.0",
|
|
150
|
+
"react-dom": "^19.3.0",
|
|
151
|
+
"solid-js": "^1.9.15",
|
|
152
|
+
"tsx": "4.23.13",
|
|
153
|
+
"vite": "7.3.6",
|
|
154
|
+
"xstate": "5.33.2",
|
|
155
|
+
"yaml": "^2.9.0",
|
|
156
|
+
"zod": "^3.25.76",
|
|
157
|
+
"zustand": "^5.0.15"
|
|
158
|
+
},
|
|
159
|
+
"peerDependencies": {
|
|
160
|
+
"detox": ">=20",
|
|
161
|
+
"playwright": ">=1.45"
|
|
162
|
+
},
|
|
163
|
+
"peerDependenciesMeta": {
|
|
164
|
+
"detox": {
|
|
165
|
+
"optional": true
|
|
166
|
+
},
|
|
167
|
+
"playwright": {
|
|
168
|
+
"optional": true
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
"devDependencies": {
|
|
172
|
+
"@commitlint/cli": "19.8.1",
|
|
173
|
+
"@commitlint/config-conventional": "19.8.1",
|
|
174
|
+
"@types/bun": "1.4.3",
|
|
175
|
+
"@types/node": "^22.20.3",
|
|
176
|
+
"@types/react": "19.2.7",
|
|
177
|
+
"@types/react-dom": "19.2.3",
|
|
178
|
+
"happy-dom": "20.11.1",
|
|
179
|
+
"husky": "^9.1.7",
|
|
180
|
+
"playwright": "1.60.0",
|
|
181
|
+
"typescript": "^5.9.3"
|
|
182
|
+
}
|
|
183
|
+
}
|