@e2edev/e2e 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/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/agent/act-validation.d.ts +27 -0
- package/dist/agent/act-validation.d.ts.map +1 -0
- package/dist/agent/act-validation.js +121 -0
- package/dist/agent/act-validation.js.map +1 -0
- package/dist/agent/act.d.ts +27 -0
- package/dist/agent/act.d.ts.map +1 -0
- package/dist/agent/act.js +775 -0
- package/dist/agent/act.js.map +1 -0
- package/dist/agent/actions.d.ts +66 -0
- package/dist/agent/actions.d.ts.map +1 -0
- package/dist/agent/actions.js +82 -0
- package/dist/agent/actions.js.map +1 -0
- package/dist/agent/ai-sdk.d.ts +16 -0
- package/dist/agent/ai-sdk.d.ts.map +1 -0
- package/dist/agent/ai-sdk.js +59 -0
- package/dist/agent/ai-sdk.js.map +1 -0
- package/dist/agent/call-options.d.ts +10 -0
- package/dist/agent/call-options.d.ts.map +1 -0
- package/dist/agent/call-options.js +28 -0
- package/dist/agent/call-options.js.map +1 -0
- package/dist/agent/default-agent.d.ts +22 -0
- package/dist/agent/default-agent.d.ts.map +1 -0
- package/dist/agent/default-agent.js +354 -0
- package/dist/agent/default-agent.js.map +1 -0
- package/dist/agent/error.d.ts +53 -0
- package/dist/agent/error.d.ts.map +1 -0
- package/dist/agent/error.js +94 -0
- package/dist/agent/error.js.map +1 -0
- package/dist/agent/executor.d.ts +238 -0
- package/dist/agent/executor.d.ts.map +1 -0
- package/dist/agent/executor.js +56 -0
- package/dist/agent/executor.js.map +1 -0
- package/dist/agent/index.d.ts +15 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +304 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/invocation.d.ts +194 -0
- package/dist/agent/invocation.d.ts.map +1 -0
- package/dist/agent/invocation.js +389 -0
- package/dist/agent/invocation.js.map +1 -0
- package/dist/agent/ledger.d.ts +24 -0
- package/dist/agent/ledger.d.ts.map +1 -0
- package/dist/agent/ledger.js +48 -0
- package/dist/agent/ledger.js.map +1 -0
- package/dist/agent/loop-guards.d.ts +35 -0
- package/dist/agent/loop-guards.d.ts.map +1 -0
- package/dist/agent/loop-guards.js +110 -0
- package/dist/agent/loop-guards.js.map +1 -0
- package/dist/agent/model/adapter.d.ts +97 -0
- package/dist/agent/model/adapter.d.ts.map +1 -0
- package/dist/agent/model/adapter.js +40 -0
- package/dist/agent/model/adapter.js.map +1 -0
- package/dist/agent/model/router.d.ts +36 -0
- package/dist/agent/model/router.d.ts.map +1 -0
- package/dist/agent/model/router.js +45 -0
- package/dist/agent/model/router.js.map +1 -0
- package/dist/agent/model/schema.d.ts +16 -0
- package/dist/agent/model/schema.d.ts.map +1 -0
- package/dist/agent/model/schema.js +37 -0
- package/dist/agent/model/schema.js.map +1 -0
- package/dist/agent/model/sdk.d.ts +28 -0
- package/dist/agent/model/sdk.d.ts.map +1 -0
- package/dist/agent/model/sdk.js +258 -0
- package/dist/agent/model/sdk.js.map +1 -0
- package/dist/agent/observation.d.ts +70 -0
- package/dist/agent/observation.d.ts.map +1 -0
- package/dist/agent/observation.js +174 -0
- package/dist/agent/observation.js.map +1 -0
- package/dist/agent/phases.d.ts +71 -0
- package/dist/agent/phases.d.ts.map +1 -0
- package/dist/agent/phases.js +124 -0
- package/dist/agent/phases.js.map +1 -0
- package/dist/agent/prompts.d.ts +40 -0
- package/dist/agent/prompts.d.ts.map +1 -0
- package/dist/agent/prompts.js +104 -0
- package/dist/agent/prompts.js.map +1 -0
- package/dist/agent/protocol.d.ts +31 -0
- package/dist/agent/protocol.d.ts.map +1 -0
- package/dist/agent/protocol.js +67 -0
- package/dist/agent/protocol.js.map +1 -0
- package/dist/agent/public.d.ts +12 -0
- package/dist/agent/public.d.ts.map +1 -0
- package/dist/agent/public.js +12 -0
- package/dist/agent/public.js.map +1 -0
- package/dist/agent/replay.d.ts +61 -0
- package/dist/agent/replay.d.ts.map +1 -0
- package/dist/agent/replay.js +185 -0
- package/dist/agent/replay.js.map +1 -0
- package/dist/agent/secrets.d.ts +22 -0
- package/dist/agent/secrets.d.ts.map +1 -0
- package/dist/agent/secrets.js +63 -0
- package/dist/agent/secrets.js.map +1 -0
- package/dist/agent/step-cache.d.ts +156 -0
- package/dist/agent/step-cache.d.ts.map +1 -0
- package/dist/agent/step-cache.js +301 -0
- package/dist/agent/step-cache.js.map +1 -0
- package/dist/agent/tool-loop.d.ts +51 -0
- package/dist/agent/tool-loop.d.ts.map +1 -0
- package/dist/agent/tool-loop.js +331 -0
- package/dist/agent/tool-loop.js.map +1 -0
- package/dist/agent/tool.d.ts +39 -0
- package/dist/agent/tool.d.ts.map +1 -0
- package/dist/agent/tool.js +52 -0
- package/dist/agent/tool.js.map +1 -0
- package/dist/backend/contract.d.ts +186 -0
- package/dist/backend/contract.d.ts.map +1 -0
- package/dist/backend/contract.js +65 -0
- package/dist/backend/contract.js.map +1 -0
- package/dist/backend/index.d.ts +316 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +219 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/session.d.ts +23 -0
- package/dist/backend/session.d.ts.map +1 -0
- package/dist/backend/session.js +213 -0
- package/dist/backend/session.js.map +1 -0
- package/dist/backend/surface.d.ts +83 -0
- package/dist/backend/surface.d.ts.map +1 -0
- package/dist/backend/surface.js +11 -0
- package/dist/backend/surface.js.map +1 -0
- package/dist/cache/anchors.d.ts +37 -0
- package/dist/cache/anchors.d.ts.map +1 -0
- package/dist/cache/anchors.js +89 -0
- package/dist/cache/anchors.js.map +1 -0
- package/dist/cache/context.d.ts +74 -0
- package/dist/cache/context.d.ts.map +1 -0
- package/dist/cache/context.js +82 -0
- package/dist/cache/context.js.map +1 -0
- package/dist/cache/decide.d.ts +42 -0
- package/dist/cache/decide.d.ts.map +1 -0
- package/dist/cache/decide.js +47 -0
- package/dist/cache/decide.js.map +1 -0
- package/dist/cache/identity.d.ts +113 -0
- package/dist/cache/identity.d.ts.map +1 -0
- package/dist/cache/identity.js +109 -0
- package/dist/cache/identity.js.map +1 -0
- package/dist/cache/recorder.d.ts +76 -0
- package/dist/cache/recorder.d.ts.map +1 -0
- package/dist/cache/recorder.js +143 -0
- package/dist/cache/recorder.js.map +1 -0
- package/dist/cache/relocate.d.ts +69 -0
- package/dist/cache/relocate.d.ts.map +1 -0
- package/dist/cache/relocate.js +125 -0
- package/dist/cache/relocate.js.map +1 -0
- package/dist/cache/store.d.ts +68 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +106 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cache/trace.d.ts +146 -0
- package/dist/cache/trace.d.ts.map +1 -0
- package/dist/cache/trace.js +249 -0
- package/dist/cache/trace.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +4 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +108 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +6 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +101 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/collect/collect.d.ts +44 -0
- package/dist/collect/collect.d.ts.map +1 -0
- package/dist/collect/collect.js +89 -0
- package/dist/collect/collect.js.map +1 -0
- package/dist/collect/registry.d.ts +47 -0
- package/dist/collect/registry.d.ts.map +1 -0
- package/dist/collect/registry.js +262 -0
- package/dist/collect/registry.js.map +1 -0
- package/dist/collect/select.d.ts +54 -0
- package/dist/collect/select.d.ts.map +1 -0
- package/dist/collect/select.js +230 -0
- package/dist/collect/select.js.map +1 -0
- package/dist/config/agent.d.ts +91 -0
- package/dist/config/agent.d.ts.map +1 -0
- package/dist/config/agent.js +232 -0
- package/dist/config/agent.js.map +1 -0
- package/dist/config/load.d.ts +23 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +75 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/resolve.d.ts +94 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +500 -0
- package/dist/config/resolve.js.map +1 -0
- package/dist/config/validate.d.ts +6 -0
- package/dist/config/validate.d.ts.map +1 -0
- package/dist/config/validate.js +21 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/credentials.d.ts +7 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +42 -0
- package/dist/credentials.js.map +1 -0
- package/dist/expect/async.d.ts +5 -0
- package/dist/expect/async.d.ts.map +1 -0
- package/dist/expect/async.js +186 -0
- package/dist/expect/async.js.map +1 -0
- package/dist/expect/index.d.ts +7 -0
- package/dist/expect/index.d.ts.map +1 -0
- package/dist/expect/index.js +23 -0
- package/dist/expect/index.js.map +1 -0
- package/dist/expect/values.d.ts +4 -0
- package/dist/expect/values.d.ts.map +1 -0
- package/dist/expect/values.js +108 -0
- package/dist/expect/values.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/ai-trace.d.ts +151 -0
- package/dist/internal/ai-trace.d.ts.map +1 -0
- package/dist/internal/ai-trace.js +360 -0
- package/dist/internal/ai-trace.js.map +1 -0
- package/dist/internal/brands.d.ts +9 -0
- package/dist/internal/brands.d.ts.map +1 -0
- package/dist/internal/brands.js +9 -0
- package/dist/internal/brands.js.map +1 -0
- package/dist/internal/debug.d.ts +43 -0
- package/dist/internal/debug.d.ts.map +1 -0
- package/dist/internal/debug.js +102 -0
- package/dist/internal/debug.js.map +1 -0
- package/dist/internal/errors.d.ts +98 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +212 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/globs.d.ts +29 -0
- package/dist/internal/globs.d.ts.map +1 -0
- package/dist/internal/globs.js +126 -0
- package/dist/internal/globs.js.map +1 -0
- package/dist/internal/ids.d.ts +32 -0
- package/dist/internal/ids.d.ts.map +1 -0
- package/dist/internal/ids.js +124 -0
- package/dist/internal/ids.js.map +1 -0
- package/dist/internal/json-value.d.ts +15 -0
- package/dist/internal/json-value.d.ts.map +1 -0
- package/dist/internal/json-value.js +61 -0
- package/dist/internal/json-value.js.map +1 -0
- package/dist/internal/package-version.d.ts +6 -0
- package/dist/internal/package-version.d.ts.map +1 -0
- package/dist/internal/package-version.js +14 -0
- package/dist/internal/package-version.js.map +1 -0
- package/dist/internal/realm-slot.d.ts +13 -0
- package/dist/internal/realm-slot.d.ts.map +1 -0
- package/dist/internal/realm-slot.js +23 -0
- package/dist/internal/realm-slot.js.map +1 -0
- package/dist/internal/redact.d.ts +33 -0
- package/dist/internal/redact.d.ts.map +1 -0
- package/dist/internal/redact.js +56 -0
- package/dist/internal/redact.js.map +1 -0
- package/dist/internal/regexp.d.ts +10 -0
- package/dist/internal/regexp.d.ts.map +1 -0
- package/dist/internal/regexp.js +27 -0
- package/dist/internal/regexp.js.map +1 -0
- package/dist/internal/text.d.ts +39 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +66 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/time.d.ts +37 -0
- package/dist/internal/time.d.ts.map +1 -0
- package/dist/internal/time.js +91 -0
- package/dist/internal/time.js.map +1 -0
- package/dist/internal/trace.d.ts +18 -0
- package/dist/internal/trace.d.ts.map +1 -0
- package/dist/internal/trace.js +46 -0
- package/dist/internal/trace.js.map +1 -0
- package/dist/internal/urls.d.ts +31 -0
- package/dist/internal/urls.d.ts.map +1 -0
- package/dist/internal/urls.js +95 -0
- package/dist/internal/urls.js.map +1 -0
- package/dist/locator/engine.d.ts +65 -0
- package/dist/locator/engine.d.ts.map +1 -0
- package/dist/locator/engine.js +164 -0
- package/dist/locator/engine.js.map +1 -0
- package/dist/locator/expression.d.ts +19 -0
- package/dist/locator/expression.d.ts.map +1 -0
- package/dist/locator/expression.js +85 -0
- package/dist/locator/expression.js.map +1 -0
- package/dist/locator/screen.d.ts +36 -0
- package/dist/locator/screen.d.ts.map +1 -0
- package/dist/locator/screen.js +281 -0
- package/dist/locator/screen.js.map +1 -0
- package/dist/report/build.d.ts +214 -0
- package/dist/report/build.d.ts.map +1 -0
- package/dist/report/build.js +346 -0
- package/dist/report/build.js.map +1 -0
- package/dist/report/code-frame.d.ts +20 -0
- package/dist/report/code-frame.d.ts.map +1 -0
- package/dist/report/code-frame.js +73 -0
- package/dist/report/code-frame.js.map +1 -0
- package/dist/report/debug-steps.d.ts +14 -0
- package/dist/report/debug-steps.d.ts.map +1 -0
- package/dist/report/debug-steps.js +85 -0
- package/dist/report/debug-steps.js.map +1 -0
- package/dist/report/list.d.ts +80 -0
- package/dist/report/list.d.ts.map +1 -0
- package/dist/report/list.js +372 -0
- package/dist/report/list.js.map +1 -0
- package/dist/report/live-status.d.ts +51 -0
- package/dist/report/live-status.d.ts.map +1 -0
- package/dist/report/live-status.js +162 -0
- package/dist/report/live-status.js.map +1 -0
- package/dist/report/write.d.ts +4 -0
- package/dist/report/write.d.ts.map +1 -0
- package/dist/report/write.js +13 -0
- package/dist/report/write.js.map +1 -0
- package/dist/run/app-process.d.ts +18 -0
- package/dist/run/app-process.d.ts.map +1 -0
- package/dist/run/app-process.js +112 -0
- package/dist/run/app-process.js.map +1 -0
- package/dist/run/artifacts.d.ts +51 -0
- package/dist/run/artifacts.d.ts.map +1 -0
- package/dist/run/artifacts.js +114 -0
- package/dist/run/artifacts.js.map +1 -0
- package/dist/run/events.d.ts +100 -0
- package/dist/run/events.d.ts.map +1 -0
- package/dist/run/events.js +59 -0
- package/dist/run/events.js.map +1 -0
- package/dist/run/execute.d.ts +119 -0
- package/dist/run/execute.d.ts.map +1 -0
- package/dist/run/execute.js +555 -0
- package/dist/run/execute.js.map +1 -0
- package/dist/run/fixtures.d.ts +40 -0
- package/dist/run/fixtures.d.ts.map +1 -0
- package/dist/run/fixtures.js +408 -0
- package/dist/run/fixtures.js.map +1 -0
- package/dist/run/in-process.d.ts +24 -0
- package/dist/run/in-process.d.ts.map +1 -0
- package/dist/run/in-process.js +120 -0
- package/dist/run/in-process.js.map +1 -0
- package/dist/run/public.d.ts +19 -0
- package/dist/run/public.d.ts.map +1 -0
- package/dist/run/public.js +11 -0
- package/dist/run/public.js.map +1 -0
- package/dist/run/realm.d.ts +52 -0
- package/dist/run/realm.d.ts.map +1 -0
- package/dist/run/realm.js +101 -0
- package/dist/run/realm.js.map +1 -0
- package/dist/run/records.d.ts +87 -0
- package/dist/run/records.d.ts.map +1 -0
- package/dist/run/records.js +3 -0
- package/dist/run/records.js.map +1 -0
- package/dist/run/retry.d.ts +18 -0
- package/dist/run/retry.d.ts.map +1 -0
- package/dist/run/retry.js +33 -0
- package/dist/run/retry.js.map +1 -0
- package/dist/run/runner.d.ts +49 -0
- package/dist/run/runner.d.ts.map +1 -0
- package/dist/run/runner.js +375 -0
- package/dist/run/runner.js.map +1 -0
- package/dist/run/scheduler.d.ts +45 -0
- package/dist/run/scheduler.d.ts.map +1 -0
- package/dist/run/scheduler.js +512 -0
- package/dist/run/scheduler.js.map +1 -0
- package/dist/run/serial.d.ts +52 -0
- package/dist/run/serial.d.ts.map +1 -0
- package/dist/run/serial.js +247 -0
- package/dist/run/serial.js.map +1 -0
- package/dist/run/sessions.d.ts +54 -0
- package/dist/run/sessions.d.ts.map +1 -0
- package/dist/run/sessions.js +221 -0
- package/dist/run/sessions.js.map +1 -0
- package/dist/run/steps.d.ts +196 -0
- package/dist/run/steps.d.ts.map +1 -0
- package/dist/run/steps.js +151 -0
- package/dist/run/steps.js.map +1 -0
- package/dist/run/unit-runner.d.ts +30 -0
- package/dist/run/unit-runner.d.ts.map +1 -0
- package/dist/run/unit-runner.js +11 -0
- package/dist/run/unit-runner.js.map +1 -0
- package/dist/run/units.d.ts +50 -0
- package/dist/run/units.d.ts.map +1 -0
- package/dist/run/units.js +103 -0
- package/dist/run/units.js.map +1 -0
- package/dist/run/worker/entry.d.ts +8 -0
- package/dist/run/worker/entry.d.ts.map +1 -0
- package/dist/run/worker/entry.js +137 -0
- package/dist/run/worker/entry.js.map +1 -0
- package/dist/run/worker/handle.d.ts +10 -0
- package/dist/run/worker/handle.d.ts.map +1 -0
- package/dist/run/worker/handle.js +74 -0
- package/dist/run/worker/handle.js.map +1 -0
- package/dist/run/worker/protocol.d.ts +129 -0
- package/dist/run/worker/protocol.d.ts.map +1 -0
- package/dist/run/worker/protocol.js +18 -0
- package/dist/run/worker/protocol.js.map +1 -0
- package/dist/run/worker/session.d.ts +69 -0
- package/dist/run/worker/session.d.ts.map +1 -0
- package/dist/run/worker/session.js +123 -0
- package/dist/run/worker/session.js.map +1 -0
- package/dist/types.d.ts +630 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `trace-1` entry format (RFC0001 layer 3, cache-in decision).
|
|
3
|
+
*
|
|
4
|
+
* A trace is the ordered list of grammar actions one passing `agent.act()`
|
|
5
|
+
* step performed, each with a durable target descriptor and secret-free,
|
|
6
|
+
* verbatim input — never model output, never plaintext secrets. An entry is
|
|
7
|
+
* deliberately small: a schema version, when it was written, and the trace
|
|
8
|
+
* with the provenance it had. It does not repeat its own key: the file name
|
|
9
|
+
* is the key digest and a reader only ever opens the digest of the key it
|
|
10
|
+
* just computed.
|
|
11
|
+
*
|
|
12
|
+
* Actions are a discriminated union: each variant carries exactly the typed
|
|
13
|
+
* input its grammar action needs, so validation here is the one owner of
|
|
14
|
+
* replayability — a document that reads back as an entry replays verbatim,
|
|
15
|
+
* and a document this runner cannot replay verbatim comes back as
|
|
16
|
+
* `undefined`, never as a repaired or partially trusted entry.
|
|
17
|
+
*/
|
|
18
|
+
import { timestamp } from '../internal/ids.js';
|
|
19
|
+
export const TRACE_SCHEMA_VERSION = 'trace-1';
|
|
20
|
+
/** Mirrors the default step action budget; overflow marks the trace truncated. */
|
|
21
|
+
export const MAX_TRACE_ACTIONS = 50;
|
|
22
|
+
/** Prose caps keep an entry a receipt, not a transcript. */
|
|
23
|
+
export const MAX_TRACE_SUMMARY_CHARS = 300;
|
|
24
|
+
export const MAX_TRACE_DESCRIPTOR_CHARS = 300;
|
|
25
|
+
/**
|
|
26
|
+
* Cap on verbatim replay inputs (typed text, URLs, option labels). Inputs are
|
|
27
|
+
* never truncated to fit — a trimmed URL or half a typed value would replay a
|
|
28
|
+
* different action than the one recorded — so an oversized input poisons the
|
|
29
|
+
* trace (`truncated`) instead of bending the value.
|
|
30
|
+
*/
|
|
31
|
+
export const MAX_TRACE_INPUT_CHARS = 4_096;
|
|
32
|
+
/** Caps prose at `maxChars`, marking the cut with an ellipsis. */
|
|
33
|
+
export function bound(text, maxChars) {
|
|
34
|
+
return text.length <= maxChars ? text : `${text.slice(0, maxChars - 1)}…`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Cap on recorded end anchors. Anchors are the step's own delta — what
|
|
38
|
+
* appeared on screen between the first observation and the passing one — so
|
|
39
|
+
* a same-screen mutation rarely has more than a handful; a step that changes
|
|
40
|
+
* the whole screen keeps the first few in document order.
|
|
41
|
+
*/
|
|
42
|
+
export const MAX_TRACE_ANCHORS = 8;
|
|
43
|
+
const SCROLL_DIRECTIONS = new Set(['up', 'down', 'left', 'right']);
|
|
44
|
+
/** The shape `timestamp()` writes: an ISO 8601 UTC instant. */
|
|
45
|
+
const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
|
|
46
|
+
/** Wraps one trace as a fresh entry. */
|
|
47
|
+
export function buildTraceEntry(payload) {
|
|
48
|
+
return { schemaVersion: TRACE_SCHEMA_VERSION, createdAt: timestamp(), payload };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reads one document as a `trace-1` entry, or returns undefined when it is
|
|
52
|
+
* not one this runner can trust. Unknown fields are dropped rather than
|
|
53
|
+
* carried: the returned entry contains exactly the validated shape.
|
|
54
|
+
*/
|
|
55
|
+
export function readTraceEntry(document) {
|
|
56
|
+
if (typeof document !== 'object' || document === null || Array.isArray(document)) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const raw = document;
|
|
60
|
+
if (raw['schemaVersion'] !== TRACE_SCHEMA_VERSION)
|
|
61
|
+
return undefined;
|
|
62
|
+
// Provenance must be the ISO instant this runner writes (`timestamp()`),
|
|
63
|
+
// not synthesized and not merely something Date.parse tolerates: a custom
|
|
64
|
+
// store returning anything else is returning a document this runner never
|
|
65
|
+
// wrote, and fail-to-miss is the only safe answer.
|
|
66
|
+
const createdAt = raw['createdAt'];
|
|
67
|
+
if (typeof createdAt !== 'string' || !ISO_INSTANT.test(createdAt))
|
|
68
|
+
return undefined;
|
|
69
|
+
const payload = readActionTrace(raw['payload']);
|
|
70
|
+
if (payload === undefined)
|
|
71
|
+
return undefined;
|
|
72
|
+
return { schemaVersion: TRACE_SCHEMA_VERSION, createdAt, payload };
|
|
73
|
+
}
|
|
74
|
+
function readActionTrace(document) {
|
|
75
|
+
if (typeof document !== 'object' || document === null || Array.isArray(document)) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const raw = document;
|
|
79
|
+
const executorRaw = raw['executor'];
|
|
80
|
+
if (typeof executorRaw !== 'object' || executorRaw === null)
|
|
81
|
+
return undefined;
|
|
82
|
+
const executorName = executorRaw['name'];
|
|
83
|
+
const executorVersion = executorRaw['version'];
|
|
84
|
+
if (typeof executorName !== 'string' || executorName === '')
|
|
85
|
+
return undefined;
|
|
86
|
+
if (executorVersion !== undefined && typeof executorVersion !== 'string')
|
|
87
|
+
return undefined;
|
|
88
|
+
const summary = readBoundedText(raw['summary'], MAX_TRACE_SUMMARY_CHARS);
|
|
89
|
+
if (summary === undefined)
|
|
90
|
+
return undefined;
|
|
91
|
+
const startPath = raw['startPath'];
|
|
92
|
+
if (startPath !== undefined) {
|
|
93
|
+
if (typeof startPath !== 'string' || startPath === '' || startPath.length > MAX_TRACE_DESCRIPTOR_CHARS) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const endPath = raw['endPath'];
|
|
98
|
+
if (endPath !== undefined) {
|
|
99
|
+
if (typeof endPath !== 'string' || endPath === '' || endPath.length > MAX_TRACE_DESCRIPTOR_CHARS) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const truncated = raw['truncated'];
|
|
104
|
+
if (truncated !== undefined && typeof truncated !== 'boolean')
|
|
105
|
+
return undefined;
|
|
106
|
+
const anchorsRaw = raw['endAnchors'];
|
|
107
|
+
let endAnchors;
|
|
108
|
+
if (anchorsRaw !== undefined) {
|
|
109
|
+
if (!Array.isArray(anchorsRaw) || anchorsRaw.length > MAX_TRACE_ANCHORS)
|
|
110
|
+
return undefined;
|
|
111
|
+
endAnchors = [];
|
|
112
|
+
for (const entry of anchorsRaw) {
|
|
113
|
+
const descriptor = readDescriptor(entry);
|
|
114
|
+
if (descriptor === undefined)
|
|
115
|
+
return undefined;
|
|
116
|
+
endAnchors.push(descriptor);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const actionsRaw = raw['actions'];
|
|
120
|
+
if (!Array.isArray(actionsRaw) || actionsRaw.length === 0 || actionsRaw.length > MAX_TRACE_ACTIONS) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const actions = [];
|
|
124
|
+
for (const entry of actionsRaw) {
|
|
125
|
+
const action = readRecordedAction(entry);
|
|
126
|
+
if (action === undefined)
|
|
127
|
+
return undefined;
|
|
128
|
+
actions.push(action);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
actions,
|
|
132
|
+
executor: {
|
|
133
|
+
name: executorName,
|
|
134
|
+
...(executorVersion === undefined ? {} : { version: executorVersion }),
|
|
135
|
+
},
|
|
136
|
+
summary,
|
|
137
|
+
...(startPath === undefined ? {} : { startPath }),
|
|
138
|
+
...(endPath === undefined ? {} : { endPath }),
|
|
139
|
+
...(endAnchors === undefined || endAnchors.length === 0 ? {} : { endAnchors }),
|
|
140
|
+
...(truncated === undefined ? {} : { truncated }),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function readRecordedAction(document) {
|
|
144
|
+
if (typeof document !== 'object' || document === null || Array.isArray(document)) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
const raw = document;
|
|
148
|
+
const summary = readBoundedText(raw['summary'], MAX_TRACE_SUMMARY_CHARS);
|
|
149
|
+
if (summary === undefined)
|
|
150
|
+
return undefined;
|
|
151
|
+
switch (raw['name']) {
|
|
152
|
+
case 'tap': {
|
|
153
|
+
const target = readDescriptor(raw['target']);
|
|
154
|
+
return target === undefined ? undefined : { name: 'tap', summary, target };
|
|
155
|
+
}
|
|
156
|
+
case 'type': {
|
|
157
|
+
const target = readDescriptor(raw['target']);
|
|
158
|
+
const value = readInputText(raw['value']);
|
|
159
|
+
if (target === undefined || value === undefined)
|
|
160
|
+
return undefined;
|
|
161
|
+
return { name: 'type', summary, target, value };
|
|
162
|
+
}
|
|
163
|
+
case 'typeSecret': {
|
|
164
|
+
const target = readDescriptor(raw['target']);
|
|
165
|
+
const secret = readBoundedText(raw['secret'], MAX_TRACE_DESCRIPTOR_CHARS);
|
|
166
|
+
if (target === undefined || secret === undefined)
|
|
167
|
+
return undefined;
|
|
168
|
+
return { name: 'typeSecret', summary, target, secret };
|
|
169
|
+
}
|
|
170
|
+
case 'press': {
|
|
171
|
+
const target = readDescriptor(raw['target']);
|
|
172
|
+
const key = readBoundedText(raw['key'], 64);
|
|
173
|
+
if (target === undefined || key === undefined)
|
|
174
|
+
return undefined;
|
|
175
|
+
return { name: 'press', summary, target, key };
|
|
176
|
+
}
|
|
177
|
+
case 'select': {
|
|
178
|
+
const target = readDescriptor(raw['target']);
|
|
179
|
+
const value = readInputText(raw['value']);
|
|
180
|
+
if (target === undefined || value === undefined)
|
|
181
|
+
return undefined;
|
|
182
|
+
return { name: 'select', summary, target, value };
|
|
183
|
+
}
|
|
184
|
+
case 'scroll': {
|
|
185
|
+
const direction = raw['direction'];
|
|
186
|
+
if (typeof direction !== 'string' || !SCROLL_DIRECTIONS.has(direction))
|
|
187
|
+
return undefined;
|
|
188
|
+
const target = raw['target'] === undefined ? undefined : readDescriptor(raw['target']);
|
|
189
|
+
if (raw['target'] !== undefined && target === undefined)
|
|
190
|
+
return undefined;
|
|
191
|
+
return {
|
|
192
|
+
name: 'scroll',
|
|
193
|
+
summary,
|
|
194
|
+
direction: direction,
|
|
195
|
+
...(target === undefined ? {} : { target }),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
case 'navigate': {
|
|
199
|
+
const url = readInputText(raw['url']);
|
|
200
|
+
return url === undefined ? undefined : { name: 'navigate', summary, url };
|
|
201
|
+
}
|
|
202
|
+
case 'tool':
|
|
203
|
+
return { name: 'tool', summary };
|
|
204
|
+
default:
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const DESCRIPTOR_FIELDS = [
|
|
209
|
+
'role',
|
|
210
|
+
'name',
|
|
211
|
+
'text',
|
|
212
|
+
'testId',
|
|
213
|
+
'placeholder',
|
|
214
|
+
'selector',
|
|
215
|
+
'inputPurpose',
|
|
216
|
+
];
|
|
217
|
+
function readDescriptor(document) {
|
|
218
|
+
if (typeof document !== 'object' || document === null || Array.isArray(document)) {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
const raw = document;
|
|
222
|
+
const descriptor = {};
|
|
223
|
+
for (const field of DESCRIPTOR_FIELDS) {
|
|
224
|
+
const value = raw[field];
|
|
225
|
+
if (value === undefined)
|
|
226
|
+
continue;
|
|
227
|
+
if (typeof value !== 'string' || value.length > MAX_TRACE_DESCRIPTOR_CHARS)
|
|
228
|
+
return undefined;
|
|
229
|
+
if (value !== '')
|
|
230
|
+
descriptor[field] = value;
|
|
231
|
+
}
|
|
232
|
+
if (Object.keys(descriptor).length === 0)
|
|
233
|
+
return undefined;
|
|
234
|
+
return descriptor;
|
|
235
|
+
}
|
|
236
|
+
function readBoundedText(value, maxChars) {
|
|
237
|
+
if (typeof value !== 'string' || value.trim() === '' || value.length > maxChars) {
|
|
238
|
+
return undefined;
|
|
239
|
+
}
|
|
240
|
+
return value;
|
|
241
|
+
}
|
|
242
|
+
/** Verbatim replay input: bounded but never trimmed — whitespace can be the value. */
|
|
243
|
+
function readInputText(value) {
|
|
244
|
+
if (typeof value !== 'string' || value === '' || value.length > MAX_TRACE_INPUT_CHARS) {
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
return value;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/cache/trace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
|
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AA0HhC,4CAA4C;AAC5C,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/** e2e CLI (spec 06-cli.md). */
|
|
2
|
+
import { Command, CommanderError, InvalidArgumentError } from 'commander';
|
|
3
|
+
import { run } from '../run/runner.js';
|
|
4
|
+
import { init } from './init.js';
|
|
5
|
+
/** Shape check only; the config resolver applies each flag's bounds. */
|
|
6
|
+
function parseNonNegativeInt(value) {
|
|
7
|
+
const parsed = Number(value);
|
|
8
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0) {
|
|
9
|
+
throw new InvalidArgumentError('must be a nonnegative integer');
|
|
10
|
+
}
|
|
11
|
+
return parsed;
|
|
12
|
+
}
|
|
13
|
+
function parseList(value) {
|
|
14
|
+
return value
|
|
15
|
+
.split(',')
|
|
16
|
+
.map((item) => item.trim())
|
|
17
|
+
.filter((item) => item !== '');
|
|
18
|
+
}
|
|
19
|
+
const REPORTERS = ['list', 'json'];
|
|
20
|
+
function isReporter(value) {
|
|
21
|
+
return REPORTERS.includes(value);
|
|
22
|
+
}
|
|
23
|
+
function isTagMode(value) {
|
|
24
|
+
return value === 'any' || value === 'all';
|
|
25
|
+
}
|
|
26
|
+
/** Builds the commander program. */
|
|
27
|
+
function createProgram() {
|
|
28
|
+
const program = new Command('e2e');
|
|
29
|
+
program.description('open, local-first standard for agentic end-to-end testing');
|
|
30
|
+
// Commander would exit(1) on a usage error itself; spec 06-cli.md reserves 1
|
|
31
|
+
// for product failures and 2 for CLI errors, so exits are decided in main.
|
|
32
|
+
program.exitOverride();
|
|
33
|
+
program
|
|
34
|
+
.command('init')
|
|
35
|
+
.description('scaffold e2e.config.ts, an example test, and .gitignore entries')
|
|
36
|
+
.option('-y, --yes', 'skip confirmation prompts')
|
|
37
|
+
.action(async (options) => {
|
|
38
|
+
process.exitCode = await init(process.cwd(), options);
|
|
39
|
+
});
|
|
40
|
+
program
|
|
41
|
+
.command('run')
|
|
42
|
+
.description('run e2e tests')
|
|
43
|
+
.argument('[files...]', 'test files relative to the project root')
|
|
44
|
+
.option('--config <path>', 'explicit config path')
|
|
45
|
+
.option('--target <ids>', 'comma-separated target IDs', parseList)
|
|
46
|
+
.option('--tag <tag>', 'repeatable tag filter', (value, previous = []) => [...previous, value])
|
|
47
|
+
.option('--tag-mode <mode>', 'tag composition: any or all', 'any')
|
|
48
|
+
.option('--headed', 'request visible UI when the backend supports it')
|
|
49
|
+
.option('--retries <n>', 'replace resolved retry count', parseNonNegativeInt)
|
|
50
|
+
.option('--workers <n>', 'replace worker count', parseNonNegativeInt)
|
|
51
|
+
.option('--reporter <ids>', 'comma-separated reporters: list, json', parseList)
|
|
52
|
+
.option('--artifacts <dir>', 'artifact root, default .e2e/artifacts')
|
|
53
|
+
.option('--no-cache', 'run without the trace cache, overriding the config')
|
|
54
|
+
.option('--pass-with-no-tests', 'allow zero runnable ordinary test-target pairs')
|
|
55
|
+
.option('--debug', 'print aggregated phase timings to stderr after the run')
|
|
56
|
+
.option('--ai-trace', 'record every model call to .e2e/ai-trace.json for trace viewers')
|
|
57
|
+
.action(async (files, options) => {
|
|
58
|
+
const { tagMode, reporter } = options;
|
|
59
|
+
if (!isTagMode(tagMode)) {
|
|
60
|
+
process.stderr.write(`invalid --tag-mode "${tagMode}"; expected any or all\n`);
|
|
61
|
+
process.exitCode = 2;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const invalidReporter = reporter?.find((value) => !isReporter(value));
|
|
65
|
+
if (invalidReporter !== undefined) {
|
|
66
|
+
process.stderr.write(`unknown reporter "${invalidReporter}"\n`);
|
|
67
|
+
process.exitCode = 2;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const outcome = await run({
|
|
71
|
+
files,
|
|
72
|
+
configPath: options.config,
|
|
73
|
+
targetIds: options.target,
|
|
74
|
+
tags: options.tag,
|
|
75
|
+
tagMode,
|
|
76
|
+
headed: options.headed,
|
|
77
|
+
retries: options.retries,
|
|
78
|
+
workers: options.workers,
|
|
79
|
+
// Validated above; the filter is the type narrowing, not a second check.
|
|
80
|
+
reporters: reporter?.filter(isReporter),
|
|
81
|
+
artifactsDir: options.artifacts,
|
|
82
|
+
noCache: options.cache === false,
|
|
83
|
+
passWithNoTests: options.passWithNoTests,
|
|
84
|
+
debug: options.debug,
|
|
85
|
+
aiTrace: options.aiTrace,
|
|
86
|
+
});
|
|
87
|
+
process.exitCode = outcome.exitCode;
|
|
88
|
+
});
|
|
89
|
+
return program;
|
|
90
|
+
}
|
|
91
|
+
/** CLI entry invoked by the bin wrapper. */
|
|
92
|
+
export async function main(argv) {
|
|
93
|
+
const program = createProgram();
|
|
94
|
+
try {
|
|
95
|
+
await program.parseAsync([...argv]);
|
|
96
|
+
}
|
|
97
|
+
catch (cause) {
|
|
98
|
+
if (cause instanceof CommanderError) {
|
|
99
|
+
// Commander has already written its diagnostic. `--help` and
|
|
100
|
+
// `--version` exit 0; every usage error is a CLI error: exit 2.
|
|
101
|
+
process.exitCode = cause.exitCode === 0 ? 0 : 2;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
process.stderr.write(`${cause instanceof Error ? cause.message : String(cause)}\n`);
|
|
105
|
+
process.exitCode = 2;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Non-destructive project scaffolding (spec 06-cli.md). */
|
|
2
|
+
/** Runs `e2e init`. Creates only missing files and stops before any conflict. */
|
|
3
|
+
export declare function init(cwd: string, options?: {
|
|
4
|
+
yes?: boolean;
|
|
5
|
+
}): Promise<number>;
|
|
6
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAsD5D,iFAAiF;AACjF,wBAAsB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DxF"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/** Non-destructive project scaffolding (spec 06-cli.md). */
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import * as clack from '@clack/prompts';
|
|
5
|
+
const CONFIG_TEMPLATE = `import { defineConfig } from '@e2edev/e2e';
|
|
6
|
+
import { createAgent } from '@e2edev/e2e/agent';
|
|
7
|
+
import { playwright } from '@e2edev/playwright';
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
specVersion: '0.1',
|
|
11
|
+
app: {
|
|
12
|
+
url: process.env.APP_URL ?? 'http://localhost:3000',
|
|
13
|
+
},
|
|
14
|
+
// The runner ships no intelligence: you construct the agent and pass it in.
|
|
15
|
+
// createAgent builds the built-in one; its model comes from E2E_MODEL.
|
|
16
|
+
agent: createAgent({
|
|
17
|
+
system: 'You are a thorough QA agent. Verify every outcome on screen.',
|
|
18
|
+
}),
|
|
19
|
+
// The runner knows no platform: a target is served by the backend you pass.
|
|
20
|
+
targets: [{ name: 'web', platform: 'web', backend: playwright({ browser: 'chromium' }) }],
|
|
21
|
+
});
|
|
22
|
+
`;
|
|
23
|
+
const EXAMPLE_TEMPLATE = `import { test } from '@e2edev/playwright';
|
|
24
|
+
import { expect } from '@e2edev/e2e';
|
|
25
|
+
|
|
26
|
+
test('app opens', async ({ app, web }) => {
|
|
27
|
+
await app.open();
|
|
28
|
+
await expect(web).toHaveURL('/');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Runs when E2E_MODEL and E2E_MODEL_API_KEY are set:
|
|
32
|
+
// test('the agent drives a flow', async ({ app, agent }) => {
|
|
33
|
+
// await app.open();
|
|
34
|
+
// await agent.act('one goal in plain language');
|
|
35
|
+
// await agent.assert('one question about the screen');
|
|
36
|
+
// });
|
|
37
|
+
`;
|
|
38
|
+
const GITIGNORE_ENTRIES = [
|
|
39
|
+
'.e2e/artifacts/',
|
|
40
|
+
'.e2e/cache/',
|
|
41
|
+
'.e2e/sessions/',
|
|
42
|
+
'.e2e/report.json',
|
|
43
|
+
'.e2e/ai-trace.json',
|
|
44
|
+
];
|
|
45
|
+
/** Runs `e2e init`. Creates only missing files and stops before any conflict. */
|
|
46
|
+
export async function init(cwd, options = {}) {
|
|
47
|
+
clack.intro('e2e init');
|
|
48
|
+
const planned = [
|
|
49
|
+
{ relative: 'e2e.config.ts', content: CONFIG_TEMPLATE },
|
|
50
|
+
{ relative: path.join('tests', 'example.e2e.ts'), content: EXAMPLE_TEMPLATE },
|
|
51
|
+
];
|
|
52
|
+
const exists = (file) => existsSync(path.join(cwd, file.relative));
|
|
53
|
+
const conflicts = planned.filter(exists);
|
|
54
|
+
const remaining = planned.filter((file) => !exists(file));
|
|
55
|
+
for (const conflict of conflicts) {
|
|
56
|
+
clack.log.warn(`exists, not touching: ${conflict.relative}`);
|
|
57
|
+
}
|
|
58
|
+
// The ignore list is reconciled on every run, not only the first: a project
|
|
59
|
+
// initialized before an entry existed (`.e2e/ai-trace.json`, say) picks it
|
|
60
|
+
// up by re-running init, without touching any scaffold file.
|
|
61
|
+
const gitignorePath = path.join(cwd, '.gitignore');
|
|
62
|
+
const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf8') : '';
|
|
63
|
+
// A CRLF .gitignore must not re-append every entry on each init.
|
|
64
|
+
const lines = existing.split(/\r?\n/);
|
|
65
|
+
const missing = GITIGNORE_ENTRIES.filter((entry) => !lines.includes(entry));
|
|
66
|
+
if (remaining.length === 0 && missing.length === 0) {
|
|
67
|
+
clack.outro('nothing to create; project already initialized');
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (options.yes !== true) {
|
|
71
|
+
const actions = [
|
|
72
|
+
...(remaining.length === 0
|
|
73
|
+
? []
|
|
74
|
+
: [`create ${remaining.map((file) => file.relative).join(', ')}`]),
|
|
75
|
+
...(missing.length === 0 ? [] : ['update .gitignore']),
|
|
76
|
+
];
|
|
77
|
+
const proceed = await clack.confirm({ message: `${actions.join(' and ')}?` });
|
|
78
|
+
if (clack.isCancel(proceed) || proceed !== true) {
|
|
79
|
+
clack.cancel('cancelled; no changes were made');
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (const file of remaining) {
|
|
84
|
+
const absolute = path.join(cwd, file.relative);
|
|
85
|
+
mkdirSync(path.dirname(absolute), { recursive: true });
|
|
86
|
+
writeFileSync(absolute, file.content, 'utf8');
|
|
87
|
+
clack.log.success(`created ${file.relative}`);
|
|
88
|
+
}
|
|
89
|
+
if (missing.length > 0) {
|
|
90
|
+
const prefix = existing === '' || existing.endsWith('\n') ? '' : '\n';
|
|
91
|
+
writeFileSync(gitignorePath, `${existing}${prefix}${missing.join('\n')}\n`, 'utf8');
|
|
92
|
+
clack.log.success(`updated .gitignore (${missing.length} entries)`);
|
|
93
|
+
}
|
|
94
|
+
if (remaining.length === 0) {
|
|
95
|
+
clack.outro('project already initialized; .gitignore brought up to date');
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
clack.outro('next: install @e2edev/playwright, then APP_URL=http://localhost:3000 npx --no-install e2e run');
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Collection realm: imports test modules and derives stable identities. */
|
|
2
|
+
import type { ResolvedConfig } from '../config/resolve.ts';
|
|
3
|
+
import { type GroupNode, type ModuleRegistration, type RegisteredTest, type SourceLocation } from './registry.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Everything needed to name and report a test, with no executable or realm
|
|
6
|
+
* state attached. Fully JSON-serializable, so it is what result records carry
|
|
7
|
+
* and what crosses the runner<->worker IPC channel.
|
|
8
|
+
*/
|
|
9
|
+
export interface TestIdentity {
|
|
10
|
+
readonly kind: 'test' | 'setup';
|
|
11
|
+
readonly title: string;
|
|
12
|
+
readonly titlePath: readonly string[];
|
|
13
|
+
readonly declarationIndex: number;
|
|
14
|
+
readonly sessions: readonly string[];
|
|
15
|
+
readonly source: SourceLocation | undefined;
|
|
16
|
+
/** Normalized project-root-relative file path with `/` separators. */
|
|
17
|
+
readonly file: string;
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly serialId: string | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface CollectedTest extends RegisteredTest, TestIdentity {
|
|
22
|
+
/** Outermost serial group, when the test is a serial-group member. */
|
|
23
|
+
readonly serialRoot: GroupNode | undefined;
|
|
24
|
+
}
|
|
25
|
+
/** Narrows a collected test to its reportable, serializable identity. */
|
|
26
|
+
export declare function testIdentity(test: CollectedTest): TestIdentity;
|
|
27
|
+
export interface CollectedFile {
|
|
28
|
+
readonly file: string;
|
|
29
|
+
readonly absolutePath: string;
|
|
30
|
+
readonly registration: ModuleRegistration;
|
|
31
|
+
readonly tests: readonly CollectedTest[];
|
|
32
|
+
}
|
|
33
|
+
export interface Collection {
|
|
34
|
+
readonly files: readonly CollectedFile[];
|
|
35
|
+
readonly tests: readonly CollectedTest[];
|
|
36
|
+
}
|
|
37
|
+
/** Builds one CollectedFile from an already-produced registration. */
|
|
38
|
+
export declare function collectFromRegistration(projectRoot: string, filePath: string, registration: ModuleRegistration): CollectedFile;
|
|
39
|
+
/**
|
|
40
|
+
* Runs collection: resolves globs, sorts matched files by code point, and
|
|
41
|
+
* imports each module once in the collection realm.
|
|
42
|
+
*/
|
|
43
|
+
export declare function collect(config: ResolvedConfig, fileFilter?: readonly string[]): Promise<Collection>;
|
|
44
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/collect/collect.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAO5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,SAAS,CAAC;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,aAAc,SAAQ,cAAc,EAAE,YAAY;IACjE,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,CAAC;CAC5C;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,YAAY,CAY9D;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CAC1C;AAsCD,sEAAsE;AACtE,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,kBAAkB,GAC/B,aAAa,CAQf;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,UAAU,CAAC,CAsBrB"}
|