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 writeslocator-suggestions.jsonfor 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.