Skills / heal playwright tracer
heal playwright tracer
Open-source statement-level Playwright tracer, purpose-built for AI agents. Analyzes test runs with increased accuracy.
Installation
Kompatibilitaet
Beschreibung
@heal-dev/heal-playwright-tracer
heal-playwright-tracer is an agent-first diagnostic layer for your Playwright tests. It gives agents (and humans) everything they need to quickly analyze test results.
👉 Add this to your playwright config, run your tests, point Claude to the improved heal trace, get more accurate test diagnosis
Why
The playwright trace doesn't contain enough data for LLM-based agents such as Claude or Open Code to analyze tests results reliably. That's because the trace ifs focused on locator evaluation, while real-life tests also evaluate non-playwright code. Heal adds the missing instrumentation layer to let LLM agents work their magic. And it's useful for humans in complex test codebases, too!
| Feature | Playwright Trace | Heal Tracer | Example: What Heal Adds |
| -------------- | --------------------- | -------------------- | ----------------------------------------------------------------------------------------- |
| Granularity | Action-level | Statement-level | Shows let x = calculate() line-by-line, not just the final page.click(). |
| Data Format | ZIP/Binary | NDJSON Stream | {"type":"step","file":"auth.spec.ts","line":12,"val":{"user":"dev"}} |
| Visual Context | Standard screenshots | Highlighted locators | An image where the target button is outlined in a neon overlay to prove hit-box accuracy. |
| Variable State | Limited/Debugger only | Full Variable Values | Captures that status_code was 403 inside a hidden helper function. |
| Error Detail | Standard stack trace | Serialized Errors | A JSON object containing the DOM snapshot at the exact millisecond of the throw. |
| Timing | Action durations | Per-statement timing | Identifies that a specific if statement logic took 2.5s to evaluate. |
| Correlations | Loose logs/network | API Correlations | Links Trace_ID_99 directly to Source_Line_45 in the NDJSON stream. |
Install
npm install -D @heal-dev/heal-playwright-tracer
Wire the Babel plugin in playwright.config.ts.
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
// @ts-ignore — `babelPlugins` is a supported Playwright option not yet in its public types
'@playwright/test': {
babelPlugins: [
[
require.resolve('@heal-dev/heal-playwright-tracer/code-hook-injector'),
{ include: [/\/tests\//] },
],
],
},
});
Or, if you prefer to keep the config fully typed, declare the
option once at the top of the file instead of using @ts-ignore:
declare module '@playwright/test' {
interface Config {
'@playwright/test'?: {
babelPlugins?: Array<[string, object?]>;
};
}
}
Per-test output lands at
test-results/<test>/heal-data/heal-traces.ndjson.
Optional: capture worker crashes
When a Playwright worker dies before the fixture can finalize its
trace (OOM, SIGKILL, segfault, process.exit()), the per-test
NDJSON is left without its test-result terminator. Register the
reporter to have the Playwright main process append a synthesized
test-result carrying the classified crash cause (e.g.
OutOfMemoryError, WorkerCrash):
// playwright.config.ts
export default defineConfig({
reporter: [['@heal-dev/heal-playwright-tracer/reporter']],
// ...
});
Fully optional and idempotent: on the common case where the fixture finalizes cleanly, the reporter is a no-op.
Usage
- After installing Heal, run your tests with the usual
npx playwright testcommand. - You should see
heal-traces.ndjson. - You can ask Claude or another agent to use those to understand your test results.
Claude Skill
See this Claude skill for a starter.
Sample output
heal-data/heal-traces.ndjson — one record per line:
{"kind":"test-header","schemaVersion":1,"test":{"title":"it works","file":"tests/example.spec.ts","context":{"testId":"...","attempt":1}}}
{"kind":"statement","statement":{"loc":{"line":5},"source":"await page.goto('https://example.com')","durationMs":412,"status":"ok","children":[...]}}
{"kind":"statement","statement":{"loc":{"line":6},"source":"await expect(page.getByRole('heading')).toBeVisible()","durationMs":73,"status":"ok"}}
{"kind":"test-result","status":"passed","duration":1234,"stdout":"...","stderr":""}
Schema: src/domain/trace-event-recorder/model/statement-trace-schema.ts
(also exported as @heal-dev/heal-playwright-tracer/statement-trace-schema).
Screenshots
Every statement that calls a patched Playwright locator action
(click, fill, hover, press, …) or a locator assertion
(expect(locator).toBeVisible(), toHaveText(), …) produces a
PNG screenshot with the targeted element outlined via an overlay
drawn in-page — so the agent sees what Playwright was actually
pointing at at the moment the action ran, not just the raw page.
Files are written to the per-test heal-data/ directory and
referenced on the corresponding statement via the screenshot
field:
{"kind":"statement","statement":{"source":"await page.getByRole('button', { name: 'Submit' }).click()","status":"ok","screenshot":"stmt-0007.png"}}
{"kind":"statement","statement":{"source":"await expect(page.getByRole('alert')).toBeVisible()","status":"ok","screenshot":"stmt-0008.png"}}
Statements that don't touch a locator (plain JS, utility calls,
page.goto) have no screenshot field — capture is scoped to the
Playwright surface where it adds diagnostic signal.
Architecture, and extending the tracer
See development.md
Caveats
The Babel plugin rewrites every leaf statement with a try/catch/finally
and three hook calls — the same shape of transformation Istanbul applies
for code coverage. Two consequences to be aware of:
- Instrumented files are larger. Each statement gains a wrapper, so on-disk size of transformed test files grows noticeably (typically ~2–4×, depending on statement density). This affects the files Playwright loads into workers, not your application bundle.
- Tests run slightly slower. The per-statement hook overhead is
small in absolute terms but not free — expect a modest slowdown on
CPU-bound test code. I/O-bound tests (the common case:
await page.click(...), network, navigation) are dominated by the browser and barely move.
Scope the include filter in playwright.config.ts so only your
tests/ directory is instrumented — never your app code or
node_modules — to keep the cost contained.
License
Copyright © 2026 MYIA SAS.
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See the LICENSE file for the full text.
Aehnliche Skills
last30days skill
AI agent skill that researches any topic across Reddit, X, YouTube, HN, Polymarket, and the web - then synthesizes a grounded summary
frontend slides
Create beautiful slides on the web using Claude's frontend skills
context mode
Context window optimization for AI coding agents. Sandboxes tool output, 98% reduction. 14 platforms
claude seo
Universal SEO skill for Claude Code. 19 sub-skills, 12 subagents, 3 extensions (DataForSEO, Firecrawl, Banana). Technical SEO, E-E-A-T, schema, GEO/AEO, backlinks, local SEO, maps intelligence, Google APIs, and PDF/Excel reporting.
claude ads
Comprehensive paid advertising audit & optimization skill for Claude Code. 250+ checks across Google, Meta, YouTube, LinkedIn, TikTok, Microsoft & Apple Ads with weighted scoring, parallel agents, industry templates, and AI creative generation.
claude obsidian
Claude + Obsidian knowledge companion. Persistent, compounding wiki vault based on Karpathy's LLM Wiki pattern. /wiki /save /autoresearch