Skip to main content
/tayyab/portfolio — zsh
tayyab
TA
// dispatch.read --classified=false --access-level: public

Self-Healing Tests Explained: How AI Fixes Your Broken Selenium/Playwright Tests

April 7, 2026 EST. READ: 13 MIN #Quality Assurance

TL;DR

Self-healing tests use AI to automatically update locators when your UI changes. Implementation in an existing Playwright framework takes 1-2 days. Real-world result: 60-80% reduction in test maintenance time. The trade-off: slightly slower test execution and occasional false heals.

The $100K Problem

You know the cycle. Developer redesigns the login page. 47 tests break. None of them found a real bug — they all broke because a button ID changed from btn-login to login-button.

This costs engineering teams thousands of hours per year. On a team with 500+ tests, 30-40% of QA time goes to fixing locators that broke due to UI changes — not finding actual bugs.

Self-healing tests fix this.

How Self-Healing Works

  1. Multiple locator strategies: Instead of one CSS selector, the framework stores 3-5 ways to find each element (ID, text, aria-label, XPath, visual position).
  2. Fallback chain: When the primary locator fails, the framework tries alternatives automatically.
  3. AI matching: If all stored locators fail, AI analyzes the page to find the most likely matching element based on context, position, and semantics.
  4. Self-update: When a fallback locator works, the framework updates the primary locator for next time.
  5. Reporting: Logs every heal so you can review and validate the AI's decisions.

Implementing Self-Healing in Playwright

Approach 1: Smart Locator Wrapper (DIY)

// lib/smart-locator.ts
import { Page, Locator } from '@playwright/test';

interface LocatorStrategy {
type: 'css' | 'text' | 'role' | 'testid' | 'xpath';
value: string;
priority: number;
}

export class SmartLocator {
private strategies: LocatorStrategy[];
private page: Page;
private name: string;

constructor(page: Page, name: string, strategies: LocatorStrategy[]) {
this.page = page;
this.name = name;
this.strategies = strategies.sort((a, b) => a.priority - b.priority);
}

async find(): Promise<Locator> {
for (const strategy of this.strategies) {
try {
const locator = this.getLocator(strategy);
if (await locator.isVisible({ timeout: 2000 })) {
if (strategy.priority > 0) {
console.log(
[HEALED] "${this.name}" - primary failed, +
used ${strategy.type}: ${strategy.value}
);
}
return locator;
}
} catch {
continue;
}
}
throw new Error(All locator strategies failed for "${this.name}");
}

private getLocator(strategy: LocatorStrategy): Locator {
switch (strategy.type) {
case 'testid': return this.page.getByTestId(strategy.value);
case 'role': return this.page.getByRole('button', { name: strategy.value });
case 'text': return this.page.getByText(strategy.value);
case 'css': return this.page.locator(strategy.value);
case 'xpath': return this.page.locator(xpath=${strategy.value});
}
}
}

Usage in Tests

const loginButton = new SmartLocator(page, 'Login Button', [
  { type: 'testid', value: 'login-btn', priority: 0 },
  { type: 'role', value: 'Sign In', priority: 1 },
  { type: 'text', value: 'Sign In', priority: 2 },
  { type: 'css', value: 'form button[type="submit"]', priority: 3 },
]);

await (await loginButton.find()).click();

Approach 2: AI-Powered Healing (Advanced)

For cases where all stored locators fail, use AI to analyze the page and find the element:

async findWithAI(): Promise<Locator> {
  // Take screenshot and get page HTML
  const html = await this.page.content();
  

// Ask AI: "Find the element that is most likely the login button"
const aiSuggestion = await askClaude(
Given this HTML, find the CSS selector for an element +
that functions as: "${this.name}". +
Previous selectors were: ${this.strategies.map(s => s.value).join(', ')}. +
Return only the CSS selector.,
html.substring(0, 5000) // Truncate for token limits
);

return this.page.locator(aiSuggestion);
}

Commercial Self-Healing Tools

ToolApproachCostBest For
MablBuilt-in self-healing + visual AI$150+/moTeams wanting no-code + healing
testRigorPlain-English tests (inherently heal)$250+/moNon-technical teams
ApplitoolsVisual AI healing for visual testsCustomVisual regression testing
Healenium (OSS)Selenium plugin for self-healingFreeJava/Selenium teams
DIY (above)Custom Playwright wrapperFreePlaywright teams wanting control

Real-World Results

After implementing self-healing on a 400-test Playwright suite:

MetricBeforeAfterChange
Tests broken by UI changes/month458-82%
Hours spent fixing locators/month204-80%
False positives (healed incorrectly)03/monthNew risk
Test execution time8 min9.5 min+19%
Overall QA productivityBaseline+35%Net positive

The Trade-offs

Pros:

  • 60-80% reduction in locator maintenance
  • Tests survive UI redesigns without manual updates
  • QA engineers focus on real bugs, not broken selectors

Cons:

  • 15-20% slower test execution (fallback chain takes time)
  • False heals (AI finds wrong element) require monitoring
  • Initial setup effort (1-2 days for DIY approach)
  • Can mask real UI bugs (element moved to wrong position but test still "heals")

Best Practices

  1. Log every heal. Review healed tests weekly to catch false positives.
  2. Use test IDs as primary locators. Self-healing is a safety net, not a primary strategy.
  3. Set a heal limit. If a test heals more than 3 times in a week, flag it for human review.
  4. Don't heal visual assertions. Only heal element finding, not visual verification.
  5. Combine with visual testing. Self-healing finds elements; Applitools verifies they look right.

Frequently Asked Questions

Does self-healing work with Selenium?

Yes. Healenium is an open-source Selenium plugin that adds self-healing. It's Java-based and works with WebDriver. The concept is the same — multiple locator strategies with AI fallback.

Will self-healing mask real bugs?

It can, which is why logging and review are essential. If a button moves from the header to the footer, a self-healing test might still find and click it — passing the test but missing a real UX regression. Combine with visual testing to catch these cases.

How much does the AI fallback cost per run?

If using Claude API for AI healing: about $0.001-0.01 per heal (sending truncated HTML for analysis). In practice, AI fallback triggers rarely (1-5 times per run after initial setup). Monthly cost: $1-5 for most teams.

Need help implementing self-healing tests?

Book a Free Call

Related Articles:

Tayyab Akmal
// author

Tayyab Akmal

AI & QA Automation Engineer

6 years of catching critical bugs in fintech, e-commerce, and SaaS — then building the Playwright and Selenium automation that prevents them from shipping again.

// related_dispatches

YOU MIGHT ALSO READ

// feedback_channel

FOUND THIS USEFUL?

Share your thoughts or let's discuss automation testing strategies.

→ Start Conversation
Available for hire