npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tracelane/wdio

v0.1.0-alpha.24

Published

WebdriverIO Service that records rrweb sessions and writes a self-contained HTML report on failed tests. The user-facing tracelane integration for WDIO.

Readme

@tracelane/wdio

The recorder for your WebdriverIO tests. Self-contained HTML for every run — replay failures, audit successes, attach to any bug tracker. No SaaS, no dashboard, no signup. (Playwright is available via @tracelane/playwright; Cypress is on the roadmap.)

npm downloads license CI OpenSSF Scorecard types node status: alpha

tracelane install — one command

Docs: https://tracelane.cubenest.in

cd your-wdio-project
npx @tracelane/cli init

That's it. npx @tracelane/cli init detects your runner, installs @tracelane/wdio, edits wdio.conf.ts in place, and gitignores the reports directory. Idempotent (re-run is a no-op) and dry-runnable (--dry-run).

Run your suite. On a failing test you get a single .html file at ./tracelane-reports/<spec>--<title>--<cid>-<ts>.html — open it in any browser, fully offline. Replay the run with rrweb-player, inspect the console + failed-network panels, attach to your bug tracker, archive it forever. No upload, no signup, no cloud.

Or wire it manually

npm install --save-dev @tracelane/wdio
// wdio.conf.ts
import TraceLaneService from '@tracelane/wdio';

export const config = {
  // ...your existing config
  services: [[TraceLaneService, { mode: 'failed' }]],
};

Same result — npx @tracelane/cli init is just the orchestration that does the lines above for you.

What this is NOT

  • Not Cypress Cloud, Replay.io, or Sentry Session Replay. There is no SaaS to host. There is no signup. There is no dashboard. There is no telemetry. The artifact is a single HTML file on your filesystem.
  • Not a reporter (in the @wdio/reporter sense). tracelane is a WDIO Service because only a Service can attach to the live browser, inject the rrweb recorder + in-page network plugin, drain the in-page buffer, and (where available) use CDP to enrich network capture. A paired Allure Reporter shim is planned for v1.1.
  • Not just for failures. mode: 'all' writes a report for every test — useful as a CI artifact, evidence in a PR, or a "what changed between green and red" diff.

Full example

// wdio.conf.ts
import type { Options } from '@wdio/types';
import TraceLaneService from '@tracelane/wdio';

export const config: Options.Testrunner = {
  runner: 'local',
  framework: 'mocha',
  specs: ['./test/specs/**/*.ts'],
  capabilities: [
    {
      browserName: 'chrome',
      'goog:chromeOptions': { args: ['--remote-debugging-port=9222', '--no-sandbox'] },
    },
  ],
  services: [
    // Optional: network is captured in-page by default (all browsers, no CDP).
    // Add devtools only to enrich it with authoritative status + no-response
    // failures on Chromium — see "Network capture" below.
    ['devtools', {}],
    [
      TraceLaneService,
      {
        mode: process.env.TRACELANE_MODE ?? 'failed', // 'failed' | 'all'
        outDir: './tracelane-reports',
        capture: { rrweb: true, network: true, console: true },
      },
    ],
  ],
  reporters: ['spec'],
};

webdriverio and @wdio/types are peer dependencies (^9.0.0); you already have them in a WDIO project. Node >= 22 is required (a common first-run failure on older runtimes).

How it works

  • On the first test, the Service injects an rrweb recorder bundle into the page and installs an in-page event buffer (window.__tracelane__events).
  • The Node side drains that buffer on a poll (default every 500 ms) and on every afterTest, re-injecting after each navigation.
  • In failed mode (default) a passing test discards its buffer; a failing test's buffer is handed to @tracelane/report, which builds the single offline HTML (≤ 25 MB).

Content-Security-Policy: rrweb capture requires in-page script evaluation. If a page's CSP blocks 'unsafe-eval', capture degrades gracefully — the test still runs and completes normally, a warning is logged once, but no replay is recorded for the affected page.

For what tracelane captures, masks, and never sends off your machine, see the security notes.

Options

| Option | Type | Default | Notes | |---|---|---|---| | mode | 'failed' \| 'all' | 'failed' | failed writes a report only on failure; all on every test. TRACELANE_MODE env var overrides this. | | outDir | string | './tracelane-reports' | Report output directory (created if missing). | | capture.rrweb | boolean | true | Record the rrweb session. | | capture.network | boolean | true | Capture network requests via the in-page rrweb/network@1 plugin — all browsers, no CDP. Privacy-first: only URL/method/status/timing by default (headers + bodies off; opt in via capture.networkOptions). CDP is an optional fallback that adds authoritative status + true no-response failures where it's available. | | capture.networkOptions | NetworkRecordOptions | plugin defaults | Forwarded to the in-page network plugin (recordHeaders, recordBody, maskRequestFn, payloadHostDenyList, …). Defaults are privacy-first (headers + bodies off). Ignored when capture.network is false. | | capture.console | boolean | true | Capture console.* via the rrweb console plugin. Setting this false also drops any [tracelane.net] network-error lines from the CDP fallback path, since those surface through console.error. | | consolePluginOptions | ConsolePluginOptions | plugin defaults | Forwarded to the in-page rrweb console plugin. Ignored when capture.console is false (which instead passes { level: [] } to patch no methods). | | drainIntervalMs | number | 500 | Node-side drain poll interval. | | cooldownMs | number | 250 | Re-injection cooldown guard (suppresses double-init on hash/HMR navigation). | | security | boolean | true | Advisory security-hygiene signals ([tracelane.sec]) captured during the run and analyzed in the report. Set false to disable both the capture and the analysis. When on, an optional tracelane.security.suppress.json in the project cwd silences known-acceptable signals (missing/malformed file degrades to no suppressions). | | allure | boolean | false | Reserved for the v1.1 Allure shim. No-op in v1. | | visualDiff | boolean | false | Reserved for the post-MVP visual-diff add-on. No-op in v1. | | report.footer | boolean | true | Show the tool-credit footer in the generated HTML report. Set false to suppress it. |

The options type is published — import type { TraceLaneOptions } from '@tracelane/wdio'.

Hook-factory alternative (no Service)

For setups that can't register a Service, the same logic is available as plain wdio.conf.ts hook functions:

import { traceLaneHooks } from '@tracelane/wdio/hooks';

const tracelane = traceLaneHooks({ mode: 'failed', outDir: './tracelane-reports' });

export const config: Options.Testrunner = {
  // ...
  beforeSession: tracelane.beforeSession,
  before: tracelane.before,
  beforeSuite: tracelane.beforeSuite,
  beforeTest: tracelane.beforeTest,
  afterCommand: tracelane.afterCommand, // re-injection after navigation
  afterTest: tracelane.afterTest,
  afterSuite: tracelane.afterSuite,
  after: tracelane.after,
  onComplete: tracelane.onComplete,
};

Network capture

By default network is captured in-page by the framework-agnostic rrweb/network@1 plugin (shipped in @cubenest/rrweb-core). It works on every browser — Chrome, Edge, Firefox, Safari, and cloud Selenium — with no CDP and no extra service, because the plugin wraps fetch/XHR and reads PerformanceObserver entries from inside the page.

Privacy-first by default: only URL, method, status, and timing are captured. Request/response headers and bodies are OFF unless you opt in via capture.networkOptions (recordHeaders / recordBody, plus masking hooks like maskRequestFn and payloadHostDenyList). A couple of accuracy caveats of the default timing surface:

  • For cross-origin sub-resources (images, scripts, fonts loaded from another origin), the Resource Timing spec reports status: 0 and no method — these are not surfaced as failures.
  • Accurate per-request status for fetch/XHR requires those wrappers, which are part of the default capture; the plugin only omits header/body payloads unless opted in.

CDP fallback (optional enhancement)

When a CDP-capable session is present, tracelane additionally uses browser.cdp(...) to capture authoritative HTTP status for failed responses (status >= 400) and true no-response failures (CORS/DNS/offline/abort) that the page wrappers can't always see. These are routed into the report's console timeline (prefixed [tracelane.net]) and the report merges them over the in-page rows for the same request (real status wins). To enable it:

  • WDIO 9: @wdio/devtools-service has no stable v9 line (it stabilized at v10); use the v10 service or a CDP-capable session.

If CDP is unavailable (cloud Selenium, Firefox, Safari), nothing is lost beyond the CDP-only authoritative-status enhancement — the in-page plugin still populates the network panel and the report is still produced.

Supported runners / browsers

| Runner | Status | |---|---| | Mocha | Supported (primary) | | Jasmine | Supported (same afterTest result shape) | | Cucumber | Supported via beforeScenario/afterScenario |

| Browser | rrweb + console | Network (in-page plugin) | Authoritative status / no-response failures (CDP) | |---|---|---|---| | Chrome / Chromium ≥ 116 | Yes | Yes | Yes (with a CDP-capable session) | | Edge (Chromium) | Yes | Yes | Yes | | Firefox | Yes | Yes (in-page plugin) | No (CDP is Chromium-only) | | Safari | Yes | Yes (in-page plugin) | No |

Playwright + Cypress

The design is portable across runners — same @tracelane/core engine, different glue. Tracking issues:

  • @tracelane/playwright — Playwright Reporter implementing onTestEnd + onAttachment for shareable HTML. Targeted for week 2-3 of the public launch.
  • @tracelane/cypress — JSON-output adapter only (no Cypress Test Replay overlap). Targeted for week 11.

Watch the release notes on Cubenest/rrweb-stack or follow @cubenest_in on X (when announced).

Versioning & telemetry

Semantic Versioning. Currently 0.1.0-alpha.x (pre-release; the API may shift before 1.0.0). See SUPPORTED.md for the compatibility matrix and the CHANGELOG for release history.

No telemetry. tracelane collects and sends nothing; reports are written to your local outDir only. The generated HTML report includes a footer crediting the tool; you can suppress it with report: { footer: false }.

License

Apache 2.0. The bundled rrweb engine + console plugin remain MIT-licensed; see NOTICE.

Contributions are accepted under the Developer Certificate of Origin (DCO) — sign your commits with git commit -s. See CONTRIBUTING.md + SECURITY.md.