Skip to content

bigmistqke/introspection

Repository files navigation

@introspection

Introspection is a Playwright-integrated tracing framework. A trace records a stream of typed trace events — network requests and responses, JS errors with scope locals, DOM snapshots, Playwright actions — and their associated assets to disk as NDJSON. Plugins are the unit of feature capture, each subscribing to Chrome DevTools Protocol (CDP) events or page state.

When an end-to-end test fails, the usual debugging loop is: read the error, guess what the app was doing, add more logs or breakpoints, re-run. With a trace on disk, you can query the recorded trace instead of re-running the test.

Introspection is built primarily for AI-assisted debugging — the trace gives a model the full execution context to reason about — but the same trace is queryable by humans too, via the introspect CLI or programmatically through @introspection/read.


Table of contents


How it works

attach(page, { plugins }) opens a CDP trace alongside the Playwright test. Plugins contribute to the event stream by subscribing to CDP events and/or injecting scripts in the browser.


Packages

Package Description
introspect CLI for querying traces: summary, events, list, plugins
@introspection/playwright Attach tracing to a Playwright page — the main integration point
@introspection/read Programmatic access to traces — adapter-based, environment-agnostic
@introspection/write Trace recording — creates traces, appends events, writes assets
@introspection/utils Shared utilities: CDP normalizers, event bus, debug, snapshot
@introspection/types Shared TypeScript types for events, plugins, and trace format

Plugins

Every capability is a plugin. If you don't wire it up, it won't log. Pass the plugins you want to attach() via the required plugins option.

Plugin Package What it captures
cdp() @introspection/plugin-cdp Raw Chrome DevTools Protocol commands and events (advanced instrumentation)
consolePlugin() @introspection/plugin-console Browser console output
debuggerPlugin() @introspection/plugin-debugger Debugger pauses with scope locals and call stack
defaults() @introspection/plugin-defaults Composition: [network(), jsError(), debuggerPlugin(), consolePlugin()]
jsError() @introspection/plugin-js-error JS exceptions and unhandled rejections
network() @introspection/plugin-network HTTP requests, responses, and response bodies
performance() @introspection/plugin-performance Core Web Vitals, resource timing, long tasks, layout shifts, and paint
webgl() @introspection/plugin-webgl WebGL state, uniforms, draw calls, textures, and canvas PNGs

Framework Specific Plugins

Plugin Package What it captures
reactScanPlugin() @introspection/plugin-react-scan React component renders and reconciler commits, via react-scan
redux() @introspection/plugin-redux Store dispatches from Redux, Zustand, Valtio, and other Redux DevTools–compatible libraries, with optional state snapshots
solidDevtools() @introspection/plugin-solid-devtools SolidJS component structure, reactive updates, and dependency graph

Quick start

pnpm add -D @introspection/playwright introspect
import { attach } from "@introspection/playwright";
import { defaults } from "@introspection/plugin-defaults";

test("checkout flow", async ({ page }) => {
  const handle = await attach(page, {
    testTitle: "checkout flow",
    plugins: defaults(),
  });

  await handle.page.goto("/cart");
  await handle.page.getByRole("button", { name: "Checkout" }).click();

  await handle.detach();
});

After the test runs, query the trace:

introspect summary
introspect events --type js.error
introspect events --type network.*  # Prefix matching: all network.* events
introspect events --type network.response --filter 'event.metadata.status >= 400'

Full documentation:


Trace format

Each test produces a trace directory:

.introspect/
  <trace-id>/
    meta.json        ← id, startedAt, endedAt, label
    events.ndjson    ← one JSON event per line
    assets/          ← response bodies, DOM snapshots, plugin captures

TraceEvents are plain JSON objects with a unique id, type, timestamp (ms since test start), references to corresponding assets and event-specific metadata.


Continuous releases

Every push to main publishes preview builds via pkg.pr.new. You can install any commit's build directly without waiting for a versioned release — useful for trying unreleased fixes or features.

The full list of published previews is tracked on the releases branch, with install commands for each package at every commit and a JSON list for use in package.json overrides (e.g. in a monorepo).

About

🔮

Resources

Contributing

Stars

Watchers

Forks

Contributors