Skip to content
SDETRole
SDETRole

Lesson 7 of 11 · AI in Software Testing

Self-Healing Locators

How self-healing locators work (element fingerprints, similarity scoring, fallbacks), Healenium as an open-source example, the risks of silent heals and safeguards that keep tests honest.

intermediate 8 min read Updated

You will learn to

  • Explain how self-healing locators fingerprint elements and score candidates
  • Describe how an open-source tool such as Healenium heals Selenium locators
  • Identify the risks of self-healing, including masked regressions and wrong-element interactions
  • Put safeguards in place: logging, thresholds, review of heals and fixing the source

Prerequisites

  • Playwright Locators
  • Page Object Model
  • Introduction to AI-Powered Testing

A large share of UI test maintenance is locator maintenance. A developer renames a CSS class, wraps a button in a new div or changes an ID, and tests that were checking perfectly good behaviour fail with “element not found”. Self-healing locators try to recover automatically: when the original locator fails, the tool searches the page for the element that most likely is the one you meant, uses it, and reports the substitution.

The idea is attractive, and in narrow cases it saves real time. It also introduces a new failure mode: tests that pass while interacting with the wrong thing. This lesson explains the mechanism so you can judge both sides.

The problem self-healing addresses

Locators break for two different reasons, and the distinction matters:

  1. Cosmetic change: the element is the same, with the same purpose, but its attributes or position changed. The test should keep passing. This is what healing is for.
  2. Behavioural change: the element was removed, replaced or now does something different. The test should fail, because that may be a regression or an intended change that needs a test update.

A healing tool cannot know the developer’s intent. It can only estimate similarity. Every design decision below is about separating case 1 from case 2 as well as possible.

Before adopting healing, check whether better locators would remove most breakage. Role-based locators (getByRole('button', { name: 'Submit order' })) and dedicated test IDs survive most refactoring, because they target what users and tests care about rather than markup structure. Healing is a supplement to good locators, not a substitute.

How healing works

Most self-healing implementations, whether rule-based or using machine learning, follow the same three steps.

1. Fingerprint the element when it works

When a locator successfully finds an element, the tool records a fingerprint: several attributes describing it, for example:

  • tag name, ID, name, classes and test ID attribute
  • visible text and accessible name
  • role and type (button, link, textbox)
  • position in the DOM (parent chain, sibling index) and sometimes position on screen
  • nearby text, such as an associated label

These are stored per locator, locally or in a database, and refreshed on later successful runs.

2. Score candidates when it fails

When the locator finds nothing, the tool collects candidate elements from the current page and scores each one against the stored fingerprint. Scoring can be a weighted comparison of attributes, a tree-similarity algorithm on DOM paths, or a trained model. The output is a ranked list with similarity scores.

3. Fall back, use and report

If the best candidate scores above a threshold, the tool uses it, typically generates a new locator for it, and records the heal. If no candidate is good enough, the original failure is reported.

Here is a deliberately simple, transparent sketch of the scoring idea in TypeScript. Real tools are more sophisticated, but the shape is the same:

type Fingerprint = {
  tag: string;
  id?: string;
  testId?: string;
  role?: string;
  text?: string;
  classes: string[];
};

const WEIGHTS = { testId: 0.35, id: 0.2, role: 0.15, text: 0.2, tag: 0.05, classes: 0.05 };

function jaccard(a: string[], b: string[]): number {
  const A = new Set(a);
  const B = new Set(b);
  const inter = [...A].filter((x) => B.has(x)).length;
  const union = new Set([...A, ...B]).size;
  return union === 0 ? 1 : inter / union;
}

export function similarity(stored: Fingerprint, candidate: Fingerprint): number {
  let score = 0;
  if (stored.testId && stored.testId === candidate.testId) score += WEIGHTS.testId;
  if (stored.id && stored.id === candidate.id) score += WEIGHTS.id;
  if (stored.role && stored.role === candidate.role) score += WEIGHTS.role;
  if (stored.text && stored.text.trim() === candidate.text?.trim()) score += WEIGHTS.text;
  if (stored.tag === candidate.tag) score += WEIGHTS.tag;
  score += WEIGHTS.classes * jaccard(stored.classes, candidate.classes);
  return score;
}

export function pickHeal(stored: Fingerprint, candidates: Fingerprint[], threshold = 0.6) {
  const ranked = candidates
    .map((c) => ({ c, score: similarity(stored, c) }))
    .sort((a, b) => b.score - a.score);
  const [best, second] = ranked;
  if (!best || best.score < threshold) return { healed: false as const };
  // Refuse ambiguous heals: two candidates almost equally similar.
  if (second && best.score - second.score < 0.1) return { healed: false as const, reason: 'ambiguous' };
  return { healed: true as const, element: best.c, score: best.score };
}

Notice two safety features even in this toy version: a minimum score and an ambiguity check. If two buttons look equally like the original, the tool should fail rather than guess.

Healenium: an open-source example

Healenium is an open-source self-healing library for Selenium WebDriver (Java). In outline:

  • You wrap your existing WebDriver in Healenium’s self-healing driver, so locator calls go through it.
  • When findElement succeeds, Healenium stores information about the element and its location in the page structure in a backend service with a database (run as containers).
  • When a locator fails, it compares the stored page structure with the current page, finds the most similar element using a tree-comparison algorithm, and continues the test with it.
  • It records healed locators and provides reports showing the original locator, the healed one and a screenshot, so people can review the change and update the code.

The design is a good reference model: healing happens at run time, but the heals are visible and meant to be reviewed, and the end goal is to fix the locator in source. Setup details (dependencies, backend containers, configuration properties) change between releases, so follow the project’s current documentation rather than copying configuration from older articles.

Commercial test platforms also offer self-healing, often described as AI-based. Ask vendors precisely what is fingerprinted, how thresholds work, how heals are reported and whether healing can be made to fail a build.

The risks

Masking real regressions

Suppose the “Place order” button is accidentally removed from the checkout page, and a “Save for later” button sits in a similar position with similar classes. A healing tool may pick “Save for later”, the test clicks it, and if the following assertions are weak, the test passes. A critical bug ships with a green build.

Silent wrong-element interactions

Even without a regression, a heal can choose the wrong element: the second of two similar inputs, a hidden duplicate, or a button in a different section with the same text. The test continues with corrupted state and fails later in a confusing place, or passes for the wrong reason.

Locator debt grows invisibly

If heals are not reviewed, the codebase keeps the broken locators and the tests depend on the healing service forever. Each run pays the healing cost, and the stored fingerprints drift further from the source code.

Weaker signal from tests

A test suite exists to tell you when behaviour changed. Healing deliberately suppresses some of those signals. The more aggressive the healing, the less a green run means.

Safeguards

If you use self-healing, put these controls in place:

  • Log every heal with the original locator, the healed locator, the similarity score, a screenshot or DOM snapshot and the test name.
  • Require review. Heals generate a report or ticket; someone confirms the element is correct and updates the locator in source. A heal that is not reviewed within an agreed time becomes a failing test.
  • Make heals visible in CI. Mark the run as “passed with heals” or unstable, rather than plain green, and show the count on the pipeline summary.
  • Set conservative thresholds and refuse ambiguous candidates.
  • Never heal on critical assertions. Restrict healing to navigation and interaction steps; elements used in assertions about prices, totals, permissions or legal text should fail if not found exactly.
  • Disable healing for release gates if you cannot meet the review requirement, or run gating suites in strict mode and use healing only to speed up diagnosis.
  • Strengthen assertions after each step. If the test verifies the outcome of each action (the order confirmation page appears with the order number), a wrong-element heal is much more likely to be caught.
  • Track metrics: heals per run, heals per locator and time to fix. A rising heal count points to unstable markup or poor locators that should be addressed at the source, for example by adding test IDs.

Practice exercise

Your company is evaluating a self-healing feature for a 1,200-test Selenium suite in which about 30 tests break each sprint because of locator changes. A manager proposes enabling healing everywhere, including the release gate, “so the pipeline is always green”. Write a recommendation.

Show a model answer

Recommendation: adopt healing in a controlled way, and not as a way to keep the pipeline green.

  1. Fix the cause first: analyse the 30 weekly breakages. If most come from CSS class or structure changes, agree with developers on stable test IDs or accessible names for interactive elements and migrate the most-broken page objects. This reduces breakage without any new risk.
  2. Pilot healing (for example Healenium with its backend) on the non-gating regression suite only, for a fixed period.
  3. Safeguards during the pilot: log every heal with screenshots; a run with heals is reported as “passed with heals”, not green; each heal becomes a ticket to update the locator; refuse ambiguous heals; no healing on elements used in assertions about money, permissions or confirmation.
  4. Release gate stays strict: a missing element fails the build, because a heal there could hide a removed or replaced control, which is exactly the regression the gate exists to catch.
  5. Measure: heals per sprint, how many heals were correct, any wrong-element heals found in review, and maintenance hours saved. Decide on wider use from that evidence.

Key takeaways

  • Self-healing locators fingerprint elements when they work, score candidates when they fail, and fall back to the best match above a threshold.
  • Healenium is an open-source example for Selenium that stores element data in a backend and reports healed locators for review.
  • The main risks are masked regressions, silent wrong-element interactions and growing locator debt.
  • Log and review every heal, use conservative thresholds, refuse ambiguous matches and keep release gates and critical assertions strict.
  • Good locators (roles, accessible names, test IDs) prevent most breakage; healing is a supplement, not a substitute.

Key terms

Finished this lesson?

Progress is saved in this browser. No account needed.

Type to search across SDETRole.

Full-text search by Pagefind · runs in your browser Open search page →