Skip to content

ADR-004: Self-healing locators

Status: Accepted ยท Date: 2026-08-23

Context

UI tests break when selectors change even though the underlying element is still present. Naive "self-healing" that retries random selectors is dangerous: it can silently bind a test to the wrong element and hide real regressions.

Decision

Build a fingerprint-based, confidence-scored, fully audited healing engine (automation/self_healing/):

  • On a good run we record an element fingerprint (tag, role, accessible name, text, test-id). Healing looks for the element most similar to that, not any element โ€” this is the core safety property.
  • Candidates are scored by a weighted similarity (role, accessible-name, tag, text, test-id). Confidence drives banded actions: >=0.90 AUTO_HEALED ยท 0.70โ€“0.89 HEALED_WITH_WARNING ยท <0.70 FAILED.
  • Uniqueness gate: a candidate locator is only used if it matches exactly one element. Ambiguous locators are rejected, never guessed.
  • Accessibility-first replacements: the preferred healed locator is getByRole(role, {name}), falling back to a unique test-id, then exact text.
  • Never silent: every decision (including NOT_NEEDED) is written to artifacts/self-healing/healing-history.json; low/medium confidence also writes locator-suggestions.json for a human to review.

Why it can be dangerous (and how we mitigate)

Auto-healing can mask a real UI regression by re-binding to a plausible-but-wrong element. Mitigations: similarity to a recorded fingerprint, a hard uniqueness gate, conservative thresholds, refusing (not guessing) below 0.70, and a complete audit trail so every heal is reviewable. Healing assists triage; it does not overrule a genuine failure.

Consequences

  • (+) Fewer false failures from cosmetic markup churn, with a safety net.
  • (+) The audit log feeds the MCP tools (Phase 6) and failure triage (Phase 5).
  • (โˆ’) Requires capturing fingerprints on green runs โ€” a small instrumentation cost.