cypress-log-to-output

A Cypress plugin that pipes browser console logs and Chrome DevTools log entries into your terminal's stdout during test runs.

Library
npm
v1.1.2
146stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
35/100Needs Attention
Development Activity0
Maintenance0
Community60
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
46/100Fair
Architecture55
Code Quality45
Innovation50
Learning Curve35

cypress-log-to-output is a small Cypress plugin that closes a long-standing gap in headless test debugging: browser console output that normally disappears when Cypress runs in CI. It attaches to the Chrome DevTools Protocol (CDP) via chrome-remote-interface, listens for Log.entryAdded and Runtime.consoleAPICalled events, and re-prints them — with severity-based coloring via chalk — directly into the terminal running cypress run or cypress open.

The plugin registers itself on the before:browser:launch event, so it needs no changes to test specs. It works with any Chromium-family browser (Chrome, Chromium, Canary) that Cypress launches, ensuring a --remote-debugging-port is set so it can connect. Electron, Cypress’s default bundled browser, is explicitly unsupported since Electron doesn’t expose the same CDP log/console surface in the way this plugin expects.

Beyond straight passthrough, it supports an optional filter callback so teams can restrict output to just error-level events, and an optional recordLogs mode that buffers messages in memory for later retrieval via getLogs()/clearLogs() — useful for asserting on console output from within a test itself rather than only reading it from CI logs.

What You Get

  • Automatic streaming of all browser console.* calls and Chrome DevTools Log.entryAdded entries into your terminal during cypress run/cypress open
  • Severity-colored output (verbose/info/warning/error) via chalk, with icons and ISO timestamps prefixed to each line
  • An optional event filter callback so you can restrict output to just errors, or apply any custom matching logic on the raw CDP event
  • An optional recordLogs buffering mode with getLogs()/clearLogs() exports, letting a test assert on captured console output instead of only reading CI logs
  • A DEBUG=-cypress-log-to-output escape hatch to silence the plugin’s own [cypress-log-to-output] status lines

Common Use Cases

  • Debugging flaky or failing CI test runs where a browser-side console.error explains the failure but is normally invisible in headless mode
  • Surfacing uncaught JS exceptions and stack traces from the app under test directly next to the Cypress command log in CI output
  • Filtering noisy console output down to just error-level events for a cleaner CI log
  • Asserting inside a spec that a specific console message was (or wasn’t) emitted, using recordLogs + getLogs()

Under The Hood

Architecture The package is a single flat module (src/log-to-output.js) exporting install, browserLaunchHandler, getLogs, and clearLogs, with no internal layering — filter state, recording state, and the message buffer all live as module-scoped variables shared across calls. install() registers a before:browser:launch hook; when Cypress launches the browser, browserLaunchHandler mutates the launch args to guarantee a --remote-debugging-port, then retries a CDP connection every 100ms until Chrome’s debugger becomes reachable, at which point it subscribes to Log.entryAdded and Runtime.consoleAPICalled. The data flow is linear: CDP event to formatter (logEntry/logConsole) to console.log, with an optional buffered copy. Because the filter and recorder are global module state rather than per-instance, attaching to more than one browser session concurrently would require reworking the core abstraction.

Tech Stack Runtime dependencies are minimal and pinned loosely: chrome-remote-interface ^0.27.1 for the CDP client and chalk ^2.4.2 for terminal coloring; devDependencies are mocha ^6.2.1 and cypress ^3.2.0. There’s no TypeScript, no bundler, and no build step — package.json’s main points straight at the plain CommonJS source file, and only src/ is published. Tests run via mocha src/*spec.js; no CI workflow file is present in the repo.

Code Quality Only one spec file exists (src/log-to-output-spec.js), covering exactly one pure helper (_ensureRdpPort) with two assertion-based cases; the CDP connection logic, event formatting, and filtering paths have no test coverage. Error handling is thin — the CDP connection retry loop silently swallows every failure (.catch(() => setTimeout(tryConnect, 100))) with no give-up condition, so a browser that never opens a debug port retries indefinitely. No linter/formatter config or type annotations are present; naming is plain and consistent camelCase throughout.

What Makes It Unique Its specific technical choice — talking directly to Chrome over the DevTools Protocol’s Log and Runtime domains rather than trying to intercept console output through Cypress’s own internal event bus — is what makes browser-to-terminal log forwarding possible at all, since Cypress had no native cross-process console-surfacing mechanism at the time. It’s a solid, narrow fix for a real gap rather than a broad architectural innovation; comparable CDP-log-forwarding plugins exist for other headless test runners, so the approach is standard practice within its niche.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search