> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser auto-heal E2E loop for Playwright tests

> Run the /heal-e2e loop to drive a feature in Playwright, classify console, network, and assertion failures, and fix flaky E2E tests to green.

**Version:** 1.0.0\
**Last Updated:** 2026-05-30\
**Purpose:** Run a guided, signal-driven loop that drives a feature in Playwright, classifies every failure signal, and fixes the test (or surfaces a real bug) until the run is green.

***

## What it is

Browser auto-heal is an agent-driven loop that wraps Playwright with a structured fix-to-green workflow. Each attempt runs your E2E target, collects test assertions, console errors, uncaught page errors, and network responses with status `>= 400`, then classifies the failures so the agent can apply the right fix.

Use it when you want a single command that:

* Reproduces an E2E failure on demand.
* Distinguishes locator drift, flakes, and real bugs.
* Stops automatically on spec drift or backend regressions instead of silently "fixing" them.
* Leaves a committed Playwright regression test behind on success.

## When to use it

* **TDD green step.** After a unit test passes, verify the feature in the browser before moving on.
* **Spec completion gate.** Run the journey clean before marking a spec complete.
* **Flaky test triage.** A test passes locally but fails in CI — let the loop classify the signal.
* **Pre-merge confidence.** Re-run a critical core (`cl`, `pm`, `hr`, etc.) end-to-end after a refactor.

Do not use it to bypass review. The loop never auto-merges, and it never auto-edits application code when the signal looks like spec drift or a backend regression — those are surfaced for a human.

## How the loop works

Each attempt is a single Playwright run plus a verdict:

1. **Run one attempt.** The verdict CLI invokes Playwright, writes `playwright-report/heal-signals.json`, prints `HEAL_VERDICT=<value>`, and exits with a status code:
   * `0` — green
   * `2` — needs-fix
   * `3` — structural-stop (spec drift or backend regression)
   * `4` — retry-exhausted
2. **Read the verdict.**
   * `green` — stop. The Playwright journey is your regression test; make sure it is committed.
   * `structural-stop` — stop. A `SPEC_DRIFT` or `BACKEND_REGRESSION` was detected. The loop writes a `heal-report.md` with the signal, the diagnosis, and the recommended human action. Do not auto-fix.
   * `retry-exhausted` — stop. A `heal-report.md` is written with the remaining signals.
   * `needs-fix` — continue.
3. **Diagnose and fix by class.** Each failure is classified:
   * `LOCATOR_DRIFT` — update the selector in the spec to match the current UI.
   * `FLAKE` — replace fixed waits with web-first assertions or `expect.poll`; fix the race.
   * `REAL_BUG` — fix the application code. The console error, 4xx, or assertion is a true defect.
   * Ambiguous (passes but looks wrong, console error with no stack) — escalate to a live Playwright MCP browser session to reproduce and confirm root cause before editing.
4. **Re-run** with the next attempt number. Repeat until `green`, `structural-stop`, or `retry-exhausted` (default cap: 4 attempts).

## Running the loop

The agent-driven entry point is the `/heal-e2e` command. It resolves a target, drives the loop, and applies fixes per class.

```text theme={null}
/heal-e2e <core | spec-id | path | --changed>
```

Targets:

| Target                          | Resolves to                                              |
| ------------------------------- | -------------------------------------------------------- |
| Core code (`cl`, `pm`, `hr`, …) | `tests/e2e/<core>/`                                      |
| Spec id                         | The spec's generated journey (auto-generated if missing) |
| Path                            | Used as-is                                               |
| `--changed`                     | The set of spec tests for changed specs                  |

To drive a single attempt yourself — for example, to inspect the signals without the agent loop — use the verdict CLI directly:

```bash theme={null}
npm run heal:verdict -- <target> --attempt 1 --max 4
```

The CLI exits with the status codes listed above. Read `playwright-report/heal-signals.json` to inspect the raw signals it captured.

## Example: heal a flaky CL journey

```bash theme={null}
# Single manual attempt against the CL core
npm run heal:verdict -- cl --attempt 1 --max 4

# Or run the full agent-driven loop
/heal-e2e cl
```

If the verdict is `needs-fix` with a `LOCATOR_DRIFT` classification, update the selector in the spec and re-run with `--attempt 2`. If the verdict is `structural-stop`, open the generated `heal-report.md` and follow the recommended action.

## Guardrails

* **No auto-merge.** A human reviews the final diff.
* **No auto-edit on structural signals.** `SPEC_DRIFT` and `BACKEND_REGRESSION` always surface to a human.
* **Retry cap.** Default is 4 attempts per loop; the loop stops cleanly when exhausted.
* **Server reuse.** The loop reuses an existing preview server when available instead of starting a second build.
* **No PHI in signals.** `heal-signals.json` records network paths and status codes only — never request or response bodies.

## Related

* [Testing setup and run](/testing/TESTING_SETUP_AND_RUN) — environment, Playwright install, and per-core scripts.
* [Testing setup and run §9 (AI / interactive browser testing)](/testing/TESTING_SETUP_AND_RUN) — credentials and login flow for browser-driven tests.
* [E2E test scenarios](/testing/E2E_TEST_SCENARIOS) — critical user journeys covered by E2E.
