Skip to content

CLI essentials

The tales binary has three subcommands: test, validate, and doctor. This page documents each.

Terminal window
tales --version
tales --help

--version prints the embedded build tag, commit, Go runtime, and platform.

Terminal window
tales test <path> [flags]

Runs every .tales scenario found in <path> (recursively).

FlagTypeDefaultEffect
--seedint64time.Now().UnixNano() (0)Deterministic generator seed. Setting 0 triggers the system-time fallback.
--parallelintruntime.NumCPU()Maximum number of scenarios running concurrently. Steps inside a scenario stay sequential.
--tag[]string(none)Filter scenarios by tag. Multi-value, OR semantics.
--scenariostring(none)Run only one scenario by exact name. Overrides --tag when both are set.
--no-colorboolfalseStrip ANSI colour codes from console output.
--no-progressboolfalseDisable scenario start/end progress events on stderr.
--timeoutduration0 (disabled)Global wall-clock budget. Cancels in-flight scenarios when exceeded.
--verboseboolfalsePrint a 30s heartbeat listing scenarios still running.
--report-junit <path>string(none)Write JUnit XML to <path>.
--report-jsonl <path>string(none)Write a JSONL event stream to <path>.
--report-html <path>string(none)Write the visual HTML report to <path>. Auto-enables --capture-screenshots actions.
--capture-screenshots <mode>stringmode-dependentMobile capture mode: none / failures / steps / actions. Defaults documented below.
Flags passedEffective mode
neitherfailures (legacy)
--report-html onlyactions
explicit --capture-screenshotsalways wins
Terminal window
# Minimal: run the whole suite with a deterministic seed
tales test ./e2e/pass --seed 1234
# CI-style: parallel, with JUnit + JSONL + HTML
tales test ./e2e/pass \
--seed 1234 \
--parallel 8 \
--timeout 10m \
--report-junit ./reports/junit.xml \
--report-jsonl ./reports/events.jsonl \
--report-html ./reports/visual.html
# Run a single scenario by name (overrides --tag)
tales test ./e2e/pass --scenario "Create blog post"
# Run only scenarios tagged smoke or critical
tales test ./e2e/pass --tag smoke --tag critical
# Quiet output for cron jobs
tales test ./e2e/pass --no-color --no-progress

On startup, tales test prints a single preflight line on stderr so you immediately see what got loaded:

tales: loaded 12 scenarios from 5 files; timeout=disabled

While the runner is in flight (and --no-progress is not set), scenario start/end events are streamed on stderr. --verbose adds a heartbeat every 30 seconds listing scenarios still running, invaluable when you suspect one is stuck.

If --timeout fires before the suite completes, the CLI prints the names of the in-flight scenarios so you know exactly which ones stalled.

Terminal window
tales validate <path>

Parses every .tales file under <path>, checks step ordering, expression references, and provider configuration, without executing anything. Exits 0 on success, 2 on parse or validation error.

Use it as a fast pre-commit hook.

Terminal window
tales doctor
tales doctor --json

One-stop diagnostic. Prints:

  • Tales build info (version, commit, Go runtime, platform).
  • Embedded driver source hash (16-hex cache key prefix), file count, total bytes.
  • iOS driver cache enumeration: extract / build markers, recorded Xcode / SDK / iOS / macOS metadata, on-disk size, “matches embedded” flag.
  • Xcode + simctl probes (xcodebuild -version, xcrun --show-sdk-version, xcode-select -p, sw_vers).
  • Available simulator runtimes and devices.
  • Hints (cache wipe, env override, stale CoreSimulator recovery).

--json emits the same data as a JSON document, scriptable from CI:

Terminal window
tales doctor --json | jq .embedded_driver.source_hash_short
tales doctor --json | jq '.cache.entries[] | select(.built == false)'

Missing Xcode or unavailable simctl is reported as a degraded section, not as an error, tales doctor is the tool you reach for when things are broken.

CLI exit codes are part of the public contract. CI pipelines can rely on them.

CodeMeaning
0All scenarios passed (or skipped).
1At least one scenario failed.
2Parse or validation error.
3Runtime or reporting fatal error.
VariablePurpose
TALES_DRIVER_CACHE_DIROverride the base directory of the embedded iOS driver cache (default ~/Library/Caches/tales/apple-driver/).
anythingAvailable inside .tales expressions via env("NAME", "default").

User-defined env vars can gate scenarios via skip_if / skip_unless, see the env_set / env attributes there.