AI-powered Self-Healing Tests system: automatic repair of broken tests

Automated tests fail after every release, and the team spends days on manual fixes instead of product development. We develop a turnkey AI-powered Self-Healing Tests system: it automatically recognizes changed elements and restores checks. The share of manual fixes is reduced severalfold, and regression again becomes a reliable foundation.
Frequently Asked Questions

Self-Healing Tests: why automated tests fail after releases

A green automated test suite before a release — and a scattering of red runs the next day, even though no one changed the business logic.

Failing automated tests in this picture describe not product defects but the fragility of the checks themselves: the build spends time on reruns, and the team investigates what worked before.

The first cause is brittle locators. A selector tied to a chain of nested elements or to a utility CSS class breaks from any markup change: moving a block, changing a theme, replacing a component. The test cannot find the button and fails by timeout, although the button is in place and works.

The second is contracts and step order. An extra field in the response, a changed status code, reordered requests — and schema checks or data preparation fall apart. Asynchrony lies on top: fixed pauses in the test guess the load time instead of waiting for a real event.

Rerunning tests removes the symptom, not the cause. Auto-retry produces a green report, false failures move into the "flaky" category, and in this noise the real failure is lost.

Automated test maintenance starts to consume a noticeable share of the team's time, and trust in the suite drops to zero.

Self-healing tests move the support point inside the run: when a locator misses, the engine searches for the element by a combination of attributes — role, text, neighboring nodes, history of successful finds, as is done on top of Playwright. Below we examine how auto-repair works and where its boundaries lie.

What auto-repair of tests gives: effect by metrics

The effect of auto-repair is measured by run history: run time and the share of edits made by a human are counted before implementation and after a month of operation on the same set of checks. Auto-repair works on top of the existing suite — including where tests are written in Playwright.

A new locator is selected by a combination of attributes: element role, label, position in markup, neighboring nodes, — and comes as a suggestion that the engineer approves in review.

Run time and share of manual edits

The run speeds up not because checks became faster, but because reruns disappear. A test that failed due to a renamed button no longer drags the suite into a rerun and does not block the pipeline. The run proceeds in one pass, and downtime due to a broken check is reduced from a day to hours.

The share of manual edits drops from every fifth check to isolated cases — the engineer switches from fixing locators to new scenarios. The cost of downtime here is measured not in money but in the window during which the team does not deliver changes.

Class of failures that goes away entirely

A whole class of false failures goes away: markup changes with unchanged logic — class changes, block reordering, local redesign.

Real defects remain visible: if the result changed, not the markup, the test keeps failing and highlights the error rather than adjusting to it. The boundary is set by policy: which attributes are considered cosmetic and which are a contract change.

Connection options: full loop, overlay layer, manual mode

Connecting the system to an existing test suite does not require rewriting it: self-healing tests integrates into the same run and triggers when the interface changed but the check must pass.

The mode is chosen by two things — how stable the suite is today and how ready the team is to hand edits to automation.

The difference between options is the depth of intervention: the full loop finds the discrepancy itself and replaces the locator, the overlay layer only suggests a replacement, manual mode shows the broken step and changes nothing.

Switching between modes is reversible — usually they start with the overlay layer and move to the full loop when trust in the proposed replacements accumulates.

Option When it fits Limitations
Full loop Large suite, frequent releases, locator edits consume team time Requires write access to the test repository and an acceptance procedure for auto-edits
Overlay layer Suite works, but release failures have increased Replacement is applied only after an engineer — time savings are partial
Manual edit mode Pilot, many inherited checks, strict change audit Automation only diagnoses; the amount of manual work remains

What changes in the existing test suite

Checks and their logic remain; the layer that accesses the interface changes: brittle bindings to element position are replaced by stable attributes — role, visible text, accessibility attributes.

The share of failures due to markup edits decreases, and time spent investigating a failed run goes to real defects rather than fixing selectors.

How self-healing tests are implemented: stages of work

Implementing self-healing tests is not connecting a library but setting up discipline: the system must distinguish a cosmetic markup edit from a real defect. Therefore, implementation stages begin with an audit of the test suite, not with configuration.

  1. Suite audit. We label tests by stability: how many failures over a period, which are caused by markup edits, which by logic. The output is a list of candidates for auto-repair and those that cannot be treated.
  2. Rule design. We describe which attributes are considered supporting, which substitutions are allowed, what counts as a discrepancy. We fix the rules in text, not "by agreement."
  3. Environment setup. We connect the system to runs, configure storage of failure history and access to the test repository.
  4. Training on history. We run accumulated failures: we check how many the system fixes correctly and where it suggests false edits.
  5. Pilot on a live run. We work in suggestion mode without auto-apply, comparing each fix against the reference.
  6. Handover to the team. We document the rules and leave a process for resolving disputed cases.

Acceptance criteria at each step

Acceptance of the result relies on the measurable: the share of correct auto-repairs on a holdout sample of failures, the number of false edits, run time before and after. Separately, we check rollback — any change must be reversible with one operation.

Who participates on the customer side

An engineer responsible for the test loop and a product owner for resolving disputed cases are needed. Their participation is about an hour per step: approve the rules, confirm the failure reference, accept the result.

What remains in hand: configurations, diagrams, processes

After implementation, working artifacts remain in the repository and on the environments — not a report on work done, but what the team uses daily. Below is the set we hand over and that then lives on without our participation.

  • Auto-repair rule configurations: which types of failures are closed automatically, which go to manual review, with full change history in the version control system.
  • Workflow diagrams: the path from a failed test to a confirmed edit — where automation triggers, where an engineer gets involved, where the rollback point is.
  • Edit process: who approves changes to reference snapshots and selectors, within what timeframes, what counts as a regression and blocks the run.
  • Access rules: roles and rights to change rules, start runs, and view logs — separately for developers, testers, and the direction lead.
  • Repair log: for each case — which test failed, what the cause was, what exactly was changed, who confirmed it.
  • Instructions for local launch and debugging: so a new engineer can reproduce the system's behavior locally rather than figuring it out by trial and error.

Documentation and team training

The documentation describes not only "how it is configured" but also "why it is so": which trade-offs were chosen and under what conditions a rule should be reconsidered.

A separate section covers typical failures and what to do if auto-repair suggested an incorrect edit.

The handover takes two meetings: a walkthrough of the workflow on a live run and a joint revision of the process for your workflows. After that, the team runs the system itself — our engineers stay in touch for non-standard cases.

Case study: the share of manual test edits decreased severalfold

Project — a retail platform with a personal account and order checkout: several hundred UI check scenarios that are run on every code change. The checks covered exactly the paths where a failure is most expensive — payment, cart, access recovery.

Before work started, the customer's team spent more time investigating failures than developing new scenarios.

What the bottleneck was before the start

The checks were tied directly to page markup: changing a button class or block nesting broke dozens of scenarios, although the interface behavior did not change. In a typical run, 15–20% of checks failed, and almost all of them turned out to be false.

Engineers fixed selectors manually, and some scenarios were marked flaky and disabled — coverage shrank unnoticed because a disabled scenario makes no noise.

How the result was measured

Measurements were taken at equal intervals before and after: the share of runs completed without false failures, the share of checks fixed by hand, and the time from failure to a green run again.

Separately, they counted how many failures an engineer investigated manually per week — this figure shows the real load on the team, not an indirect one.

Auto-repair (self-healing tests) works like this: when markup changes, the system selects the current element by a combination of attributes — text, role, neighboring nodes, — and then confirms the choice by the element behaving as expected in the scenario.

An erroneous match does not pass the behavior check, so false "fixes" do not mask real defects.

Manual edits became several times fewer, run recovery dropped from hours to minutes, the share of stable runs increased, and previously disabled scenarios returned to the suite.

Auto-repair versus rerun: what's the difference

Direct answer: rerun treats environment instability, auto-repair treats changed interface.

These are different causes of failure, so the approaches do not replace but complement each other: one is responsible for repeatability of conditions, the other for stability of element descriptions. Comparing them as replacements for each other is incorrect.

Locator substitution relies not on one attribute: the system stores a set of element attributes — text, role, neighboring nodes, position in structure — and on failure selects the candidate with the highest match.

It is the set of attributes that distinguishes a meaningful repair from substituting the first similar element.

Option When it fits Limitations
Rerun Flaky failures: timeout exceeded, services unavailable Does not treat a changed interface, lengthens the run, masks the defect
Locator substitution Markup cosmetics, attribute renaming May lead to a similar element and confirm an incorrect result
Auto-repair with review Regular interface releases, shared steps Requires confirmation and change history

The limitations of the approach begin where the match is formal: the element fits by attributes but no longer checks the right thing, and the test goes green with a live defect.

Therefore, locator edits go through review and are stored in history, and for critical checks auto-repair is disabled.

Rerun is appropriate where the cause is external: service unavailability, a race during data load. The criterion is simple — if the failure repeats on unchanged code, we fix the element description; if the failure is flaky, we investigate the launch conditions.

Technical doubts: false positives and boundaries

A false positive is the main risk: self-repair substitutes the locator with the first one matching the markup, the run is green, and the check no longer checks anything. Such a result is more expensive than a failure — the defect goes further and surfaces for users.

Therefore, edits are divided by risk classes. Cosmetics — attribute renaming, markup shift, container change — are applied automatically.

Anything that changes the meaning of the check is only suggested with a diff and requires engineer confirmation: until then, the test is marked flaky rather than passed.

Each repair is recorded in the log — original locator, new one, cause, who approved. The share of auto-approved edits, repeat failures of the same test, and path coverage keep stability under observation.

Will the system start massively rewriting tests — won't we lose control?

If the share of auto-edits per run is exceeded, the system switches to suggestion mode and applies nothing itself. Mass rewriting is a sign that the interface changed, not the markup, and here the decision is up to the engineer.

How tied is the approach to our stack?

It works where there is access to markup and stable ways to find elements: web interfaces, mobile applications, service contracts.

On custom formats, canvas rendering, and dynamic identifiers without semantics, accuracy drops — such tests remain under manual maintenance, which we discuss before the start.

What about rolling back a harmful edit?

The change is versioned together with the test, returning to the previous locator is one operation. The history stores who approved the edit and why.

Let's discuss the task: what data is needed for estimation

Estimation of self-healing tests is not based on a description in chat: to name the scope of work and timelines, engineers need access to real artifacts — the test repository, run logs, and environment configuration. The more complete the input, the fewer assumptions in the plan.

  • automated test repository: structure, change history, way locators are defined;
  • logs of failed runs over several weeks — with the failure cause and environment name;
  • environment configuration: how environments are brought up and where test data comes from;
  • list of locators and steps that break most often, tied to business scenarios;
  • description of the current process: who and when fixes tests manually after interface changes;
  • access to systems and security requirements — what is allowed to change and what is read-only.

Then the order is: we review what has been collected and build a diagram of connections between test steps, interface elements, and code changes. The diagram shows which failures are removed automatically and which remain with the engineer.

Based on it, we prepare a task estimate, stage-by-stage scope of work, and a plan with stop points where the result can be checked before continuing.

Describe the task and attach what you already have — we will come back with an estimate and work plan.

AI Development Areas

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1393
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1368
  • B2B Advance company logo design
    B2B Advance company logo design
    815
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1139
  • AIDER company logo development
    AIDER company logo development
    1057
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1152