Replay & E2E Testing (Experimental)
Agents use refs for exploration and authoring. Replay scripts are deterministic runs that can be used for E2E testing.
Core model
Two-pass workflow:
- Agent pass: discover and interact with refs (
snapshot->click @e../fill @e..). - Deterministic pass: run recorded
.adscript withreplay.
Record a replay script
Enable recording during a session:
By default, on close, a replay script is written to:
You can also provide a custom output file path:
--save-scriptvalue is treated as a file path.- Parent directories are created automatically when they do not exist.
- For ambiguous bare values, use
--save-script=workflow.ador a path-like value such as./workflow.ad.
Run replay
- Replay reads
.adscripts.
Run a lightweight .ad suite
testdiscovers.adfiles from files, directories, or globs and runs them serially.context platform=...inside each.adfile is the target source of truth for suite execution.--platformis a filter for suite discovery; files without platform metadata are skipped when a filter is present.context timeout=...andcontext retries=...can be declared per script; CLI flags override metadata. Retries are capped at3, and duplicate keys in the context header fail fast instead of silently overriding each other.- By default, suite artifacts are written under
.agent-device/test-artifacts/<run-id>/.... Each attempt writesreplay.adandresult.txt; failed attempts also keep copied logs and artifact files when the replay produced them. - Timeouts are cooperative: the runner marks the attempt failed at the timeout boundary, then gives the underlying replay a short grace period to stop before session cleanup.
- The default text reporter prints the suite summary, failed tests, and passed-on-retry flaky tests; use
--verboseto print every test result. - When
--fail-fastand retries are both set, the current test still consumes its retries before the suite stops.
Parametrise .ad scripts
Substitute ${VAR} tokens in .ad scripts using values from the CLI, shell env, script-local env directives, or built-ins.
Precedence
Built-ins
Built-ins are provided by replay/test runtime and use the reserved AD_* namespace.
AD_PLATFORM- matchescontext platform=...or the selected platform when availableAD_SESSION- active session nameAD_FILENAME- path of the running.adfileAD_DEVICE- device identifier (when--deviceis set)AD_ARTIFACTS- attempt artifacts directory (when running undertest)
User-defined keys starting with AD_ are rejected in env, -e, and shell imports such as AD_VAR_AD_FOO, so built-ins cannot be overridden.
Substitution happens inside parsed string values. It does not create extra arguments, so quote selectors or text values that contain spaces:
Fallback and escape
${VAR:-default} yields default when VAR is unset.
\${APP} emits a literal ${APP} with no substitution.
Recipes
Run one flow against two app variants in CI:
Tune timings locally without editing the script:
Extract a reusable selector. Before:
After:
Quote ${VAR} inside selector expressions so the whole expression is treated as a single argument.
Notes
replay -udoes not yet preserveenvdirectives or${VAR}tokens. Workaround: temporarily inline the literal values, run-u, re-parametrise.- Shell env (
AD_VAR_*) is collected on the CLI/client side at request time, so the same values are seen whether the daemon runs locally or remotely. - No nested fallback.
${A:-${B}}is not supported. - Unresolved
${VAR}fails with afile:linereference. Typos are loud.
Update stale selectors in replay scripts
When a replay step fails, update can:
- Take a fresh snapshot.
- Resolve a stable replacement target.
- Retry the step.
- Rewrite the failing line in the same
.adfile.
Current update targets:
clickfillgetiswait
replay -u before/after examples
Example 1: stale selector rewritten in place
Example 2: stale ref-based action upgraded to selector form
Use replay -u locally during maintenance, review the rewritten .ad lines, then commit the updated script.
Troubleshooting
- Replay fails after UI/layout changes:
- Run
replay -ulocally and review the rewritten lines.
- Run
- Updating cannot resolve a unique target:
- Re-record that flow (
--save-script) from a fresh exploratory pass.
- Re-record that flow (
- Replay file parse error:
- Validate quoting in
.adlines (unclosed quotes are rejected).
- Validate quoting in
