How to Run Cypress End-to-End Tests Headlessly from the Command Line
Run Cypress end-to-end tests headlessly with reliable CLI commands, browser selection, CI reporting, debugging, and failure fixes.

Run this from your project root:
npx cypress run
Cypress runs the configured end-to-end suite in a headless browser by default. The same command with other package managers is yarn cypress run, pnpm cypress run, or bunx cypress run. Use Cypress’s command-line reference for version-specific options.
1. Install Cypress and verify the project
Cypress must be installed as a project dependency before the CLI commands work.
npm install --save-dev cypress
npx cypress verify
If this is a new project, open Cypress once to generate the recommended folders and configuration:
npx cypress open
cypress open is the interactive headed workflow. After your specs and configuration exist, use cypress run for repeatable command-line and CI runs.
2. Run the complete suite headlessly
npx cypress run
By default, Cypress runs all tests headlessly and exits with a success or failure status suitable for shell scripts and CI jobs. Cypress chooses an available browser unless you select one explicitly.

Run with Yarn, pnpm, or Bun
yarn cypress run
pnpm cypress run
bunx cypress run
Run a specific browser
npx cypress run --browser chrome
npx cypress run --browser chromium
npx cypress run --browser edge
npx cypress run --browser firefox
The selected browser must be installed in the local machine or CI runner. Browser availability and support can change between Cypress releases; check the browser-launch guide for the version you use.
Run one spec file
npx cypress run --spec "cypress/e2e/checkout.cy.js"
The path must also match your configured specPattern. If Cypress reports that no specs were found, inspect the pattern in your Cypress configuration and use a path relative to the project root.
3. Use the most useful CLI options
| Goal | Command |
|---|---|
| Choose a browser | npx cypress run --browser chrome |
| Run one spec | npx cypress run --spec "cypress/e2e/login.cy.js" |
| Show the browser while running | npx cypress run --headed --no-exit --browser chrome |
| Record to Cypress Cloud | npx cypress run --record |
| Override a configuration value | npx cypress run --config video=true |
| Set environment values | npx cypress run --env apiUrl=https://staging.example.com |
Use --headed when diagnosing a failure that may depend on browser rendering. Combining it with --no-exit keeps the browser open after the run for inspection.
4. Configure screenshots, video, and reports
Cypress saves failure screenshots by default. Video recording is optional and is disabled by default. When enabled, Cypress records one video per spec during cypress run.
// cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
video: true,
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos',
trashAssetsBeforeRuns: true
})
The documented default video directory is cypress/videos. Cypress clears screenshot and video folders before a run unless trashAssetsBeforeRuns is changed. See the configuration reference and screenshots and videos guide.
Produce JUnit XML
npx cypress run \
--reporter junit \
--reporter-options "mochaFile=results/cypress-[hash].xml,toConsole=true"
Choose a reporter format your CI system can parse. Reporter options are configurable; keep output files in a directory that your CI artifact step preserves. See the reporter guide.
5. Run Cypress in CI
A typical CI sequence installs dependencies, starts the application, waits for it to be reachable, and then runs Cypress.
npm ci
npm run start -- --port 3000 &
npx cypress run --browser chrome
A long-running web server must run in the background or the CI job can wait forever and never reach the Cypress command. Provider-specific tools can also start the server and wait for its URL. Read the Cypress CI overview for your provider.
Use a fixed base URL
// cypress.config.js
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:3000'
}
})
Tests can then use relative paths such as cy.visit('/login'). Keep the base URL configurable for staging and preview environments.
Record a run in Cypress Cloud
npx cypress run --record
Recording requires project setup and a record key. Supply the key as an operating-system or CI environment variable:
export CYPRESS_RECORD_KEY="your-record-key"
npx cypress run --record
Cypress does not read this key from cypress.env.json or the configuration env block. Store it in your CI secret manager and never commit it.
6. Make headless runs stable and fast
- Match production browsers: run the browser families your users depend on, and install each one in the runner image.
- Keep specs focused: smaller specs make retries, diagnosis, and parallel execution easier.
- Use deterministic data: reset database state and avoid tests that depend on wall-clock timing or shared accounts.
- Wait on application state: prefer Cypress commands and assertions over arbitrary sleeps.
- Control media: enable video only when its diagnostic value justifies storage and run time.
- Cache dependencies carefully: cache package downloads, but invalidate the cache when lockfiles or browser versions change.
- Separate artifacts: retain JUnit files, failure screenshots, and videos long enough to investigate failures.
Headless execution is generally appropriate for routine automation. A headed retry is useful when a failure appears only with a visible browser or when you need to inspect layout and timing.
7. Troubleshoot common failures
| Error or symptom | Cause | Fix |
|---|---|---|
cypress: command not found |
Cypress is not installed locally or the package script is bypassing the project binary. | Run npm install --save-dev cypress, then use npx cypress run or a package-manager equivalent. |
| No specs found | The --spec path does not match specPattern. |
Check the configured pattern and pass a project-relative path. |
| Browser not detected | The requested browser is absent from the runner. | Install that browser in the image or choose one that is installed. |
| CI hangs after starting the app | The server process is running in the foreground. | Background it, or use a CI server-and-test utility that waits for the URL. |
| Tests pass headed but fail headlessly | Timing, viewport, browser, or rendering differences. | Run npx cypress run --headed --no-exit --browser chrome, inspect screenshots and video, and replace timing sleeps with state-based assertions. |
| Cloud recording is rejected | Project setup or record-key configuration is incomplete. | Confirm the project ID and provide CYPRESS_RECORD_KEY as an OS or CI environment variable. |
| Old screenshots or videos disappear | trashAssetsBeforeRuns clears asset folders before each run. |
Change that setting or copy artifacts to a retention directory after each run. |
| JUnit files are missing | The reporter option points to a directory that does not exist or is not uploaded. | Create the results directory, verify the generated path, and configure CI artifact collection. |
8. A repeatable command checklist
- Install dependencies with the lockfile.
- Verify Cypress can launch in the runner.
- Start the application in the background.
- Choose a browser that is installed and matches your users.
- Run the full suite with
npx cypress run. - Save failure screenshots, optional video, and machine-readable reports.
- Use headed mode only when a failure needs visual diagnosis.
- Keep cloud record keys in CI secrets.
9. Or skip the browser setup
If your goal is a clean image of a page rather than an interactive test, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and returns PNG, JPEG, WebP, or PDF.

One request is enough (see the ScreenshotNeo API documentation):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Before capture, ScreenshotNeo accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.
Create a free ScreenshotNeo account to get started.
10. FAQ
Is Cypress headless by default?
Yes. cypress run launches browsers headlessly unless you pass --headed.
Should I use cypress open in CI?
No. Use cypress run for non-interactive execution and reserve cypress open for local development.
Can I run only one test?
Use --spec to select a spec file. To narrow further, use test filtering techniques supported by your Cypress version and project configuration.
Does enabling video change test behavior?
It adds recording work and storage. Keep it disabled for routine runs and enable it when retained visual evidence is useful.
Do I need Cypress Cloud?
No. Local console output, screenshots, videos, and reporters work without Cloud. Cloud recording is an optional run-management and retention workflow.


