@crvouga/atlas 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -1
- package/README.md +191 -611
- package/dist/bun/src/driver.d.ts +41 -7
- package/dist/bun/src/driver.js +47 -6
- package/dist/bun/src/index.d.ts +8 -0
- package/dist/bun/src/index.js +8 -0
- package/dist/core/src/cli.d.ts +14 -1
- package/dist/core/src/cli.js +35 -1
- package/dist/core/src/config.d.ts +77 -4
- package/dist/core/src/config.js +110 -17
- package/dist/core/src/events/cloudevents.d.ts +54 -9
- package/dist/core/src/events/cloudevents.js +60 -9
- package/dist/core/src/graph.d.ts +21 -0
- package/dist/core/src/graph.js +26 -0
- package/dist/core/src/index.d.ts +11 -0
- package/dist/core/src/index.js +11 -0
- package/dist/core/src/lint.d.ts +30 -0
- package/dist/core/src/lint.js +13 -0
- package/dist/core/src/plan.d.ts +39 -1
- package/dist/core/src/plan.js +28 -1
- package/dist/core/src/privacy.d.ts +29 -2
- package/dist/core/src/privacy.js +19 -2
- package/dist/core/src/report/formats.d.ts +34 -4
- package/dist/core/src/report/formats.js +24 -4
- package/dist/core/src/report/markdown.d.ts +15 -0
- package/dist/core/src/report/markdown.js +8 -0
- package/dist/core/src/run/clients.d.ts +44 -5
- package/dist/core/src/run/clients.js +46 -2
- package/dist/core/src/run/execute.d.ts +75 -16
- package/dist/core/src/run/execute.js +71 -18
- package/dist/core/src/run/frames.d.ts +13 -4
- package/dist/core/src/run/frames.js +19 -4
- package/dist/core/src/run/http.d.ts +34 -1
- package/dist/core/src/run/http.js +14 -1
- package/dist/core/src/run/types.d.ts +76 -3
- package/dist/core/src/run/types.js +19 -3
- package/dist/core/src/signals.d.ts +49 -5
- package/dist/core/src/signals.js +22 -5
- package/dist/core/src/spec/compose.d.ts +23 -1
- package/dist/core/src/spec/compose.js +10 -1
- package/dist/core/src/spec/index.d.ts +9 -1
- package/dist/core/src/spec/index.js +9 -1
- package/dist/core/src/spec/load.d.ts +22 -1
- package/dist/core/src/spec/load.js +31 -1
- package/dist/core/src/spec/parse.d.ts +16 -2
- package/dist/core/src/spec/parse.js +25 -2
- package/dist/core/src/spec/scxml.d.ts +25 -4
- package/dist/core/src/spec/scxml.js +36 -4
- package/dist/core/src/spec/types.d.ts +52 -1
- package/dist/core/src/spec/types.js +24 -0
- package/dist/detox/src/index.d.ts +54 -11
- package/dist/detox/src/index.js +45 -7
- package/dist/playwright/src/driver.d.ts +39 -3
- package/dist/playwright/src/driver.js +27 -3
- package/dist/playwright/src/index.d.ts +10 -0
- package/dist/playwright/src/index.js +10 -0
- package/dist/playwright/src/media.d.ts +50 -4
- package/dist/playwright/src/media.js +55 -4
- package/dist/playwright/src/signals.d.ts +44 -5
- package/dist/playwright/src/signals.js +29 -5
- package/dist/reports/src/attachment-files.d.ts +44 -0
- package/dist/reports/src/attachment-files.js +121 -0
- package/dist/reports/src/attachment-response.d.ts +31 -0
- package/dist/reports/src/attachment-response.js +55 -0
- package/dist/reports/src/aws-credentials.d.ts +48 -0
- package/dist/reports/src/aws-credentials.js +221 -0
- package/dist/reports/src/browser-navigation.d.ts +14 -0
- package/dist/reports/src/browser-navigation.js +7 -0
- package/dist/reports/src/bundle.d.ts +34 -2
- package/dist/reports/src/bundle.js +38 -2
- package/dist/reports/src/catalog.d.ts +34 -3
- package/dist/reports/src/catalog.js +17 -3
- package/dist/reports/src/cli-stores.d.ts +36 -0
- package/dist/reports/src/cli-stores.js +73 -0
- package/dist/reports/src/clock.d.ts +7 -2
- package/dist/reports/src/clock.js +5 -2
- package/dist/reports/src/completion-order.d.ts +18 -5
- package/dist/reports/src/completion-order.js +18 -5
- package/dist/reports/src/compose.d.ts +80 -0
- package/dist/reports/src/compose.js +117 -0
- package/dist/reports/src/copy-store.d.ts +29 -0
- package/dist/reports/src/copy-store.js +52 -0
- package/dist/reports/src/directory-outline.d.ts +38 -0
- package/dist/reports/src/directory-outline.js +103 -0
- package/dist/reports/src/directory-store.d.ts +20 -0
- package/dist/reports/src/directory-store.js +166 -0
- package/dist/reports/src/doctor.d.ts +29 -0
- package/dist/reports/src/doctor.js +85 -0
- package/dist/reports/src/effective-delta.d.ts +34 -0
- package/dist/reports/src/effective-delta.js +25 -0
- package/dist/reports/src/evidence-detail.d.ts +64 -0
- package/dist/reports/src/evidence-detail.js +92 -0
- package/dist/reports/src/evidence-live.d.ts +35 -5
- package/dist/reports/src/evidence-live.js +18 -2
- package/dist/reports/src/evidence-types.d.ts +68 -1
- package/dist/reports/src/evidence-types.js +5 -1
- package/dist/reports/src/evidence-view.d.ts +43 -4
- package/dist/reports/src/evidence-view.js +13 -2
- package/dist/reports/src/explorer-types.d.ts +40 -3
- package/dist/reports/src/explorer-types.js +8 -0
- package/dist/reports/src/explorer-versions.d.ts +9 -1
- package/dist/reports/src/explorer-versions.js +18 -1
- package/dist/reports/src/export-evidence.d.ts +16 -1
- package/dist/reports/src/export-evidence.js +52 -1
- package/dist/reports/src/fetcher.d.ts +27 -3
- package/dist/reports/src/fetcher.js +11 -3
- package/dist/reports/src/format-date.d.ts +6 -0
- package/dist/reports/src/format-date.js +6 -0
- package/dist/reports/src/format.d.ts +16 -0
- package/dist/reports/src/format.js +10 -0
- package/dist/reports/src/frames.d.ts +36 -3
- package/dist/reports/src/frames.js +22 -3
- package/dist/reports/src/hash.d.ts +18 -0
- package/dist/reports/src/hash.js +13 -0
- package/dist/reports/src/host.d.ts +29 -0
- package/dist/reports/src/host.js +64 -0
- package/dist/reports/src/html-frame.d.ts +5 -6
- package/dist/reports/src/html-frame.js +12 -1
- package/dist/reports/src/http-store.d.ts +56 -0
- package/dist/reports/src/http-store.js +148 -0
- package/dist/reports/src/http.d.ts +7 -0
- package/dist/reports/src/http.js +6 -0
- package/dist/reports/src/ingest.d.ts +54 -0
- package/dist/reports/src/ingest.js +210 -0
- package/dist/reports/src/init.d.ts +40 -0
- package/dist/reports/src/init.js +369 -0
- package/dist/reports/src/junit.d.ts +33 -6
- package/dist/reports/src/junit.js +87 -21
- package/dist/reports/src/keyboard.d.ts +20 -0
- package/dist/reports/src/keyboard.js +11 -0
- package/dist/reports/src/keys.d.ts +21 -3
- package/dist/reports/src/keys.js +21 -3
- package/dist/reports/src/layer-axes.d.ts +35 -5
- package/dist/reports/src/layer-axes.js +25 -5
- package/dist/reports/src/layer-catalog.d.ts +28 -1
- package/dist/reports/src/layer-catalog.js +18 -1
- package/dist/reports/src/layer-merge.d.ts +98 -9
- package/dist/reports/src/layer-merge.js +147 -31
- package/dist/reports/src/layer-source.d.ts +18 -0
- package/dist/reports/src/layer-source.js +11 -0
- package/dist/reports/src/layer-store.d.ts +42 -0
- package/dist/reports/src/layer-store.js +63 -5
- package/dist/reports/src/layer-types.d.ts +32 -1
- package/dist/reports/src/layers-route.d.ts +47 -4
- package/dist/reports/src/layers-route.js +86 -7
- package/dist/reports/src/live-reporter.d.ts +34 -0
- package/dist/reports/src/live-reporter.js +122 -0
- package/dist/reports/src/media-types.d.ts +11 -0
- package/dist/reports/src/media-types.js +22 -0
- package/dist/reports/src/namespace-guard.d.ts +10 -1
- package/dist/reports/src/namespace-guard.js +10 -1
- package/dist/reports/src/navigation.d.ts +12 -0
- package/dist/reports/src/navigation.js +7 -0
- package/dist/reports/src/object-io.d.ts +11 -4
- package/dist/reports/src/object-io.js +4 -4
- package/dist/reports/src/object-store-conformance.d.ts +27 -0
- package/dist/reports/src/object-store-conformance.js +87 -0
- package/dist/reports/src/object-store.d.ts +33 -24
- package/dist/reports/src/object-store.js +17 -24
- package/dist/reports/src/parse-with.d.ts +16 -0
- package/dist/reports/src/parse-with.js +14 -0
- package/dist/reports/src/performance-part.d.ts +25 -1
- package/dist/reports/src/performance-part.js +15 -1
- package/dist/reports/src/performance.d.ts +22 -2
- package/dist/reports/src/performance.js +12 -2
- package/dist/reports/src/persist.d.ts +12 -3
- package/dist/reports/src/persist.js +12 -3
- package/dist/reports/src/phone.d.ts +18 -1
- package/dist/reports/src/phone.js +18 -1
- package/dist/reports/src/protocol.d.ts +26 -4
- package/dist/reports/src/protocol.js +15 -4
- package/dist/reports/src/publication.d.ts +21 -1
- package/dist/reports/src/publication.js +21 -1
- package/dist/reports/src/publish-checks.d.ts +35 -0
- package/dist/reports/src/publish-checks.js +122 -0
- package/dist/reports/src/publish.d.ts +42 -9
- package/dist/reports/src/publish.js +36 -7
- package/dist/reports/src/read.d.ts +46 -16
- package/dist/reports/src/read.js +38 -14
- package/dist/reports/src/recording-bundle.d.ts +13 -2
- package/dist/reports/src/recording-bundle.js +4 -2
- package/dist/reports/src/recording-keys.d.ts +15 -1
- package/dist/reports/src/recording-keys.js +15 -1
- package/dist/reports/src/remote-report.d.ts +28 -7
- package/dist/reports/src/remote-report.js +15 -7
- package/dist/reports/src/report-cli.d.ts +51 -0
- package/dist/reports/src/report-cli.js +486 -0
- package/dist/reports/src/report-index.d.ts +99 -0
- package/dist/reports/src/report-index.js +337 -0
- package/dist/reports/src/report-loader.d.ts +10 -0
- package/dist/reports/src/report-loader.js +6 -0
- package/dist/reports/src/report-parts.d.ts +29 -3
- package/dist/reports/src/report-parts.js +37 -3
- package/dist/reports/src/report-status.d.ts +48 -0
- package/dist/reports/src/report-status.js +156 -0
- package/dist/reports/src/report-types.d.ts +73 -0
- package/dist/reports/src/report-types.js +3 -0
- package/dist/reports/src/reporter.d.ts +67 -0
- package/dist/reports/src/reporter.js +128 -0
- package/dist/reports/src/reports-explorer-route.d.ts +541 -0
- package/dist/reports/src/reports-explorer-route.js +11 -0
- package/dist/reports/src/reports-list-route.d.ts +9 -0
- package/dist/reports/src/reports-list-route.js +9 -0
- package/dist/reports/src/reports-route.d.ts +561 -22
- package/dist/reports/src/reports-route.js +11 -3
- package/dist/reports/src/reports-store.d.ts +19 -2
- package/dist/reports/src/reports-store.js +10 -2
- package/dist/reports/src/resilient-cache.d.ts +14 -1
- package/dist/reports/src/resilient-cache.js +8 -1
- package/dist/reports/src/retention.d.ts +17 -1
- package/dist/reports/src/retention.js +5 -1
- package/dist/reports/src/run-bundle.d.ts +63 -0
- package/dist/reports/src/run-bundle.js +159 -0
- package/dist/reports/src/s3-store.d.ts +79 -0
- package/dist/reports/src/s3-store.js +295 -0
- package/dist/reports/src/scenario.d.ts +14 -4
- package/dist/reports/src/scenario.js +5 -4
- package/dist/reports/src/sigv4.d.ts +72 -0
- package/dist/reports/src/sigv4.js +96 -0
- package/dist/reports/src/snapshot-bundle.d.ts +24 -1
- package/dist/reports/src/snapshot-bundle.js +27 -2
- package/dist/reports/src/snapshot-surface.d.ts +20 -9
- package/dist/reports/src/snapshot-surface.js +32 -19
- package/dist/reports/src/source-content.d.ts +23 -0
- package/dist/reports/src/source-content.js +30 -1
- package/dist/reports/src/source-entries.d.ts +13 -0
- package/dist/reports/src/source-entries.js +6 -0
- package/dist/reports/src/source-part.d.ts +15 -0
- package/dist/reports/src/source-part.js +8 -0
- package/dist/reports/src/source-reader.d.ts +11 -0
- package/dist/reports/src/source-reader.js +5 -0
- package/dist/reports/src/spec-evidence.d.ts +12 -2
- package/dist/reports/src/spec-evidence.js +6 -2
- package/dist/reports/src/spec-inventory.d.ts +15 -1
- package/dist/reports/src/spec-inventory.js +22 -1
- package/dist/reports/src/spec-link.d.ts +28 -0
- package/dist/reports/src/spec-link.js +70 -0
- package/dist/reports/src/spec-set.d.ts +63 -0
- package/dist/reports/src/spec-set.js +177 -0
- package/dist/reports/src/status.d.ts +10 -0
- package/dist/reports/src/status.js +5 -0
- package/dist/reports/src/store-prefix.d.ts +28 -0
- package/dist/reports/src/store-prefix.js +22 -0
- package/dist/reports/src/store-url.d.ts +89 -0
- package/dist/reports/src/store-url.js +160 -0
- package/dist/reports/src/test-catalog-entity.d.ts +11 -0
- package/dist/reports/src/test-catalog-entity.js +6 -0
- package/dist/reports/src/types.d.ts +6 -1
- package/dist/reports/src/use-report-nav.d.ts +35 -0
- package/dist/reports/src/use-report-nav.js +12 -0
- package/dist/runners/src/codecept.d.ts +14 -0
- package/dist/runners/src/codecept.js +16 -0
- package/dist/runners/src/jest.d.ts +50 -0
- package/dist/runners/src/jest.js +52 -0
- package/dist/runners/src/mocha.d.ts +40 -0
- package/dist/runners/src/mocha.js +39 -0
- package/dist/runners/src/node-test.d.ts +28 -0
- package/dist/runners/src/node-test.js +44 -0
- package/dist/runners/src/publish.d.ts +30 -0
- package/dist/runners/src/publish.js +68 -0
- package/dist/schema/src/api.d.ts +800 -0
- package/dist/schema/src/api.js +201 -0
- package/dist/schema/src/cli-results.d.ts +210 -0
- package/dist/schema/src/cli-results.js +124 -0
- package/dist/schema/src/common.d.ts +53 -0
- package/dist/schema/src/common.js +42 -0
- package/dist/schema/src/index.d.ts +16 -0
- package/dist/schema/src/index.js +16 -0
- package/dist/schema/src/layer.d.ts +2273 -0
- package/dist/schema/src/layer.js +462 -0
- package/dist/schema/src/live-run.d.ts +123 -0
- package/dist/schema/src/live-run.js +30 -0
- package/dist/schema/src/manifest.d.ts +97 -2
- package/dist/schema/src/manifest.js +84 -0
- package/dist/schema/src/project.d.ts +20 -0
- package/dist/schema/src/project.js +10 -0
- package/dist/schema/src/report-sources.d.ts +29 -0
- package/dist/schema/src/report-sources.js +27 -1
- package/dist/schema/src/runs-index.d.ts +17 -1
- package/dist/schema/src/runs-index.js +15 -0
- package/dist/schema/src/server-config.d.ts +177 -0
- package/dist/schema/src/server-config.js +85 -0
- package/dist/schema/src/spec.d.ts +69 -0
- package/dist/schema/src/spec.js +58 -0
- package/dist/server/src/app.d.ts +72 -0
- package/dist/server/src/app.js +557 -0
- package/dist/server/src/auth.d.ts +41 -0
- package/dist/server/src/auth.js +59 -0
- package/dist/server/src/config.d.ts +83 -0
- package/dist/server/src/config.js +204 -0
- package/dist/server/src/dev.d.ts +12 -0
- package/dist/server/src/dev.js +89 -0
- package/dist/server/src/events.d.ts +29 -0
- package/dist/server/src/events.js +101 -0
- package/dist/server/src/host.d.ts +30 -0
- package/dist/server/src/host.js +115 -0
- package/dist/server/src/index.d.ts +18 -0
- package/dist/server/src/index.js +18 -0
- package/dist/server/src/live-runs.d.ts +52 -0
- package/dist/server/src/live-runs.js +229 -0
- package/dist/server/src/llms.d.ts +19 -0
- package/dist/server/src/llms.js +63 -0
- package/dist/server/src/main.d.ts +30 -0
- package/dist/server/src/main.js +114 -0
- package/dist/server/src/openapi.d.ts +56 -0
- package/dist/server/src/openapi.js +438 -0
- package/dist/server/src/problem.d.ts +8 -0
- package/dist/server/src/problem.js +39 -0
- package/dist/server/src/projects.d.ts +3 -0
- package/dist/server/src/projects.js +154 -0
- package/dist/server/src/settings-page.d.ts +9 -0
- package/dist/server/src/settings-page.js +93 -0
- package/dist/server/src/settings.d.ts +23 -0
- package/dist/server/src/settings.js +72 -0
- package/dist/server/src/site.d.ts +15 -0
- package/dist/server/src/site.js +78 -0
- package/dist/server/src/store-api.d.ts +28 -0
- package/dist/server/src/store-api.js +180 -0
- package/dist/server/src/validate.d.ts +71 -0
- package/dist/server/src/validate.js +197 -0
- package/dist/vitest/src/index.d.ts +27 -5
- package/dist/vitest/src/index.js +18 -5
- package/dist/webdriver/src/driver.d.ts +63 -11
- package/dist/webdriver/src/driver.js +57 -6
- package/dist/webdriver/src/index.d.ts +8 -0
- package/dist/webdriver/src/index.js +1 -0
- package/dist/webdriver/src/protocol.d.ts +75 -6
- package/dist/webdriver/src/protocol.js +79 -6
- package/docs/agents.md +137 -0
- package/docs/deploying.md +345 -0
- package/docs/dogfooding.md +175 -0
- package/docs/extending.md +242 -0
- package/docs/integrating.md +485 -0
- package/docs/reference/bun.md +141 -0
- package/docs/reference/cli.md +148 -0
- package/docs/reference/core.md +2432 -0
- package/docs/reference/detox.md +150 -0
- package/docs/reference/http-api.md +799 -0
- package/docs/reference/playwright.md +303 -0
- package/docs/reference/reports.md +7152 -0
- package/docs/reference/runners.md +169 -0
- package/docs/reference/schema.md +1762 -0
- package/docs/reference/server.md +825 -0
- package/docs/reference/vitest.md +45 -0
- package/docs/reference/webdriver.md +330 -0
- package/docs/report-backends.md +144 -0
- package/docs/report-contract.md +400 -0
- package/docs/reporting-issues.md +160 -0
- package/docs/runners.md +69 -0
- package/docs/server.md +321 -0
- package/docs/statecharts.md +643 -0
- package/llms-full.txt +4114 -0
- package/llms.txt +49 -0
- package/package.json +61 -11
- package/packages/core/README.md +2 -1
- package/packages/reports/README.md +65 -0
- package/packages/reports/STORAGE.md +4 -0
- package/packages/runners/README.md +6 -0
- package/packages/runners/compat/codecept.cjs +2 -0
- package/packages/runners/compat/jest.cjs +2 -0
- package/packages/runners/compat/mocha.cjs +2 -0
- package/packages/schema/README.md +14 -0
- package/packages/schema/schemas/atlas-change.schema.json +4 -0
- package/packages/schema/schemas/check-detail.schema.json +1032 -0
- package/packages/schema/schemas/checks-result.schema.json +26 -0
- package/packages/schema/schemas/command-error.schema.json +35 -0
- package/packages/schema/schemas/doctor-result.schema.json +60 -0
- package/packages/schema/schemas/effective-delta.schema.json +490 -0
- package/packages/schema/schemas/effective-evidence.schema.json +471 -0
- package/packages/schema/schemas/evidence-page.schema.json +271 -0
- package/packages/schema/schemas/hello-event.schema.json +26 -0
- package/packages/schema/schemas/init-plan.schema.json +347 -0
- package/packages/schema/schemas/layer-rows.schema.json +199 -0
- package/packages/schema/schemas/layer.schema.json +2888 -0
- package/packages/schema/schemas/live-run-start.schema.json +42 -0
- package/packages/schema/schemas/live-run-update.schema.json +93 -0
- package/packages/schema/schemas/live-run.schema.json +225 -0
- package/packages/schema/schemas/merge-result.schema.json +40 -0
- package/packages/schema/schemas/outline.schema.json +62 -0
- package/packages/schema/schemas/problem.schema.json +37 -0
- package/packages/schema/schemas/project-slug.schema.json +8 -0
- package/packages/schema/schemas/project.schema.json +22 -0
- package/packages/schema/schemas/projects.schema.json +33 -0
- package/packages/schema/schemas/publish-checks.schema.json +1413 -0
- package/packages/schema/schemas/publish-result.schema.json +168 -0
- package/packages/schema/schemas/ready.schema.json +68 -0
- package/packages/schema/schemas/report-event.schema.json +100 -0
- package/packages/schema/schemas/report-status.schema.json +370 -0
- package/packages/schema/schemas/server-config.schema.json +208 -0
- package/packages/schema/schemas/server-editable-settings.schema.json +132 -0
- package/packages/schema/schemas/server-info.schema.json +114 -0
- package/packages/schema/schemas/server-settings-snapshot.schema.json +285 -0
- package/packages/schema/schemas/spec-set.schema.json +103 -0
- package/packages/schema/schemas/store-listing.schema.json +29 -0
- package/packages/schema/schemas/store-write-result.schema.json +28 -0
- package/packages/schema/schemas/stream-result.schema.json +59 -0
- package/packages/server/README.md +43 -0
- package/packages/server/openapi.json +11021 -0
- package/packages/visualizer/README.md +32 -11
- package/packages/visualizer/bin/atlas-client.mjs +176 -0
- package/packages/visualizer/bin/atlas-visualizer.mjs +2 -175
- package/packages/visualizer/src/app/AppShell.tsx +32 -16
- package/packages/visualizer/src/app/report-sources.tsx +7 -4
- package/packages/visualizer/src/app/router.tsx +3 -3
- package/packages/visualizer/src/components/ActivityIndicator.module.css +4 -0
- package/packages/visualizer/src/components/ActivityIndicator.tsx +6 -0
- package/packages/visualizer/src/components/Header.module.css +101 -192
- package/packages/visualizer/src/components/Header.tsx +88 -13
- package/packages/visualizer/src/components/ProjectPicker.tsx +64 -0
- package/packages/visualizer/src/data/adapters/adapter.ts +5 -17
- package/packages/visualizer/src/data/adapters/index.ts +10 -1
- package/packages/visualizer/src/data/adapters/report-backend.test.ts +3 -2
- package/packages/visualizer/src/data/adapters/report-backend.ts +1 -1
- package/packages/visualizer/src/data/queries.ts +14 -7
- package/packages/visualizer/src/evidence/api.ts +16 -3
- package/packages/visualizer/src/evidence/artifacts.module.css +213 -0
- package/packages/visualizer/src/evidence/artifacts.tsx +272 -0
- package/packages/visualizer/src/evidence/check-detail.tsx +21 -4
- package/packages/visualizer/src/evidence/document-page.tsx +6 -2
- package/packages/visualizer/src/evidence/evidence-context.tsx +79 -12
- package/packages/visualizer/src/evidence/evidence.module.css +11 -1
- package/packages/visualizer/src/evidence/feature-page.tsx +7 -3
- package/packages/visualizer/src/evidence/model-page.tsx +6 -2
- package/packages/visualizer/src/evidence/project-home.tsx +45 -0
- package/packages/visualizer/src/evidence/recording-page.tsx +4 -1
- package/packages/visualizer/src/evidence/spec-index.tsx +2 -1
- package/packages/visualizer/src/evidence/spec-page.tsx +23 -16
- package/packages/visualizer/src/evidence/test-filter.tsx +21 -0
- package/packages/visualizer/src/find/Finder.tsx +1 -7
- package/packages/visualizer/src/find/open.ts +4 -0
- package/packages/visualizer/src/live/live-query.ts +21 -0
- package/packages/visualizer/src/live/live-runs.tsx +69 -0
- package/packages/visualizer/src/live/live-stream.ts +225 -0
- package/packages/visualizer/src/live/report-progress.ts +62 -0
- package/packages/visualizer/src/live/test-progress.tsx +34 -0
- package/packages/visualizer/src/runtime.ts +35 -0
- package/packages/visualizer/src/state/ui-store.ts +3 -2
- package/packages/visualizer/src/views/ChartPage.tsx +2 -0
- package/packages/visualizer/src/views/ChartTests.tsx +43 -0
- package/packages/visualizer/src/views/SidePanel.tsx +2 -0
- package/packages/visualizer/vite/atlas-files.test.ts +4 -4
- package/packages/visualizer/vite/atlas-files.ts +1 -5
- package/packages/visualizer/vite/atlas-server-proxy.ts +37 -0
- package/packages/visualizer/vite.config.ts +11 -3
package/dist/bun/src/driver.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export type WebViewContext = SignalContext & {
|
|
|
37
37
|
press(key: string, label?: string): Promise<void>;
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
|
+
/** Options of `bunWebViewDriver`; every field is optional. */
|
|
40
41
|
export type BunWebViewDriverOptions = {
|
|
41
42
|
/** Where `goto` paths resolve; the implementation's setup decides where to open. */
|
|
42
43
|
baseUrl?: string | (() => string | Promise<string>);
|
|
@@ -47,7 +48,10 @@ export type BunWebViewDriverOptions = {
|
|
|
47
48
|
backend?: 'webkit' | 'chrome';
|
|
48
49
|
/** How long a tap waits for its target to show, in milliseconds (default 10 000). */
|
|
49
50
|
actionTimeoutMs?: number;
|
|
50
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Showcase pacing, in milliseconds: the hold before each event runs and after its state shows (default 400 and
|
|
53
|
+
* 900).
|
|
54
|
+
*/
|
|
51
55
|
pacing?: {
|
|
52
56
|
before: number;
|
|
53
57
|
after: number;
|
|
@@ -56,12 +60,42 @@ export type BunWebViewDriverOptions = {
|
|
|
56
60
|
concurrency?: number;
|
|
57
61
|
};
|
|
58
62
|
/**
|
|
59
|
-
*
|
|
60
|
-
* install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
63
|
+
* Drives a web app in Bun's built-in headless browser for `atlas run`: the system WebKit on macOS (nothing to
|
|
64
|
+
* install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about ten, so it is the
|
|
65
|
+
* quickest way to run a chart against a real page. Each path attempt gets its own view, closed afterwards. Screenshots
|
|
66
|
+
* are PNG files without a thumbnail. Clips are encoded from screenshots with FFmpeg (no clip is recorded without it).
|
|
67
|
+
* `user.tap` and `user.type` wait up to `actionTimeoutMs` for the target signal to show, then click its centre; a
|
|
68
|
+
* target that never shows fails the step with "<signal> is not on screen". Needs the Bun runtime (run
|
|
69
|
+
* `bun --bun atlas run`), and throws on open without it. There is no fake clock, so time events use the app's own
|
|
70
|
+
* controls.
|
|
71
|
+
*
|
|
72
|
+
* @see docs/statecharts.md
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* import { defineConfig } from '@crvouga/atlas';
|
|
77
|
+
* import { bunWebViewDriver, screen, text } from '@crvouga/atlas/bun';
|
|
78
|
+
*
|
|
79
|
+
* export default defineConfig({
|
|
80
|
+
* specs: './specs',
|
|
81
|
+
* driver: () => bunWebViewDriver({ baseUrl: 'http://127.0.0.1:4317' }),
|
|
82
|
+
* implementation: {
|
|
83
|
+
* async setup(ctx) { await ctx.goto('/'); },
|
|
84
|
+
* events: {
|
|
85
|
+
* // one entry per event of the spec
|
|
86
|
+
* },
|
|
87
|
+
* states: { 'No todos': screen({ all: [text('Nothing to do yet')] }) }
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
64
91
|
*/
|
|
65
92
|
export declare function bunWebViewDriver(options?: BunWebViewDriverOptions): Driver<WebViewContext>;
|
|
66
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* Builds a state implementation for a `WebViewContext` from its signals in the page: every `all` signal visible, one
|
|
95
|
+
* `any` signal visible (when given), no `none` signal visible. It is core's `signatureScreen` over `ctx.isVisible`, so
|
|
96
|
+
* it takes the same spec as `screen` from `@crvouga/atlas/signals` (`checks`, `transient`, `sameAs`, `lookIn`,
|
|
97
|
+
* `settle` included).
|
|
98
|
+
*
|
|
99
|
+
* @see docs/statecharts.md
|
|
100
|
+
*/
|
|
67
101
|
export declare const screen: (spec: import('../../core/src/signals.js').ScreenSpec<WebViewContext, Signal>) => import('../../core/src/index.js').StateImplementation<WebViewContext>;
|
package/dist/bun/src/driver.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Bun WebView driver
|
|
3
|
+
*
|
|
4
|
+
* `bunWebViewDriver()` is the core `Driver` that runs a statechart's paths in Bun's built-in headless browser
|
|
5
|
+
* (`Bun.WebView`), the quickest way to run a chart against a real page. It provides a `WebViewContext` whose
|
|
6
|
+
* `user.tap` and `user.type` act on `Signal`s, found by the shared in-page DOM probe from core, so an implementation
|
|
7
|
+
* written against `SignalContext` runs here and on the other web drivers unchanged. `Bun.WebView` is typed
|
|
8
|
+
* structurally (`BunWebView`), so this package builds without Bun's types; at run time the Bun runtime is required.
|
|
9
|
+
*
|
|
10
|
+
* @see docs/statecharts.md
|
|
11
|
+
*/
|
|
1
12
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
13
|
import path from 'node:path';
|
|
3
14
|
import { recordFrames } from '../../core/src/index.js';
|
|
@@ -51,11 +62,34 @@ function contextFor(view, baseUrl, timeline, options) {
|
|
|
51
62
|
return ctx;
|
|
52
63
|
}
|
|
53
64
|
/**
|
|
54
|
-
*
|
|
55
|
-
* install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
65
|
+
* Drives a web app in Bun's built-in headless browser for `atlas run`: the system WebKit on macOS (nothing to
|
|
66
|
+
* install), Chrome over CDP elsewhere. A view starts in milliseconds and screenshots take about ten, so it is the
|
|
67
|
+
* quickest way to run a chart against a real page. Each path attempt gets its own view, closed afterwards. Screenshots
|
|
68
|
+
* are PNG files without a thumbnail. Clips are encoded from screenshots with FFmpeg (no clip is recorded without it).
|
|
69
|
+
* `user.tap` and `user.type` wait up to `actionTimeoutMs` for the target signal to show, then click its centre; a
|
|
70
|
+
* target that never shows fails the step with "<signal> is not on screen". Needs the Bun runtime (run
|
|
71
|
+
* `bun --bun atlas run`), and throws on open without it. There is no fake clock, so time events use the app's own
|
|
72
|
+
* controls.
|
|
73
|
+
*
|
|
74
|
+
* @see docs/statecharts.md
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { defineConfig } from '@crvouga/atlas';
|
|
79
|
+
* import { bunWebViewDriver, screen, text } from '@crvouga/atlas/bun';
|
|
80
|
+
*
|
|
81
|
+
* export default defineConfig({
|
|
82
|
+
* specs: './specs',
|
|
83
|
+
* driver: () => bunWebViewDriver({ baseUrl: 'http://127.0.0.1:4317' }),
|
|
84
|
+
* implementation: {
|
|
85
|
+
* async setup(ctx) { await ctx.goto('/'); },
|
|
86
|
+
* events: {
|
|
87
|
+
* // one entry per event of the spec
|
|
88
|
+
* },
|
|
89
|
+
* states: { 'No todos': screen({ all: [text('Nothing to do yet')] }) }
|
|
90
|
+
* }
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
59
93
|
*/
|
|
60
94
|
export function bunWebViewDriver(options = {}) {
|
|
61
95
|
const width = options.width ?? 390;
|
|
@@ -86,5 +120,12 @@ export function bunWebViewDriver(options = {}) {
|
|
|
86
120
|
hold: (_ctx, ms) => new Promise((r) => setTimeout(r, ms))
|
|
87
121
|
};
|
|
88
122
|
}
|
|
89
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* Builds a state implementation for a `WebViewContext` from its signals in the page: every `all` signal visible, one
|
|
125
|
+
* `any` signal visible (when given), no `none` signal visible. It is core's `signatureScreen` over `ctx.isVisible`, so
|
|
126
|
+
* it takes the same spec as `screen` from `@crvouga/atlas/signals` (`checks`, `transient`, `sameAs`, `lookIn`,
|
|
127
|
+
* `settle` included).
|
|
128
|
+
*
|
|
129
|
+
* @see docs/statecharts.md
|
|
130
|
+
*/
|
|
90
131
|
export const screen = signatureScreen((ctx, signal) => ctx.isVisible(signal), describeSignal);
|
package/dist/bun/src/index.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Bun WebView driver entry point (`@crvouga/atlas/bun`)
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the Bun WebView driver for statechart runs (`bunWebViewDriver`), its context and option types, `screen`
|
|
5
|
+
* for recognising states from signals, and the signal constructors. Needs the Bun runtime.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/statecharts.md
|
|
8
|
+
*/
|
|
1
9
|
export { bunWebViewDriver, screen, type BunWebView, type BunWebViewDriverOptions, type WebViewContext } from './driver.js';
|
|
2
10
|
export { css, label, role, testId, text, describeSignal, type Signal } from '../../core/src/signals.js';
|
package/dist/bun/src/index.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Bun WebView driver entry point (`@crvouga/atlas/bun`)
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the Bun WebView driver for statechart runs (`bunWebViewDriver`), its context and option types, `screen`
|
|
5
|
+
* for recognising states from signals, and the signal constructors. Needs the Bun runtime.
|
|
6
|
+
*
|
|
7
|
+
* @see docs/statecharts.md
|
|
8
|
+
*/
|
|
1
9
|
export { bunWebViewDriver, screen } from './driver.js';
|
|
2
10
|
export { css, label, role, testId, text, describeSignal } from '../../core/src/signals.js';
|
package/dist/core/src/cli.d.ts
CHANGED
|
@@ -1 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module The `atlas` command
|
|
3
|
+
*
|
|
4
|
+
* Dispatches `atlas <command>`: the statechart commands (`lint`, `plan`, `run`, `merge`, `export`) and, loaded on demand so
|
|
5
|
+
* they cost nothing otherwise, `serve`, `dev`, `init` and `report`. Statechart configuration is `atlas.config.ts` (see
|
|
6
|
+
* `defineConfig`). A command that is wrong prints a message and exits 2; a plan, lint or run that finds problems exits 1.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/statecharts.md
|
|
9
|
+
* @see docs/reference/cli.md
|
|
10
|
+
*/
|
|
11
|
+
/** The text `atlas --help` prints: every command, and the flags of the statechart commands. */
|
|
12
|
+
export declare const USAGE = "atlas \u2014 executable statecharts\n\n atlas lint [--config atlas.config.ts | --specs <dir>] [--require-implementations]\n atlas plan [--config atlas.config.ts] [--state <name>]\n atlas run [--config atlas.config.ts] [--mode fast|showcase] [--workers n] [--state <name>]\n [--seed <name>]... [--paths id,id] [--shard i/n] [--rerun-failed | --reuse <run-dir>]\n [--no-retry] [--output <dir>]\n atlas merge [--config atlas.config.ts] [--output <dir>] <run-dir> <run-dir>...\n atlas export --specs <dir> --format scxml|mermaid|markdown|json [--out <file>]\n atlas server [--data <dir>] [--port 8080] [--store <url>]... one Atlas node: API, projects and client\n atlas client build [--no-data] [--out <dir>] build the project-agnostic Atlas client\n atlas dev [--port 5180] develop the Atlas server and client on one host\n atlas init [--server <url>] [--write] integrate this project: detect its suites, print the plan (atlas init --help)\n atlas report publish|stream|status|merge|doctor|policy \u2026 layered evidence for any kind of spec (atlas report --help)\n\n --workers path attempts that run at once (default: one per CPU, capped by the driver)\n --seed only paths that start from this seed (\"start\" for paths setup starts); repeatable\n --shard 2/4 run the second quarter of the plan; merge the shards' runs afterwards\n --rerun-failed keep the newest run's passed paths and run only the rest\n";
|
|
13
|
+
/** Runs `atlas` with `argv` (default: the process arguments) and returns the exit code. Throws for a command that is wrong, which the `atlas` binary reports as a message and exit code 2. */
|
|
14
|
+
export declare function main(argv?: string[]): Promise<number>;
|
package/dist/core/src/cli.js
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module The `atlas` command
|
|
3
|
+
*
|
|
4
|
+
* Dispatches `atlas <command>`: the statechart commands (`lint`, `plan`, `run`, `merge`, `export`) and, loaded on demand so
|
|
5
|
+
* they cost nothing otherwise, `serve`, `dev`, `init` and `report`. Statechart configuration is `atlas.config.ts` (see
|
|
6
|
+
* `defineConfig`). A command that is wrong prints a message and exits 2; a plan, lint or run that finds problems exits 1.
|
|
7
|
+
*
|
|
8
|
+
* @see docs/statecharts.md
|
|
9
|
+
* @see docs/reference/cli.md
|
|
10
|
+
*/
|
|
1
11
|
import { writeFileSync } from 'node:fs';
|
|
2
12
|
import path from 'node:path';
|
|
3
13
|
import { pathToFileURL } from 'node:url';
|
|
@@ -8,7 +18,8 @@ import { toMarkdown } from './report/markdown.js';
|
|
|
8
18
|
import { composeCharts } from './spec/compose.js';
|
|
9
19
|
import { loadSpecDirectory } from './spec/load.js';
|
|
10
20
|
import { machineToScxml } from './spec/scxml.js';
|
|
11
|
-
|
|
21
|
+
/** The text `atlas --help` prints: every command, and the flags of the statechart commands. */
|
|
22
|
+
export const USAGE = `atlas — executable statecharts
|
|
12
23
|
|
|
13
24
|
atlas lint [--config atlas.config.ts | --specs <dir>] [--require-implementations]
|
|
14
25
|
atlas plan [--config atlas.config.ts] [--state <name>]
|
|
@@ -17,6 +28,11 @@ const USAGE = `atlas — executable statecharts
|
|
|
17
28
|
[--no-retry] [--output <dir>]
|
|
18
29
|
atlas merge [--config atlas.config.ts] [--output <dir>] <run-dir> <run-dir>...
|
|
19
30
|
atlas export --specs <dir> --format scxml|mermaid|markdown|json [--out <file>]
|
|
31
|
+
atlas server [--data <dir>] [--port 8080] [--store <url>]... one Atlas node: API, projects and client
|
|
32
|
+
atlas client build [--no-data] [--out <dir>] build the project-agnostic Atlas client
|
|
33
|
+
atlas dev [--port 5180] develop the Atlas server and client on one host
|
|
34
|
+
atlas init [--server <url>] [--write] integrate this project: detect its suites, print the plan (atlas init --help)
|
|
35
|
+
atlas report publish|stream|status|merge|doctor|policy … layered evidence for any kind of spec (atlas report --help)
|
|
20
36
|
|
|
21
37
|
--workers path attempts that run at once (default: one per CPU, capped by the driver)
|
|
22
38
|
--seed only paths that start from this seed ("start" for paths setup starts); repeatable
|
|
@@ -69,8 +85,26 @@ async function loadConfig(file) {
|
|
|
69
85
|
throw new Error(`${file} has no default export (use defineConfig)`);
|
|
70
86
|
return { config: mod.default, base: path.dirname(absolute) };
|
|
71
87
|
}
|
|
88
|
+
/** Runs `atlas` with `argv` (default: the process arguments) and returns the exit code. Throws for a command that is wrong, which the `atlas` binary reports as a message and exit code 2. */
|
|
72
89
|
export async function main(argv = process.argv.slice(2)) {
|
|
73
90
|
const [command] = argv;
|
|
91
|
+
// Loaded on demand: lint, plan and run do not pay for the reports.
|
|
92
|
+
if (command === 'serve' || command === 'server') {
|
|
93
|
+
const { serveMain } = await import('../../server/src/main.js');
|
|
94
|
+
return serveMain(argv.slice(1), { out: text => process.stdout.write(text) });
|
|
95
|
+
}
|
|
96
|
+
if (command === 'client') {
|
|
97
|
+
const { clientMain } = await import('../../server/src/site.js');
|
|
98
|
+
return clientMain(argv.slice(1));
|
|
99
|
+
}
|
|
100
|
+
if (command === 'dev') {
|
|
101
|
+
const { devMain } = await import('../../server/src/dev.js');
|
|
102
|
+
return devMain(argv.slice(1), { out: text => process.stdout.write(text) });
|
|
103
|
+
}
|
|
104
|
+
if (command === 'init')
|
|
105
|
+
return (await import('../../reports/src/init.js')).initMain(argv.slice(1), { out: text => process.stdout.write(text) });
|
|
106
|
+
if (command === 'report')
|
|
107
|
+
return (await import('../../reports/src/report-cli.js')).runReportCommand(argv.slice(1));
|
|
74
108
|
const configFile = flag(argv, 'config') ?? 'atlas.config.ts';
|
|
75
109
|
const specs = flag(argv, 'specs');
|
|
76
110
|
const output = flag(argv, 'output');
|
|
@@ -1,13 +1,21 @@
|
|
|
1
|
+
import { type LiveReporterOptions } from '../../reports/src/live-reporter.js';
|
|
1
2
|
import type { StateValue } from './graph.js';
|
|
2
3
|
import type { Shard } from './run/execute.js';
|
|
3
4
|
import type { Driver, EventMatcher, EventSource, Implementation, PrivacyRules, RunMode } from './run/types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Everything a project says about running its specs. `C` is the type of the driver's context
|
|
7
|
+
* (a Playwright `Page`, a model, ...), which events and states receive.
|
|
8
|
+
*/
|
|
4
9
|
export type AtlasConfig<C = unknown> = {
|
|
5
10
|
/** The directory holding the charts (`*.scxml`, `*.machine.{json,yaml}`) and `journeys.yaml`. */
|
|
6
11
|
specs: string;
|
|
12
|
+
/** Live reporting endpoint. Defaults to ATLAS_SERVER_URL when set; false disables streaming. */
|
|
13
|
+
reporting?: LiveReporterOptions | false;
|
|
7
14
|
/** The chart to run; the root chart when omitted. */
|
|
8
15
|
chart?: string;
|
|
9
16
|
/** Where generated paths start (an XState state value); the initial state when omitted. */
|
|
10
17
|
start?: StateValue;
|
|
18
|
+
/** A phrase describing `start` in reports; `The start of the chart` when omitted. */
|
|
11
19
|
startLabel?: string;
|
|
12
20
|
/** Only these events enter the chart from outside it. */
|
|
13
21
|
entryEvents?: string[];
|
|
@@ -17,27 +25,61 @@ export type AtlasConfig<C = unknown> = {
|
|
|
17
25
|
workers?: number;
|
|
18
26
|
/** Runs once before any path: prepare what every seed relies on (reference data, config). */
|
|
19
27
|
beforeRun?: () => Promise<void> | void;
|
|
28
|
+
/** The driver, or a function that creates it (called once per run, after `beforeRun`). */
|
|
20
29
|
driver: Driver<C> | (() => Driver<C> | Promise<Driver<C>>);
|
|
30
|
+
/** How to make each event happen and recognise each state. */
|
|
21
31
|
implementation: Implementation<C>;
|
|
22
32
|
/** Where runs are written; `atlas-runs` beside the config when omitted. */
|
|
23
33
|
output?: string;
|
|
34
|
+
/** Creates the business event sources for a run (called once per run; the run closes them). */
|
|
24
35
|
eventSources?: () => EventSource[] | Promise<EventSource[]>;
|
|
36
|
+
/** How each business event name from `meta.events` is recognised; by default a CloudEvent whose `type` equals the name. */
|
|
25
37
|
eventMatchers?: Record<string, EventMatcher>;
|
|
38
|
+
/** Extra privacy rules on top of the defaults. */
|
|
26
39
|
privacy?: PrivacyRules;
|
|
27
40
|
/** URLs the run will reach; checked against `privacy.allowHosts` (loopback by default). */
|
|
28
41
|
targets?: string[];
|
|
42
|
+
/** Recorded in the manifest as the run's environment (`run.environment`), beside the driver name. */
|
|
29
43
|
environment?: Record<string, unknown>;
|
|
44
|
+
/** How long to wait for a state to be recognised after an event, in milliseconds; 45 000 when omitted. */
|
|
30
45
|
stepTimeoutMs?: number;
|
|
31
46
|
/** Meta fields every state must carry (default: description). */
|
|
32
47
|
requiredMeta?: string[];
|
|
33
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* Declares an Atlas config with types, returning it unchanged. Put it as the default export of
|
|
51
|
+
* `atlas.config.ts`; the CLI loads the file with `tsx` and defaults to `atlas.config.ts` in the
|
|
52
|
+
* current directory.
|
|
53
|
+
*
|
|
54
|
+
* @see docs/statecharts.md
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* export default defineConfig({
|
|
58
|
+
* specs: './specs',
|
|
59
|
+
* driver: () => functionDriver(() => new TodoModel()),
|
|
60
|
+
* implementation: {
|
|
61
|
+
* events: { 'Adds a todo': { kind: 'user', how: 'Calls add().', run: async (model) => model.add('x') } },
|
|
62
|
+
* states: { 'No todos': { recognize: async (model) => ({ matched: model.count === 0, signals: [] }) } }
|
|
63
|
+
* }
|
|
64
|
+
* });
|
|
65
|
+
*/
|
|
34
66
|
export declare function defineConfig<C>(config: AtlasConfig<C>): AtlasConfig<C>;
|
|
35
|
-
/**
|
|
67
|
+
/** Overrides of a config that the command line can give. */
|
|
36
68
|
export type PrepareOptions = {
|
|
37
69
|
/** Scope the run to this state instead of the config's. */
|
|
38
70
|
state?: string;
|
|
39
71
|
};
|
|
40
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Loads, lints and plans a config without running anything (what `atlas lint` and `atlas plan` do).
|
|
74
|
+
*
|
|
75
|
+
* @param baseDirectory what a relative `config.specs` resolves against.
|
|
76
|
+
* @returns the loaded `bundle`; `lint` (findings, composition and graph, including `implemented`
|
|
77
|
+
* findings for what the implementation lacks); the run's `scope`; the `plan` (paths, journeys, seeds,
|
|
78
|
+
* `unreachable`); and the resolved `specs` directory.
|
|
79
|
+
* @throws Error when the specs cannot be loaded or composed, when a seed's `shows` is not active where
|
|
80
|
+
* it starts, or when a seed's `for` names an event no state handles. Lint findings are returned,
|
|
81
|
+
* not thrown.
|
|
82
|
+
*/
|
|
41
83
|
export declare function prepare<C>(config: AtlasConfig<C>, baseDirectory?: string, options?: PrepareOptions): {
|
|
42
84
|
bundle: import('./index.js').SpecBundle;
|
|
43
85
|
lint: {
|
|
@@ -82,22 +124,43 @@ export declare function prepare<C>(config: AtlasConfig<C>, baseDirectory?: strin
|
|
|
82
124
|
};
|
|
83
125
|
specs: string;
|
|
84
126
|
};
|
|
127
|
+
/** The options of `atlas run` that `runConfig` accepts; each overrides the config's own setting. */
|
|
85
128
|
export type RunCommandOptions = PrepareOptions & {
|
|
129
|
+
/** `fast` when omitted. */
|
|
86
130
|
mode?: RunMode;
|
|
131
|
+
/** Override live reporting. Defaults to config.reporting or ATLAS_SERVER_URL. */
|
|
132
|
+
reporting?: LiveReporterOptions | false;
|
|
87
133
|
/** Only these paths, by id. */
|
|
88
134
|
paths?: string[];
|
|
89
135
|
/** Only paths that start from these seeds ("start" for paths that `setup` starts). */
|
|
90
136
|
seeds?: string[];
|
|
137
|
+
/** Whether a failed path runs again to tell flaky from broken; true unless `false`. */
|
|
91
138
|
retry?: boolean;
|
|
139
|
+
/** Where the run is written; the config's `output`, else `atlas-runs`. */
|
|
92
140
|
output?: string;
|
|
141
|
+
/** Path attempts at once; the config's `workers`, else one per CPU, always capped by the driver. */
|
|
93
142
|
workers?: number;
|
|
94
143
|
/** Run one shard of the plan; `atlas merge` composes the shards. */
|
|
95
144
|
shard?: Shard;
|
|
96
145
|
/** Keep the passed paths of this run (or the newest run, with "latest") and run the rest. */
|
|
97
146
|
reuse?: string;
|
|
147
|
+
/** Receives progress lines; stdout when omitted. */
|
|
98
148
|
log?: (line: string) => void;
|
|
99
149
|
};
|
|
100
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Runs a config end to end and writes the run (manifest, reports, media) under its output
|
|
152
|
+
* directory, like `atlas run`.
|
|
153
|
+
*
|
|
154
|
+
* Refuses to start (throws) when the spec has any structural lint finding (everything but missing
|
|
155
|
+
* implementations, which just block paths) or when a `targets` URL is not on the privacy allow-list.
|
|
156
|
+
* Then it calls `beforeRun`, creates the driver and runs the planned paths (filtered by
|
|
157
|
+
* `options.paths`/`seeds`/`shard`, reusing earlier passes when `options.reuse` is set).
|
|
158
|
+
*
|
|
159
|
+
* @returns what `runPaths` returns: the run directory, the manifest and `ok` (false if any path
|
|
160
|
+
* failed or the privacy scan found something).
|
|
161
|
+
* @throws Error also when `reuse` names a run with no outcomes or there is no earlier run for `latest`.
|
|
162
|
+
* @see docs/statecharts.md
|
|
163
|
+
*/
|
|
101
164
|
export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunCommandOptions, baseDirectory?: string): Promise<{
|
|
102
165
|
runDir: string;
|
|
103
166
|
manifest: {
|
|
@@ -202,6 +265,7 @@ export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunComman
|
|
|
202
265
|
key: string;
|
|
203
266
|
name: string;
|
|
204
267
|
kind: import('./plan.js').PlannedPath["kind"];
|
|
268
|
+
progress?: "queued" | "running" | "complete";
|
|
205
269
|
status: import('./index.js').Status;
|
|
206
270
|
attempts: {
|
|
207
271
|
status: "passed" | "failed";
|
|
@@ -285,7 +349,15 @@ export declare function runConfig<C>(config: AtlasConfig<C>, options?: RunComman
|
|
|
285
349
|
};
|
|
286
350
|
ok: boolean;
|
|
287
351
|
}>;
|
|
288
|
-
/**
|
|
352
|
+
/**
|
|
353
|
+
* Composes runs of a config (its shards, or a rerun and the run before it) into one new run
|
|
354
|
+
* under the output directory, like `atlas merge`. The plan is recomputed from the config, so the runs
|
|
355
|
+
* must come from the same specs, implementation and seeds.
|
|
356
|
+
*
|
|
357
|
+
* @param runDirs the run directories to compose; later ones win when two ran the same path.
|
|
358
|
+
* @returns what `mergeRuns` returns: the new run directory, its manifest and `ok`.
|
|
359
|
+
* @throws Error when a run directory has no `outcomes.json`.
|
|
360
|
+
*/
|
|
289
361
|
export declare function mergeConfigRuns<C>(config: AtlasConfig<C>, runDirs: string[], options?: PrepareOptions & {
|
|
290
362
|
output?: string;
|
|
291
363
|
}, baseDirectory?: string): {
|
|
@@ -392,6 +464,7 @@ export declare function mergeConfigRuns<C>(config: AtlasConfig<C>, runDirs: stri
|
|
|
392
464
|
key: string;
|
|
393
465
|
name: string;
|
|
394
466
|
kind: import('./plan.js').PlannedPath["kind"];
|
|
467
|
+
progress?: "queued" | "running" | "complete";
|
|
395
468
|
status: import('./index.js').Status;
|
|
396
469
|
attempts: {
|
|
397
470
|
status: "passed" | "failed";
|
package/dist/core/src/config.js
CHANGED
|
@@ -1,14 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module Config and programmatic API
|
|
3
|
+
*
|
|
4
|
+
* The user-facing entry point: `defineConfig` types a project's `atlas.config.ts`, and `prepare`,
|
|
5
|
+
* `runConfig` and `mergeConfigRuns` are the programmatic equivalents of `atlas lint`/`plan`, `atlas
|
|
6
|
+
* run` and `atlas merge`. They wire the pieces together (load specs, lint, scope, plan, run) and add
|
|
7
|
+
* no behaviour of their own beyond validating the config against the spec. Relative paths in a config
|
|
8
|
+
* resolve against the `baseDirectory` argument (the config file's directory when called by the CLI).
|
|
9
|
+
*
|
|
10
|
+
* @see docs/statecharts.md
|
|
11
|
+
*/
|
|
1
12
|
import { availableParallelism } from 'node:os';
|
|
2
13
|
import path from 'node:path';
|
|
14
|
+
import { createLiveReporter } from '../../reports/src/live-reporter.js';
|
|
15
|
+
import { httpStore } from '../../reports/src/http-store.js';
|
|
16
|
+
import { publishChecks } from '../../reports/src/publish-checks.js';
|
|
17
|
+
import { publishRunBundle } from '../../reports/src/run-bundle.js';
|
|
18
|
+
import { checksFromManifest } from '../../reports/src/ingest.js';
|
|
3
19
|
import { lintBundle } from './lint.js';
|
|
4
20
|
import { chartScope, planChart } from './plan.js';
|
|
5
21
|
import { assertAllowedTarget, mergePrivacy } from './privacy.js';
|
|
6
22
|
import { latestRun, mergeRuns, readOutcomes, runPaths, shardPaths } from './run/execute.js';
|
|
7
23
|
import { loadSpecDirectory } from './spec/load.js';
|
|
24
|
+
/**
|
|
25
|
+
* Declares an Atlas config with types, returning it unchanged. Put it as the default export of
|
|
26
|
+
* `atlas.config.ts`; the CLI loads the file with `tsx` and defaults to `atlas.config.ts` in the
|
|
27
|
+
* current directory.
|
|
28
|
+
*
|
|
29
|
+
* @see docs/statecharts.md
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* export default defineConfig({
|
|
33
|
+
* specs: './specs',
|
|
34
|
+
* driver: () => functionDriver(() => new TodoModel()),
|
|
35
|
+
* implementation: {
|
|
36
|
+
* events: { 'Adds a todo': { kind: 'user', how: 'Calls add().', run: async (model) => model.add('x') } },
|
|
37
|
+
* states: { 'No todos': { recognize: async (model) => ({ matched: model.count === 0, signals: [] }) } }
|
|
38
|
+
* }
|
|
39
|
+
* });
|
|
40
|
+
*/
|
|
8
41
|
export function defineConfig(config) {
|
|
9
42
|
return config;
|
|
10
43
|
}
|
|
11
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Loads, lints and plans a config without running anything (what `atlas lint` and `atlas plan` do).
|
|
46
|
+
*
|
|
47
|
+
* @param baseDirectory what a relative `config.specs` resolves against.
|
|
48
|
+
* @returns the loaded `bundle`; `lint` (findings, composition and graph, including `implemented`
|
|
49
|
+
* findings for what the implementation lacks); the run's `scope`; the `plan` (paths, journeys, seeds,
|
|
50
|
+
* `unreachable`); and the resolved `specs` directory.
|
|
51
|
+
* @throws Error when the specs cannot be loaded or composed, when a seed's `shows` is not active where
|
|
52
|
+
* it starts, or when a seed's `for` names an event no state handles. Lint findings are returned,
|
|
53
|
+
* not thrown.
|
|
54
|
+
*/
|
|
12
55
|
export function prepare(config, baseDirectory = process.cwd(), options = {}) {
|
|
13
56
|
const specs = path.resolve(baseDirectory, config.specs);
|
|
14
57
|
const bundle = loadSpecDirectory(specs);
|
|
@@ -60,7 +103,20 @@ const contextOf = (config, prepared) => ({
|
|
|
60
103
|
...(config.privacy ? { privacy: config.privacy } : {}),
|
|
61
104
|
...(config.environment ? { environment: config.environment } : {})
|
|
62
105
|
});
|
|
63
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Runs a config end to end and writes the run (manifest, reports, media) under its output
|
|
108
|
+
* directory, like `atlas run`.
|
|
109
|
+
*
|
|
110
|
+
* Refuses to start (throws) when the spec has any structural lint finding (everything but missing
|
|
111
|
+
* implementations, which just block paths) or when a `targets` URL is not on the privacy allow-list.
|
|
112
|
+
* Then it calls `beforeRun`, creates the driver and runs the planned paths (filtered by
|
|
113
|
+
* `options.paths`/`seeds`/`shard`, reusing earlier passes when `options.reuse` is set).
|
|
114
|
+
*
|
|
115
|
+
* @returns what `runPaths` returns: the run directory, the manifest and `ok` (false if any path
|
|
116
|
+
* failed or the privacy scan found something).
|
|
117
|
+
* @throws Error also when `reuse` names a run with no outcomes or there is no earlier run for `latest`.
|
|
118
|
+
* @see docs/statecharts.md
|
|
119
|
+
*/
|
|
64
120
|
export async function runConfig(config, options = {}, baseDirectory = process.cwd()) {
|
|
65
121
|
const prepared = prepare(config, baseDirectory, options);
|
|
66
122
|
const structural = prepared.lint.findings.filter((f) => f.rule !== 'implemented');
|
|
@@ -78,22 +134,59 @@ export async function runConfig(config, options = {}, baseDirectory = process.cw
|
|
|
78
134
|
const reused = reuseDir ? readOutcomes(reuseDir) : null;
|
|
79
135
|
if (options.reuse && !reused)
|
|
80
136
|
throw new Error(`There is no earlier run to reuse${reuseDir ? ` at ${reuseDir}` : ''}`);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
137
|
+
const requestedReporting = options.reporting ?? config.reporting ?? (process.env.ATLAS_SERVER_URL ? { url: process.env.ATLAS_SERVER_URL, token: process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN } : undefined);
|
|
138
|
+
const reporting = requestedReporting ? { ...requestedReporting, project: requestedReporting.project ?? process.env.ATLAS_PROJECT, token: requestedReporting.token ?? process.env.ATLAS_PUBLISH_TOKEN ?? process.env.ATLAS_TOKEN } : undefined;
|
|
139
|
+
let live;
|
|
140
|
+
const onProgress = reporting ? (manifest) => {
|
|
141
|
+
if (!manifest.privacy.passed)
|
|
142
|
+
return;
|
|
143
|
+
live ??= createLiveReporter({ producer: process.env.ATLAS_PRODUCER ?? 'atlas-statecharts', title: `${prepared.scope.chart} · ${options.mode ?? 'fast'}`,
|
|
144
|
+
plannedChecks: paths.length, environment: process.env.ATLAS_ENVIRONMENT ?? 'desktop-web', branch: manifest.run.branch ?? undefined, sha: manifest.run.commit ?? undefined }, reporting);
|
|
145
|
+
const ingested = checksFromManifest(manifest);
|
|
146
|
+
ingested.checks.forEach((check, index) => {
|
|
147
|
+
if (manifest.paths[index]?.progress === 'queued' && !manifest.run.finishedAt)
|
|
148
|
+
return;
|
|
149
|
+
live.check({ ...check, steps: check.steps?.slice(-20).map(step => ({ name: step.name, status: step.status })) });
|
|
150
|
+
});
|
|
151
|
+
} : undefined;
|
|
152
|
+
try {
|
|
153
|
+
const outcome = await runPaths({
|
|
154
|
+
...contextOf(config, prepared),
|
|
155
|
+
paths,
|
|
156
|
+
driver,
|
|
157
|
+
mode: options.mode ?? 'fast',
|
|
158
|
+
outputRoot,
|
|
159
|
+
...(options.retry === undefined ? {} : { retry: options.retry }),
|
|
160
|
+
...(config.stepTimeoutMs === undefined ? {} : { stepTimeoutMs: config.stepTimeoutMs }),
|
|
161
|
+
eventSources: config.eventSources ? await config.eventSources() : [],
|
|
162
|
+
workers: options.workers ?? config.workers ?? availableParallelism(),
|
|
163
|
+
...(options.shard ? { shard: options.shard } : {}),
|
|
164
|
+
...(reused && reuseDir ? { reuse: { runDir: reuseDir, outcomes: reused.outcomes } } : {}),
|
|
165
|
+
...(options.log ? { log: options.log } : {}), ...(onProgress ? { onProgress } : {})
|
|
166
|
+
});
|
|
167
|
+
await live?.finish(outcome.manifest.privacy.passed ? 'completed' : 'interrupted', outcome.manifest.privacy.passed ? undefined : 'Run failed its privacy scan; unsafe progress was withheld.');
|
|
168
|
+
if (reporting && outcome.manifest.privacy.passed) {
|
|
169
|
+
const store = httpStore({ url: reporting.url, project: reporting.project, token: reporting.token });
|
|
170
|
+
await publishChecks(store, { producer: process.env.ATLAS_PRODUCER ?? 'atlas-statecharts', environment: process.env.ATLAS_ENVIRONMENT ?? 'desktop-web',
|
|
171
|
+
branch: outcome.manifest.run.branch, sha: outcome.manifest.run.commit, recordedAtMs: Math.max(Date.now(), (live?.finishedAtMs ?? 0) + 1), checks: checksFromManifest(outcome.manifest).checks.map(check => ({ ...check, measurements: [...check.measurements] })) });
|
|
172
|
+
await publishRunBundle(store, outcome.runDir);
|
|
173
|
+
}
|
|
174
|
+
return outcome;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
await live?.finish('interrupted', 'The producer exited before completing the run.').catch(() => { });
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
95
180
|
}
|
|
96
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* Composes runs of a config (its shards, or a rerun and the run before it) into one new run
|
|
183
|
+
* under the output directory, like `atlas merge`. The plan is recomputed from the config, so the runs
|
|
184
|
+
* must come from the same specs, implementation and seeds.
|
|
185
|
+
*
|
|
186
|
+
* @param runDirs the run directories to compose; later ones win when two ran the same path.
|
|
187
|
+
* @returns what `mergeRuns` returns: the new run directory, its manifest and `ok`.
|
|
188
|
+
* @throws Error when a run directory has no `outcomes.json`.
|
|
189
|
+
*/
|
|
97
190
|
export function mergeConfigRuns(config, runDirs, options = {}, baseDirectory = process.cwd()) {
|
|
98
191
|
const prepared = prepare(config, baseDirectory, options);
|
|
99
192
|
return mergeRuns(contextOf(config, prepared), prepared.plan.paths, runDirs.map((d) => path.resolve(d)), { outputRoot: path.resolve(baseDirectory, options.output ?? config.output ?? 'atlas-runs') });
|