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 runand 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:
-
CLI Parsing: In
cli/lib/exec/run.ts, theprocessRunOptionsfunction builds an argument array. When you pass--headed, the code executesargs.push('--headed', options.headed)to forward the flag to the server. If you supply--headlessinstead, the system converts this to--headed falseto maintain mutual exclusivity. -
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. -
Browser Launcher: The
@packages/launcherpackage receives the headed flag and callslaunchBrowser. When headed mode is active, the launcher omits the--headlessargument from Chrome (or equivalent flags for other browsers), allowing the browser window to render normally. -
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-extensionflag in headless mode. According to thenpm/puppeteer/README.mdin 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 --headedto execute tests in a visible browser window from the command line. - Use
npx cypress openfor the interactive, always-headed test runner that allows manual spec selection. - The
--headedflag is parsed incli/lib/exec/run.tsand propagated throughpackages/server/lib/modes/run.tsto 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
--headlessto 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →