Regression & CI

A discovered anomaly never becomes a test on its own. Jevitate reproduces it, minimizes it, and keeps a deterministic, replayable repro — evidence first, always.

Available. Capture a failing Recording into a committed regression with jevitate regression capture --from <file> --id <id>. The artifact is a deterministic Recording that replays via the interpreter; direct Playwright export is a candidate for a later slice.

Evidence, not interpretation

After every action, Jevitate collects what actually happened and monitors for:

  • Browser errors: uncaught exceptions, page errors, console errors, crashes, navigation failures
  • Network errors: failed requests, unexpected 4xx/5xx, timeouts, aborted or malformed responses
  • UI failures: blank screens, error boundaries, infinite spinners, unresponsive controls, stale overlays
  • Behavioral anomalies: no state change, endless repeats, success UI despite a failed request, backend success with no UI transition

A failure is based on observable evidence or an explicit invariant you define; a suspicious state may be recorded without being classified as a confirmed failure. Failure classes include browser_exception, console_error, network_failure, assertion_failure, dead_end, infinite_loop, unexpected_state, and custom_invariant_failure.

The trace

Every execution produces a serializable, replayable trace. Each step captures its evidence:

step:
  number: 7
  state_before: "sha256:..."
  action: CLICK
  target:
    role: button
    name: Apply
    test_id: apply-promo
  decision_probability: 0.91
  state_after: "sha256:..."
  console_errors: []
  network_failures: []
  screenshots: []

Traces carry enough semantic selector information to reconstruct locators — never only ephemeral DOM indices.

Reproduce, then minimize

Explore → Discover failure → Capture trace → Reproduce
  → Minimize trace → Commit regression → Fix → Verify
jevitate regression capture --from ./failing.recording.json --id checkout-001 --attempts 3

regression capture retries the failure --attempts times and computes a reproduction rate. Flaky failures are labeled and refused — never silently promoted to deterministic regressions. Reproducible ones are minimized by replay-and-elimination, often from dozens of actions down to a handful, while preserving reproduction at each step. The result is committed as <id>.recording.json alongside a <id>.meta.json sidecar (attempts, reproduction rate, optional summary).

Durable selectors

The committed Recording is built from semantic descriptors, preferred in order:

  1. data-testid
  2. role + accessible name
  3. label, then placeholder
  4. stable application identifier, then text
  5. CSS selector (last resort)

These never depend on Jev or temporary DOM indices, so the repro replays anywhere via the interpreter — no model in the loop. Direct Playwright export (a standalone .spec.ts) is a candidate for a later slice, not shipped today.

Proof-of-failure / proof-of-fix

Replay the committed regression Recording against the buggy build (it fails), fix the code, and replay it again (it passes). This is behavioral evidence, not a proof of total correctness: a passing regression proves only that the captured failure no longer reproduces under the encoded conditions. Failing to find more bugs never proves none exist.

Artifacts

.jevitate/
├── runs/
│   └── <run-id>/
│       ├── run.json
│       ├── trace.json
│       ├── states.json
│       ├── transitions.json
│       ├── failures.json
│       └── screenshots/
├── regressions/
└── coverage/