How to Debug Issues Within the Cypress Driver: A Complete Guide to Internal Logs and Inspection
Enable verbose internal logging by setting the DEBUG environment variable to cypress:driver:* and attach a Node inspector via CYPRESS_INTERNAL_DEV_DEBUG to step through the driver source code.
The Cypress driver is the JavaScript layer that executes inside the browser and mediates every cy.* command, network stubbing, and DOM interaction. When you need to debug issues within the Cypress driver, you are effectively inspecting the internal state of this browser-side controller. According to the cypress-io/cypress source code, the driver leverages the debug npm package to emit hierarchical log messages that can be toggled at runtime, providing granular visibility into command queues, runner events, and visibility calculations.
Understanding the Driver Debug Architecture
The Debug Package Integration
The driver uses the debug library (aliased as debugFn or Debug in the source) to create namespaced loggers. Each subsystem registers its own namespace under the cypress:driver prefix. When the DEBUG environment variable matches a namespace, the corresponding function becomes active; otherwise, it remains a no-op to minimize performance overhead.
Key Source Files and Log Namespaces
The driver emits logs from specific subsystems defined throughout the packages/driver directory:
cypress:driver:cypress– Emitted frompackages/driver/src/main.ts, tracks the initialization and export of the$Cypressobject.cypress:driver:command_queue– Emitted frompackages/driver/src/cypress/command_queue.ts, logs queue lifecycle, cleanup routines, and error handling.cypress:driver:runner– Emitted frompackages/driver/src/cypress/runner.ts, captures hook firing, test start/end events, and duration calculations.cypress:driver:dom:visibility:fastIsHidden– Emitted frompackages/driver/src/dom/visibility/fastIsHidden.ts, details visibility checks and bounding-rect calculations.cypress:driver:location– Emitted frompackages/driver/src/cy/location.ts, records channel timeouts and message receipt during navigation.cypress:driver:errors– Emitted from multiple files includingrunner.tsandcommand_queue.ts, captures stack traces and uncaught exceptions.
Enabling Driver Debug Output
Command Line Activation
Expose the desired namespaces by setting the DEBUG variable before invoking Cypress. Use wildcards to capture all driver activity or specify a single subsystem to reduce noise.
# Show all driver debug output
DEBUG=cypress:driver:* yarn cypress:run
# Focus only on the command queue
DEBUG=cypress:driver:command_queue yarn cypress:run
Capturing Logs to File
The driver writes debug output to stdout, interleaving it with test results. Redirect this stream to a file for post-run analysis using standard shell redirection:
DEBUG=cypress:driver:* yarn cypress:run > driver.log 2>&1
# Filter for specific events later
grep 'fire:' driver.log | less
Programmatic Activation
For CI environments or specific test runs, set the debug namespace programmatically in your support file:
// cypress/support/e2e.js
Cypress.env('DEBUG', 'cypress:driver:runner')
Attaching a Node Inspector for Source-Level Debugging
To step through the driver’s TypeScript source in Chrome DevTools, use the internal development flag. The CLI forwards this value to the child process spawn logic.
Set the CYPRESS_INTERNAL_DEV_DEBUG variable to a Node inspector flag:
export CYPRESS_INTERNAL_DEV_DEBUG="--inspect-brk"
yarn cypress:open
Then navigate to chrome://inspect in Chrome to attach the debugger. This functionality is implemented in cli/lib/exec/spawn.ts (lines 38-41), where the environment variable is injected into the process arguments.
Because the driver is compiled with source maps, breakpoints map directly back to the original TypeScript files, such as packages/driver/src/cypress/runner.ts and packages/driver/src/cypress/cy.ts.
Practical Debugging Workflow
Follow this structured approach to diagnose flaky behavior or command failures:
-
Identify the subsystem – Choose a namespace (
command_queue,runner,dom:visibility, etc.) based on the symptom. This keeps output focused and searchable. -
Run Cypress with the
DEBUGvariable – Execute your tests with the targeted namespace enabled to emit granular internal state, such as queue length or pending commands. -
Correlate logs with failures – Look for specific log patterns like
debug('fire: %o', { event })in the runner ordebug('cleanup called …')in the command queue to pinpoint divergence from expected behavior. -
Attach a Node inspector (optional) – Set
CYPRESS_INTERNAL_DEV_DEBUG=--inspect-brkand runyarn cypress:opento step through the actual driver implementation. -
Examine source maps – Use the original
.tsfiles inpackages/driver/src/to set breakpoints and inspect variables at runtime.
Key Driver Subsystems to Monitor
Focus your debugging efforts on these specific modules based on the type of issue encountered:
| Subsystem | Source File | Debug Output |
|---|---|---|
| Command Queue | packages/driver/src/cypress/command_queue.ts |
Queue state changes, cleanup logic, error propagation |
| Test Runner | packages/driver/src/cypress/runner.ts |
Hook execution, test lifecycle, duration metrics |
| DOM Visibility | packages/driver/src/dom/visibility/fastIsHidden.ts |
Bounding rect details, visibility calculations |
| Navigation | packages/driver/src/cy/location.ts |
URL changes, timeout events, message channels |
| Error Handling | packages/driver/src/cypress/runner.ts |
Uncaught exceptions, stack traces |
Summary
- The driver relies on the
debugpackage, exposing hierarchical namespaces undercypress:driver:*. - Enable logging by setting the
DEBUGenvironment variable to match the desired namespace pattern. - Attach Chrome DevTools to the driver process using
CYPRESS_INTERNAL_DEV_DEBUGto step through TypeScript source. - Target specific subsystems like
command_queueorrunnerto filter noise and isolate issues. - Debug output streams to stdout and can be captured to files for offline analysis.
Frequently Asked Questions
How do I enable debug logs for only the command queue?
Set DEBUG=cypress:driver:command_queue before running Cypress. This filters output to only the command queue subsystem defined in packages/driver/src/cypress/command_queue.ts, showing queue lifecycle events and cleanup calls without noise from other driver components.
What is the difference between DEBUG and CYPRESS_INTERNAL_DEV_DEBUG?
The DEBUG variable controls log output from the debug package, emitting text to stdout from namespaces like cypress:driver:runner. The CYPRESS_INTERNAL_DEV_DEBUG variable passes Node.js inspector flags (such as --inspect-brk) to the child process spawn logic in cli/lib/exec/spawn.ts, enabling breakpoint debugging in Chrome DevTools.
Can I debug driver issues in CI environments?
Yes. Set the DEBUG environment variable in your CI configuration to cypress:driver:* or a specific subsystem, and redirect stdout to a file artifact. You can also programmatically enable debugging via Cypress.env('DEBUG', 'cypress:driver:runner') in your support file, then grep the captured logs for specific patterns like fire: or cleanup.
Where are the source maps for the driver located?
The driver TypeScript files in packages/driver/src/ are compiled with source maps. When you attach a debugger using CYPRESS_INTERNAL_DEV_DEBUG, Chrome DevTools automatically maps the running JavaScript back to original .ts files like packages/driver/src/cypress/runner.ts, allowing you to set breakpoints and inspect variables in the source code.
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 →