Driving Cypress with cypress tap
cypress tap controls an already-running cypress open session. Use it to iterate on specs,
inspect the reporter and command log, and read the app under test without GUI interaction.
Use cypress run instead for a one-shot headless batch.
Prerequisites
- Confirm from package metadata or the lockfile that the resolved Cypress is 15.21.0+ and
contains
tap. Do not use tap --help to probe an unknown older build; prereleases below the
version floor may attempt session discovery instead of printing help.
- The session must use Electron, Chrome, Chromium, or Edge. Firefox and WebKit are unsupported.
cypress open and any configured baseUrl dev server must already be running.
- The cwd chooses both the Cypress binary and the automatically selected session. When the
target project pins an older Cypress, run
tap from a compatible checkout and pass
--session <pid> on every call.
Route by task
- Start, select, or poll a session: read
session-lifecycle.md.
- Run a spec or read its results: read session-lifecycle.md
and reading-results.md.
- Author or inspect a spec: read recipes.md and
reading-the-app.md.
- Diagnose a failure: read recipes.md,
reading-results.md, and
reading-the-app.md.
- Command failure, hang, wrong project, or surprising output: read
troubleshooting.md.
- One noninteractive batch: use
cypress run, not tap.
Read only the references required for the current task.
Core commands
sessions: reachable sessions, project roots, testing types, and browsers; JSON adds support
and renderer health.
status: lifecycle stage, selected spec, run identity, counts, build error, and active pin.
specs: runnable project-relative spec paths for the session's testing type.
run <spec>: dispatches a spec and returns immediately.
reporter: spec overview and test ids; with --test-id, the complete test attempt.
command: one command-log row with network data, snapshots, and console properties.
pin: rewinds the app frame to a command snapshot.
dom, aria, inspect: read the settled app or currently pinned snapshot.
All commands accept --session <pid>, --json, and --timeout <ms>. On a confirmed supported
build, use npx cypress tap <command> --help for command-specific flags.
The non-negotiable verdict rule
run confirms dispatch, not execution, and returns before the new run starts. During that gap,
status and app reads can still return the previous run's plausible verdict and page.
For every explicit run:
- Read the current
startedAt.
- Dispatch exactly one spec.
- Poll one
status --json response at a time.
- Accept only
passed or failed for the expected spec with a non-empty, changed
startedAt. startedAt is null only when no run has ever started for that spec in the
session — a build failure on first selection. A build that fails on rerun or on a watcher
rebuild still advances startedAt, so it takes the normal path. Keep the null fallback
(a changed observable baseline, or a preceding loading/running observation) for the
first-selection case only.
- Bound the loop and fail if no matching fresh verdict arrives.
Saving the active spec triggers an automatic watcher run. After editing, either use that run or
let it settle before taking a baseline and dispatching another. Never intentionally put two runs
in flight.
Blank and partial payloads from a successful status call occur transiently. Treat missing
fields as "keep waiting," not as a state change. A nonzero status exit is a command failure,
not a partial read: stop polling and report it.
Only passed and failed are verdicts. A build failure is failed with the diagnostic in
status.error, possibly before any tests exist. status is the only surface that carries that
diagnostic — reporter renders a failed build as an empty spec.
Critical correctness rules
- Target the intended session. If several sessions exist, or auto-selection behaves oddly,
inspect
sessions and pass --session <pid>. Auto-selection can choose another project or an
unresponsive session.
- Preserve the binary location. Cwd controls
npx resolution on every call. When the
project pins an older Cypress, run commands from a compatible checkout and pass
--session <pid>.
- Do not parse failed commands. Check the exit code before parsing JSON. Supported-build
failures generally use stderr, but older compatibility failures may use stdout. An ambiguous
selector is the intentional exception: it exits
1 and lists matches on stdout.
- Do not discard dispatch stdout while checking compatibility. An older Cypress may print
Unknown command "tap" and usage text to stdout; redirecting it hides the cause.
- Redirect potentially large JSON.
reporter --test-id --json and command --json can be
hundreds of kilobytes. Save them to a file and parse the file.
- Check truncation before concluding absence.
dom and aria cap output. Narrow the
selector or raise the limit when (output truncated) appears.
- Sanity-check the live frame before concluding absence. A trailing pending/skipped test
can leave the settled runner on a blank placeholder while app reads still exit
0. Confirm a
known app anchor. If the frame is blank, pin a snapshot from the last real command and read
that state instead.
- Read results before editing or deleting the spec. Results and snapshots live in the
Cypress app's memory and can disappear on rerun, restart, rename, or deletion.
- Clear pins. After inspecting a command snapshot, run
pin --clear; otherwise later app
reads continue to describe the pinned past. An exit-0 cleared:false result is a benign
no-op even if human output says FAILED TO CLEAR PIN.
- Use the right reader for live state. Use
aria for current form-control values:
dom and inspect can show the initial HTML value attribute, and inspect may omit the
accessibility value. Use dom for exact live-region, toast, status, and label text because
aria may omit descendant text.
Output contract
- Human output is for reading;
--json is for parsing and may contain much more data.
status exits 0 for known lifecycle stages, including not connected. Discovery,
compatibility, unsupported-browser, and renderer failures exit 1, sometimes with no stdout;
a poller must fail fast on that nonzero exit.
dom, aria, and inspect require exactly one selected element. Ambiguity exits 1 with
candidate selectors. A miss is not a CLI failure: dom and inspect report found:false;
aria returns an empty tree both for a miss and for an element with no accessibility node.
- Failures are prose without stable error codes. Branch on exit status, not message text.
Performance defaults
- Prefer one
reporter --test-id read over one command call per row.
- After a fresh verdict and live-frame sanity check, independent app reads may run concurrently.
- If bounded status polling fails, inspect
sessions for rendererResponsive: false; restart a
wedged renderer instead of increasing --timeout.
1---2name: cypress-tap3description: Drives a running Cypress open-mode session through `cypress tap` to run and rerun specs, wait for fresh results, inspect reporter and command logs, and query or rewind the app under test through DOM, accessibility, styles, and snapshots. Use when authoring or debugging Cypress e2e or component specs, discovering selectors, diagnosing failures, or verifying test behavior without GUI interaction. Not for one-shot headless runs. Requires Cypress 15.21+, a Chromium-family browser, and a running `cypress open` session.4---5
6# Driving Cypress with `cypress tap`
7
8`cypress tap` controls an already-running `cypress open` session. Use it to iterate on specs,
9inspect the reporter and command log, and read the app under test without GUI interaction.
10Use `cypress run` instead for a one-shot headless batch.
11
12## Prerequisites
13
14- Confirm from package metadata or the lockfile that the resolved Cypress is 15.21.0+ and
15 contains `tap`. Do not use `tap --help` to probe an unknown older build; prereleases below the
16 version floor may attempt session discovery instead of printing help.
17- The session must use Electron, Chrome, Chromium, or Edge. Firefox and WebKit are unsupported.
18- `cypress open` and any configured `baseUrl` dev server must already be running.
19- The cwd chooses both the Cypress binary and the automatically selected session. When the
20 target project pins an older Cypress, run `tap` from a compatible checkout and pass
21 `--session <pid>` on every call.
22
23## Route by task
24
25- **Start, select, or poll a session:** read
26 [session-lifecycle.md](references/session-lifecycle.md).
27- **Run a spec or read its results:** read [session-lifecycle.md](references/session-lifecycle.md)
28 and [reading-results.md](references/reading-results.md).
29- **Author or inspect a spec:** read [recipes.md](references/recipes.md) and
30 [reading-the-app.md](references/reading-the-app.md).
31- **Diagnose a failure:** read [recipes.md](references/recipes.md),
32 [reading-results.md](references/reading-results.md), and
33 [reading-the-app.md](references/reading-the-app.md).
34- **Command failure, hang, wrong project, or surprising output:** read
35 [troubleshooting.md](references/troubleshooting.md).
36- **One noninteractive batch:** use `cypress run`, not `tap`.
37
38Read only the references required for the current task.
39
40## Core commands
41
42- `sessions`: reachable sessions, project roots, testing types, and browsers; JSON adds support
43 and renderer health.
44- `status`: lifecycle stage, selected spec, run identity, counts, build error, and active pin.
45- `specs`: runnable project-relative spec paths for the session's testing type.
46- `run <spec>`: dispatches a spec and returns immediately.
47- `reporter`: spec overview and test ids; with `--test-id`, the complete test attempt.
48- `command`: one command-log row with network data, snapshots, and console properties.
49- `pin`: rewinds the app frame to a command snapshot.
50- `dom`, `aria`, `inspect`: read the settled app or currently pinned snapshot.
51
52All commands accept `--session <pid>`, `--json`, and `--timeout <ms>`. On a confirmed supported
53build, use `npx cypress tap <command> --help` for command-specific flags.
54
55## The non-negotiable verdict rule
56
57`run` confirms dispatch, not execution, and returns before the new run starts. During that gap,
58`status` and app reads can still return the previous run's plausible verdict and page.
59
60For every explicit run:
61
621. Read the current `startedAt`.
632. Dispatch exactly one spec.
643. Poll one `status --json` response at a time.
654. Accept only `passed` or `failed` for the expected `spec` with a non-empty, changed
66 `startedAt`. `startedAt` is null only when no run has ever started for that spec in the
67 session — a build failure on first selection. A build that fails on rerun or on a watcher
68 rebuild still advances `startedAt`, so it takes the normal path. Keep the null fallback
69 (a changed observable baseline, or a preceding `loading`/`running` observation) for the
70 first-selection case only.
715. Bound the loop and fail if no matching fresh verdict arrives.
72
73Saving the active spec triggers an automatic watcher run. After editing, either use that run or
74let it settle before taking a baseline and dispatching another. Never intentionally put two runs
75in flight.
76
77Blank and partial payloads from a successful `status` call occur transiently. Treat missing
78fields as "keep waiting," not as a state change. A nonzero `status` exit is a command failure,
79not a partial read: stop polling and report it.
80
81Only `passed` and `failed` are verdicts. A build failure is `failed` with the diagnostic in
82`status.error`, possibly before any tests exist. `status` is the only surface that carries that
83diagnostic — `reporter` renders a failed build as an empty spec.
84
85## Critical correctness rules
86
871. **Target the intended session.** If several sessions exist, or auto-selection behaves oddly,
88 inspect `sessions` and pass `--session <pid>`. Auto-selection can choose another project or an
89 unresponsive session.
902. **Preserve the binary location.** Cwd controls `npx` resolution on every call. When the
91 project pins an older Cypress, run commands from a compatible checkout and pass
92 `--session <pid>`.
933. **Do not parse failed commands.** Check the exit code before parsing JSON. Supported-build
94 failures generally use stderr, but older compatibility failures may use stdout. An ambiguous
95 selector is the intentional exception: it exits `1` and lists matches on stdout.
964. **Do not discard dispatch stdout while checking compatibility.** An older Cypress may print
97 `Unknown command "tap"` and usage text to stdout; redirecting it hides the cause.
985. **Redirect potentially large JSON.** `reporter --test-id --json` and `command --json` can be
99 hundreds of kilobytes. Save them to a file and parse the file.
1006. **Check truncation before concluding absence.** `dom` and `aria` cap output. Narrow the
101 selector or raise the limit when `(output truncated)` appears.
1027. **Sanity-check the live frame before concluding absence.** A trailing pending/skipped test
103 can leave the settled runner on a blank placeholder while app reads still exit `0`. Confirm a
104 known app anchor. If the frame is blank, pin a snapshot from the last real command and read
105 that state instead.
1068. **Read results before editing or deleting the spec.** Results and snapshots live in the
107 Cypress app's memory and can disappear on rerun, restart, rename, or deletion.
1089. **Clear pins.** After inspecting a command snapshot, run `pin --clear`; otherwise later app
109 reads continue to describe the pinned past. An exit-`0` `cleared:false` result is a benign
110 no-op even if human output says `FAILED TO CLEAR PIN`.
11110. **Use the right reader for live state.** Use `aria` for current form-control values:
112 `dom` and `inspect` can show the initial HTML `value` attribute, and `inspect` may omit the
113 accessibility value. Use `dom` for exact live-region, toast, status, and label text because
114 `aria` may omit descendant text.
115
116## Output contract
117
118- Human output is for reading; `--json` is for parsing and may contain much more data.
119- `status` exits `0` for known lifecycle stages, including `not connected`. Discovery,
120 compatibility, unsupported-browser, and renderer failures exit `1`, sometimes with no stdout;
121 a poller must fail fast on that nonzero exit.
122- `dom`, `aria`, and `inspect` require exactly one selected element. Ambiguity exits `1` with
123 candidate selectors. A miss is not a CLI failure: `dom` and `inspect` report `found:false`;
124 `aria` returns an empty tree both for a miss and for an element with no accessibility node.
125- Failures are prose without stable error codes. Branch on exit status, not message text.
126
127## Performance defaults
128
129- Prefer one `reporter --test-id` read over one `command` call per row.
130- After a fresh verdict and live-frame sanity check, independent app reads may run concurrently.
131- If bounded status polling fails, inspect `sessions` for `rendererResponsive: false`; restart a
132 wedged renderer instead of increasing `--timeout`.