How to Run Cypress in Headed Mode: Complete Guide to Visible Browser Testing

Use npx cypress run --headed to launch a visible browser window, or npx cypress open for the interactive test runner UI.

Running tests in a visible browser is essential for debugging complex interactions and verifying UI behavior in real-time. In the cypress-io/cypress repository, headed mode launches an actual browser window rather than running headlessly in the background, allowing you to watch the Test Runner in real time. This guide explains how to run Cypress in headed mode using CLI commands and explores the underlying implementation in the source code.

What is Headed Mode in Cypress?

Cypress supports two distinct execution modes:

  • Headed mode: Launches a real browser window (Chrome, Edge, Firefox, or Electron) where you can see the application under test, interact with the page, and watch the Cypress UI execute commands.
  • Headless mode: Runs tests without any visible UI, executing in the background—this is the default for cypress run and is ideal for continuous integration environments.

While headless mode offers faster execution for CI pipelines, headed mode is indispensable for local development and debugging flaky tests.

CLI Commands to Run Cypress in Headed Mode

Run Specific Specs with --headed

To execute your test suite in a visible browser window from the command line, use the --headed flag with the run command:

npx cypress run --headed

Target a specific spec file for faster debugging:

npx cypress run --headed --spec "cypress/e2e/login.cy.js"

Specify the browser explicitly:

npx cypress run --headed --browser chrome

Launch the Interactive Test Runner (Always Headed)

The cypress open command boots the Electron-based desktop UI, which is inherently headed and requires no additional flags:

npx cypress open

For component testing with the interactive UI:

npx cypress open --component

Force Headless Mode (The Opposite)

The --headless flag forces headless execution, though it is the default for cypress run. According to the source code in cli/lib/exec/run.ts, these flags are mutually exclusive—when --headless is passed, the CLI internally adds --headed false to prevent conflicts.

How the Headed Flag Works Under the Hood

The --headed flag flows through several layers of the Cypress architecture:

  1. CLI Parsing: In cli/lib/exec/run.ts, the processRunOptions function builds an argument array. When you pass --headed, the code executes args.push('--headed', options.headed) to forward the flag to the server. If you supply --headless instead, the system converts this to --headed false to maintain mutual exclusivity.

  2. Server Mode: The arguments reach packages/server/lib/modes/run.ts, which interprets the flag and determines whether to launch a browser with a visible UI.

  3. Browser Launcher: The @packages/launcher package receives the headed flag and calls launchBrowser. When headed mode is active, the launcher omits the --headless argument from Chrome (or equivalent flags for other browsers), allowing the browser window to render normally.

  4. Execution: The driver injects Cypress code into the visible browser, reports results back to the CLI, and streams UI events if applicable.

When to Use Headed Mode

Headed mode is not just for watching tests run—it is required for specific workflows:

  • Debugging Flaky Tests: Seeing the DOM update in real time helps identify race conditions and timing issues that are invisible in headless logs.
  • Browser Extension Support: Chrome version 137 and later dropped support for the --load-extension flag in headless mode. According to the npm/puppeteer/README.md in the repository, extensions—including those used by @cypress/puppeteer—only work in headed runs.
  • Component Testing: When running cypress open --component, the headed UI allows you to interact with the component preview pane and inspect isolated component behavior.

Practical Code Examples

Run all specs in a visible Chrome window:

npx cypress run --headed --browser chrome

Debug a single failing spec:

npx cypress run --headed --spec "cypress/e2e/checkout.cy.js"

Programmatic usage from a Node.js script:

const { exec } = require('child_process');

// Run in headed mode with Chrome
exec('npx cypress run --headed --browser chrome', (err, stdout, stderr) => {
  console.log(stdout);
  if (err) console.error(stderr);
});

Summary

  • Use npx cypress run --headed to execute tests in a visible browser window from the command line.
  • Use npx cypress open for the interactive, always-headed test runner that allows manual spec selection.
  • The --headed flag is parsed in cli/lib/exec/run.ts and propagated through packages/server/lib/modes/run.ts to the @packages/launcher.
  • Headed mode is required for loading browser extensions in Chrome 137+ and is essential for debugging complex UI interactions.
  • For CI environments, omit the flag or use --headless to run tests without a UI.

Frequently Asked Questions

What is the difference between cypress run --headed and cypress open?

cypress run --headed executes your complete test suite (or specified specs) in a visible browser window and automatically exits when finished. In contrast, cypress open launches the interactive Electron-based desktop application where you can manually select individual specs, watch them run in real time, and interact with the Test Runner's time-travel debugging features.

Can I run specific test files in headed mode?

Yes. Append the --spec flag to target specific files while running in headed mode: npx cypress run --headed --spec "cypress/e2e/login.cy.js". This command launches the specified file in a visible browser window, which is useful for isolating and debugging individual test failures.

Why do browser extensions not work in headless mode?

According to the cypress-io/cypress source code, Chrome version 137 and later removed support for the --load-extension flag when running in headless mode. Consequently, extensions—including those required by @cypress/puppeteer—can only initialize when Cypress runs in headed mode, as the browser must fully render the UI to load extension artifacts.

How do I programmatically run Cypress in headed mode from JavaScript?

Spawn a child process with the --headed flag included in the command string: exec('npx cypress run --headed --browser chrome', callback). The CLI parser in cli/lib/exec/run.ts processes this flag and passes it through the server to the launcher, ensuring the browser launches with a visible window.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →