skip to content

Unattended Execution

Running the suite with nobody watching it: the command a pipeline invokes, the flags it passes, the code it exits with, and the prebuilt container it all runs inside.

on this pageshow

explore

questions

10

What do the Cypress Docker images cypress/base, cypress/browsers and cypress/included contain?

level: juniorimportance: must knowfreq 58%

answer

  1. Three published images stacked on each other
  2. One of them ships no browser at all
  3. The middle one adds Chrome, Firefox, Edge
  4. The top one pins the runner itself
  5. A fourth generates custom combinations

basics

~20 s

cypress/base carries Debian, Node.js and the OS packages Cypress needs, but no browser. cypress/browsers adds Chrome, Firefox and Edge. cypress/included adds a tag-pinned Cypress installed globally. cypress/factory generates a custom image when no published combination fits.

solid answer

~40 s

The official images stack. `cypress/base` is Debian plus the operating-system packages Cypress needs, Node.js, npm and Yarn v1 Classic — but no browser, so its tag only chooses a Node.js version. `cypress/browsers` builds on it and adds Chrome, Firefox and Edge, so its tag fixes the combined Node.js and browser versions. `cypress/included` builds on `cypress/browsers` and adds a fixed Cypress installed globally with npm, so the image tag rather than your dependency file decides the runner version. `cypress/factory` is not a ready-made runner image at all: it takes the base operating system and lets you select each component version to generate your own, for combinations no published tag covers. All are Linux (Debian) based and published for `linux/amd64` and `linux/arm64`.

go deeper

for a junior

Be ready to name the three stacked images in order and say which one has no browser in it. Knowing that the tag encodes Node.js, browser or Cypress versions is enough at this level.

for a middle

Explain why the split exists: the npm module and the Cypress binary install separately, and the OS libraries and browsers are a third cost. Say which layer each image removes from your job.

for a senior

An interviewer expects you to justify a choice for a real pipeline, including the arm64 browser gaps, whether the image or the dependency file owns the runner version, and what a browser-less base costs after Cypress 16 deprecated Electron.

for a principal

Own the standard across repos: one pinned image family, a documented upgrade cadence for Node.js and browser bumps, and a clear rule about who may build from cypress/factory and who then maintains it.

## Why a prebuilt image exists at all Getting Cypress running on a bare Linux container is a three-part job, and each part costs a pipeline job time on every single run. The `cypress` npm module is small — a CLI, TypeScript types and a launcher — while the **Cypress application itself is a large, platform-specific binary** downloaded separately in a `postinstall` step. Before that binary will start, the operating system needs a set of Debian/Ubuntu libraries. And if you want to test in a real browser rather than a bundled one, a browser has to be installed too. The official Cypress Docker images move that work out of the job and into an image that was built once. They are Linux (Debian) based and published for both `linux/amd64` and `linux/arm64`, and picking one is how you fix the environment your tests run in — it stops a pipeline provider silently bumping Node.js or a browser version underneath you. ## The four variants and what each one adds | Image | What it carries | Who picks the Cypress version | | --- | --- | --- | | `cypress/base` | Debian, the OS packages Cypress needs, Node.js, npm, Yarn v1 Classic — **no browser** | your project | | `cypress/browsers` | everything in `base`, plus **Chrome, Firefox and Edge** | your project | | `cypress/included` | everything in `browsers`, plus a **fixed Cypress installed globally with npm** | the image tag | | `cypress/factory` | the base OS image plus per-component version selection | you, when you build it | They genuinely stack: `cypress/browsers` builds on `cypress/base`, and `cypress/included` builds on `cypress/browsers`. The tag is where the variation lives: - a `cypress/base` tag selects the **Node.js** version; - a `cypress/browsers` tag selects the **combined Node.js and browser** versions; - a short `cypress/included` tag selects the **Cypress** version, and the long form spells out the Node.js and browser versions it was built against. `cypress/factory` is different in kind. It is not a ready-to-run runner image but a way to generate one, choosing each component version yourself. Reach for it only when no published tag offers the Node.js, browser and Cypress combination you need — after that you own rebuilding it whenever any one of those moves. ## Choosing one for a multi-package storefront monorepo 1. **Do the packages disagree about the Cypress version?** In a monorepo where `packages/storefront-web` and `packages/checkout` may upgrade Cypress at different times, `cypress/browsers` is usually the right base: each package's own dependency file stays the source of truth, and the image only supplies Node.js and the browsers. 2. **Do you want one pinned runner for the whole repo, with nothing to install?** Then `cypress/included` is attractive: the Cypress binary is already in the image, so a job can execute specs without a binary download at all. The cost is that upgrading Cypress now means changing the image tag, and that a package pinning a different version in its dependency file will quietly install a second copy anyway. 3. **Does nothing published match?** Only then build from `cypress/factory`. ## What Cypress 16 changed about the browser-less option As of Cypress 16, the **bundled Electron browser is deprecated** as a test browser and will be removed in a future major version. That makes `cypress/base` with nothing else installed a poor default: with no installed browser present, a run falls back to Electron, which now emits a deprecation warning and will eventually fail outright. If you are on `cypress/base` today, either move to `cypress/browsers` or install Chrome, Firefox or Edge into the environment yourself. ## Caveats worth checking before you pin a tag - **The architectures are not identical.** On `linux/arm64`, `cypress/browsers` carries Firefox from version 136 and above and Chrome from version 151 and above, and **Edge is not available at all** — its version segment in an arm64 tag is an empty placeholder kept only for multi-platform tag compatibility. A matrix that assumes Edge everywhere breaks the moment a job lands on an ARM runner. - **`cypress/included` pins the runner, not your project.** The Cypress it carries is installed globally. If a package in the monorepo also lists `cypress` as a dev dependency at a different version, installing that package downloads its own binary and you get two. - **A tag is a contract about Node.js too.** Upgrading the image can move the Node.js version your specs and any `setupNodeEvents` code run under, so treat an image bump as a real change, not housekeeping. - **Pinning is the point.** A floating tag re-introduces exactly the drift the image was chosen to eliminate.

  • Which Cypress image would you pick if no published tag has the Node.js and browser combination you need?
    `cypress/factory`. It provides the base operating system image and lets you select each component version individually to generate a custom image. It is the right answer only after you have checked the published `cypress/browsers` and `cypress/included` tags, because from then on you own rebuilding and republishing that image every time Node.js, a browser or Cypress moves.
  • As of Cypress 16, why is cypress/base with no browser installed a poor default?
    Cypress 16 deprecates the bundled Electron browser as a test browser and will remove it in a future major version. A `cypress/base` container with nothing else installed leaves a run falling back to Electron, which now emits a deprecation warning and will eventually fail. Move to `cypress/browsers`, or install Chrome, Firefox or Edge into the environment yourself.

The three stacked images are the same crate packed to three depths: tools only, tools plus browsers, and tools, browsers and the test runner already inside.

saying these in an interview costs you the question

  • Thinks cypress/base already contains Chrome or Firefox
  • Believes package.json picks the version in cypress/included
  • Assumes the official images are Windows or macOS based
  • Cannot say what cypress/browsers adds over cypress/base
  • Expects an arm64 image to carry exactly the same browsers
open as a page

In Cypress, what is the difference between `cypress open` and `cypress run`?

level: juniorimportance: must knowfreq 85%

basics

~20 s

cypress open launches the interactive Cypress app: you pick a spec, watch it run in a visible browser, and it reruns every time you save. cypress run executes matching specs once, headlessly, then exits with a status code a pipeline reads.

open as a page

What exit code does `cypress run` return, and what does `--posix-exit-codes` change?

level: middleimportance: must knowfreq 62%

basics

~20 s

By default cypress run exits with the number of failed tests, Mocha-style: three failures give status 3, and 0 means everything passed. Passing --posix-exit-codes makes any test failure exit 1 instead, and adds 112 for a Cypress Cloud network failure.

open as a page

Why does caching node_modules not stop Cypress downloading its binary in CI?

level: seniorimportance: must knowfreq 52%

basics

~20 s

The Cypress binary is not in node_modules. Only the small npm module is; the application binary is downloaded by a postinstall script into a global cache outside the project, so that directory is what a pipeline has to persist.

open as a page

What does CYPRESS_INSTALL_BINARY control, and what does setting it to 0 do?

level: middleimportance: should knowfreq 44%

basics

~10 s

CYPRESS_INSTALL_BINARY chooses which Cypress binary the postinstall step downloads: a version, a URL, or a local zip file. Setting it to 0 skips the binary download entirely, leaving only the small npm module installed.

open as a page

What does Cypress 16's manageBrowserMemory option do, and when would you disable it?

level: middleimportance: should knowfreq 38%

basics

~20 s

It samples browser memory during a run and forces a garbage collection before the next test when a sample crosses a threshold. It defaults to true in Cypress 16, covers Chromium browsers only, and costs time at test transitions.

open as a page

Which edits make a `cypress open` session rerun your Cypress spec?

level: middleimportance: should knowfreq 40%

basics

~20 s

Only edits inside the spec graph: the active spec file, the support file, and any module they import or require. Application source, node_modules and cypress/fixtures are deliberately not watched, and the whole watcher is governed by watchForFileChanges.

open as a page

A storefront checkout spec fails only under `cypress run`, never in `cypress open`. How do you inspect it?

level: seniorimportance: should knowfreq 48%

basics

~20 s

Keep 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.

open as a page

In a monorepo, which binaries does `cypress cache prune` actually delete?

level: seniorimportance: nice to knowfreq 24%

basics

~10 s

It deletes every cached Cypress binary except the version resolved from the directory you ran it in. Other packages in the monorepo lose the binaries they pinned, and re-download them on their next run.

open as a page

Why does Cypress's `cypress.run()` resolve instead of rejecting when tests fail?

level: seniorimportance: nice to knowfreq 26%

basics

~20 s

Because a failing test is a normal outcome of running a suite, not an error in running it. cypress.run() resolves with a results object carrying totalFailed and per-spec stats; it rejects only when Cypress could not run at all, such as an uninstalled binary.

open as a page