A storefront checkout spec fails only under `cypress run`, never in `cypress open`. How do you inspect it?
answer
- Reproduce it in the mode that fails
- Same browser on both sides
- Stop it from vanishing when it ends
- One spec, from a clean start
- Headless changes rendering, not commands
basics
~20 sKeep using cypress run and remove what hides it: narrow with --spec, pin the browser with --browser, add --headed to see the window, and --no-exit so Cypress stays up after the spec finishes. Then compare the browser, the spec set, and the inherited state.
solid answer
~40 sDo not switch to open mode — the difference *is* the mode, so reproduce it inside `cypress run`. Narrow the run with `--spec`, pin the browser with `--browser chrome` so both modes use the same one, then add `--headed` to see the window and `--no-exit` so Cypress does not exit once the spec's tests have finished; the documented pairing is `cypress run --headed --no-exit`. From there, suspect the environmental differences rather than the engine: which browser was launched, headless rendering, `isInteractive` being `false`, and the fact that each spec is processed separately in a batch run, so state a previously-clicked spec left behind in your open session is simply not there. If it fails only headless, stop reading the spec and look at rendering, viewport and timing.
code
bash · 7 lines# 1. does it fail headlessly, on the browser the pipeline used?
npx cypress run --browser chrome \
--spec "packages/checkout/cypress/e2e/place-order.cy.js"
# 2. now watch it, and keep Cypress up once the spec finishes
npx cypress run --browser chrome --headed --no-exit \
--spec "packages/checkout/cypress/e2e/place-order.cy.js"go deeper
Know that cypress run can be made visible with --headed and narrowed with --spec, and that this is how you look at a batch run rather than guessing from the terminal output.
Explain what actually differs between the modes — browser choice, visibility, evidence capture, and specs being processed separately — and which of those a flag can neutralise.
Show a procedure that converges: reproduce headless first, pin the browser, then watch it with --headed --no-exit, and know when to stop blaming the spec and start blaming the environment.
Own how much divergence between local and pipeline runs your team tolerates, and what you standardise — browser, image, seeded data — so this class of investigation stops recurring.
## Reach for the flags that put the batch run in front of you `cypress run` is not a different engine — it is the same binary with different defaults — so the fastest path is to keep running it and change only what hides it from you: - **`--spec`** narrows the run to the one spec, so you are not waiting for the whole suite. Remember it intersects `specPattern`: a path outside the configured pattern matches nothing and the run reports that no specs were found. - **`--browser chrome`** pins the browser to whatever the pipeline used. Left off, open mode and the batch run may have launched different browsers entirely, which is the single most common cause of a "passes locally, fails in the run" spec. As of Cypress 16 the accepted names are `chrome`, `chromium`, `edge` and `firefox`, plus a release channel such as `chrome:canary` or a filesystem path; `electron` still works but is deprecated. - **`--headed`** shows the browser instead of running it hidden. - **`--no-exit`** stops Cypress from exiting once the spec's tests have finished, so the window and its dev tools are still there for you to poke at. The documented pairing is `cypress run --headed --no-exit`. - **`--runner-ui`** forces the Cypress Runner UI to render during the run if it is not showing. ## What genuinely differs between the modes Once you can see the run, the differences worth suspecting are environmental rather than logical: | Difference | `cypress open` | `cypress run` | |---|---|---| | Browser | whichever you clicked | whatever `--browser` says, or the default | | Rendering | a real visible window | headless unless `--headed` | | Failure evidence | on screen | screenshot on failure, video if enabled | | `isInteractive` | `true` | `false` | | `numTestsKeptInMemory` | `50` | `0` | | Spec set | the one you clicked | every spec, each processed separately | That last row matters more than it looks: each spec file is processed completely separately during a `cypress run`. A spec that only passes because a spec you happened to run earlier in your open-mode session left state behind will fail the moment it runs from a clean start, and it will fail differently depending on the order the batch run picks. ## A procedure that converges 1. Run it headless first: `cypress run --spec <one spec>`. If it passes, the failure is order-dependent or environmental, not in the spec. 2. Add `--browser` to match the pipeline's browser and run again. A fair number of these investigations end here. 3. Add `--headed --no-exit` and watch it happen. The window stays up afterwards. 4. If it fails **only** when headless, stop looking at the spec: suspect rendering, viewport, fonts, or animation timing, and lean on the failure screenshot and the recorded video instead. 5. If it fails only on the pipeline machine and never locally in either mode, the variable is the environment — image, base URL, seeded data — and none of these flags will show it to you. ## Flags that will not help here Half of the `cypress run` option list is about somewhere else entirely, and reaching for it wastes a cycle: - `--record`, `--group`, `--tag`, `--ci-build-id`, `--parallel` are about sending the run to Cypress Cloud and splitting it. None of them changes what you can see locally. - `--quiet` reduces what reaches stdout, which is the opposite of what you want while investigating. - `--no-runner-ui` hides the Runner UI; `--runner-ui` forces it back on if it is not rendering. Neither changes when the process exits, so neither substitutes for `--no-exit`. - `--config` can override a value for the run, which is useful for a hypothesis (`--config viewportWidth=1280`) but is a probe, not a fix — anything you leave in place there has quietly become configuration nobody can find later. ## The trap worth naming Do not conclude "run mode is flaky". Cypress executes commands identically in both modes; there is no parallel queue in one and a serial queue in the other, and the support file is loaded either way. Something concrete differs — the browser, the visibility of the window, the spec set, or the state the spec inherited — and the flags above exist to make that concrete thing visible. An answer that ends at "add a retry and move on" is the one interviewers are listening for, because it hides the difference instead of naming it.
- Your `cypress run --spec` command reports that no specs were found, though the path exists. Why?`--spec` only runs specs that also match the configured `specPattern`; Cypress intersects the two. A spec living outside the pattern is not found even when you pass its exact path. Check the pattern for the testing type you are running, and that the path is relative to the project folder.
- The spec fails headless but passes with `--headed`. Where do you look next?Not at the command sequence — Cypress queues and drains commands identically either way. Look at what rendering changes: viewport size, fonts and layout, animation and transition timing, and anything that depends on the window actually being painted. The failure screenshot and the recorded video usually show it directly.
saying these in an interview costs you the question
- Concludes run mode is simply flaky and adds a retry
- Debugs the failure only in open mode, where it never reproduces
- Never pins --browser, so the two modes use different browsers
- Thinks cypress run skips the support file or custom commands
- Assumes commands execute differently in headless mode