Stop Babysitting Your Tests: Self-Healing Selenium with Local LLMs
How I built a Java framework that automatically fixes broken locators at runtime and without sending your code to the cloud
Stop Babysitting Your Tests: Self-Healing Selenium with Local LLMs
How I built a Java framework that automatically fixes broken locators at runtime and without sending your code to the cloud
There’s a particular kind of frustration that every QA engineer knows intimately: you come in Monday morning, run your test suite, and half of it is red. Not because the application broke. Because a developer renamed a button ID. Or shuffled some XPaths. Or swapped a CSS class.
Your tests aren’t testing anything wrong. They just can’t find the thing anymore.
This is the locator fragility problem, and it quietly eats engineering hours every week across teams worldwide. The traditional answers which has better locator strategies, more resilient selectors, regular maintenance sprints and all work to some degree. But they’re all reactive. You still lose time.
What if your tests could just… fix themselves?
That’s the idea behind **ollama-autoheal** a Java-based self-healing Selenium framework that uses a local LLM (via Ollama) to automatically repair broken locators at runtime, right in the middle of your test run.
The Core Problem with Selenium Locators
Selenium tests live and die by their locators. A locator is how your test says “find this element on the page.” The trouble is that locators are tightly coupled to implementation details that developers change all the time:
By.id("username")breaks when someone renames the fieldBy.xpath("//div[@class='btn-primary']")breaks when CSS is refactoredBy.cssSelector(".login-form > input:nth-child(2)")breaks when the layout changes
Every UI change is a potential test failure. And since UI changes happen constantly in fast-moving products, test maintenance becomes a perpetual tax on your team’s velocity.
The Self-Healing Idea
The self-healing approach asks: when a locator fails, what does a human test engineer actually do to fix it?
- They open the browser
- They look at the current page source
- They think about what the element is and its purpose, its label, its context
- They try a few alternative selectors until one works
This is exactly the kind of fuzzy, context-aware reasoning that LLMs are good at. The insight behind ollama-autoheal is to intercept a NoSuchElementException, hand the current page DOM and a plain-English description of the element to a local LLM, and let it suggest new locators to try.
Why Local? Why Ollama?
Most self-healing frameworks that use AI are cloud-based (and often expensive). ollama-autoheal takes a different approach: it runs the LLM entirely on your machine using Ollama, an open-source tool for running language models locally.
This has significant advantages:
Privacy: Your page source and DOM structure never leave your machine. For teams working on internal tools, banking software, or healthcare applications, this is non-negotiable.
Cost: Zero API costs. Once you pull the model, every healing event is free.
Latency: Local inference is fast, especially with a small model. There’s no network round-trip to a cloud endpoint.
Offline operation: Your CI/CD pipeline doesn’t need internet access for test healing to work.
The default model is qwen2.5-coder:1.5b a small, fast, code-specialized model that's very good at understanding HTML structure and generating selector syntax.
How It Works: The Healing Pipeline
Here’s what happens, step by step, when a locator fails:
Test Runs → NoSuchElementException → [Self-Healing kicks in]
↓
1. Capture current URL + first 3000 chars of page source
↓
2. Build a structured prompt with element description + page context
↓
3. Send to local Ollama API (http://localhost:11434/api/chat)
↓
4. LLM responds with alternative locators + confidence scores
↓
5. Try each suggestion against the live DOM
↓
6. First one that works? Apply it. Test continues.
↓
7. No match found? Fail as normal.

The key insight in step 2 is the element description a human-readable string you provide when writing your page object, like "Username input field on the login page". This is what allows the LLM to understand what it's looking for semantically, not just syntactically. This is the bridge between natural language and DOM structure.
Usage: Extending SelfHealingBasePage
Integration into an existing Page Object Model is straightforward. Instead of extending a plain base page, you extend SelfHealingBasePage:
public class LoginPage extends SelfHealingBasePage {
private By usernameField = By.id("username");
private By loginButton = By.xpath("//button[@type='submit']");
public LoginPage(WebDriver driver) {
super(driver);
}
public void login(String username, String password) {
// If By.id("username") fails, the framework heals it automatically
sendKeysWithHealing(
usernameField,
"Username input field on login page",
username
);
// Same for the button
clickWithHealing(
loginButton,
"Submit/Login button on login page"
);
}
}
Notice the second parameter in sendKeysWithHealing and clickWithHealingand that's your human-readable element description. Write it like you'd describe the element to a colleague. The more descriptive, the better the LLM can reason about it.
Architecture Deep Dive
The project is organized around a few clean abstractions:
**com.selfhealing.agent** The brain. This is where the OllamaClient lives (handles all communication with the local LLM API) and where the SelfHealingAgent validates suggested locators against the live DOM.
**com.selfhealing.agent.base**The bridge. SelfHealingBasePage is what your page objects extend. It wraps standard Selenium actions (click, sendKeys, findElement) with healing-aware alternatives.
**com.selfhealing.agent.model** The data layer. Typed models for LLM responses and locator suggestions, including confidence scores from the model.
**com.selfhealing.pages** Example page objects showing the pattern in practice.
The validation step (in SelfHealingAgent) is critical to the framework's reliability. LLMs can confidently suggest locators that don't actually exist on the page. By actually trying each suggestion against the live DOM before applying it, the framework filters out hallucinations automatically. Only validated, working locators ever get used.
Prerequisites and Setup
Getting started requires:
- Java 17+
- Maven 3.6+
- Ollama running locally on port
11434
Pull the default model:
ollama pull qwen2.5-coder:1.5b
Clone and install the framework:
git clone https://github.com/chhatbarjignesh/ollama-autoheal.git
cd ollama-autoheal
mvn install
Run the included integration tests:
mvn test -Dtest=SelfHealingAgentTest

Configuration lives in OllamaClient.java. The OLLAMA_URL and MODEL constants can be changed if you want to use a different Ollama model (like llama3, mistral, or a larger coder model for more complex pages). You can also toggle healing per-page-object with setSelfHealingEnabled(true/false).
Limitations and Honest Trade-offs
Self-healing is powerful, but it’s not magic. A few things to keep in mind:
It’s a recovery mechanism, not a replacement for good locators. The best outcome is that your tests never need healing. Write locators using stable attributes (data-testid, aria-label) where possible. Use healing as a safety net, not a crutch.
Healing adds latency. When a locator fails and healing kicks in, there’s a round-trip to the local LLM. Even with a small model, this adds a few seconds per healing event. Frequent healing events will slow your suite down.
The LLM can be wrong. The validation step catches most issues, but if a page has multiple elements that match a suggested locator, the wrong one might be selected. Good element descriptions reduce this risk significantly.
3000 characters of page source isn’t the whole page. For large, complex pages, the LLM only sees a portion of the DOM. This is a deliberate trade-off for token efficiency and speed, but it means elements buried deep in large pages may be harder to heal reliably.
The Bigger Picture
ollama-autoheal is an early but compelling example of a broader trend: using LLMs not as chatbots, but as embedded reasoning engines inside developer tools.
The locator-healing use case is elegant because the problem is well-scoped. The LLM gets a clear context (page DOM), a clear goal (find this element), and its output is immediately verifiable (does the suggested selector work?). That verifiability is what makes it trustworthy for production use and you’re not blindly applying AI suggestions, you’re using AI to generate candidates and then using deterministic code to validate them.
This hybrid approach AI for generation, code for validation and is a pattern worth paying attention to. It gives you the benefit of LLM reasoning while keeping a firm, testable safety net in place.
Get Involved
The project is open source under the MIT license and actively welcomes contributions. Whether you want to add support for additional locator strategies, improve the prompt engineering for better healing accuracy, or add configuration options and pull requests are welcome.
GitHub: https://github.com/chhatbarjignesh/ollama-autoheal
If you’ve been fighting the locator fragility problem in your test suite, give it a try. Your Monday mornings might start looking a lot greener.
메타데이터
- post_id
- b2f943eec7c4
- slug
- stop-babysitting-your-tests-self-healing-selenium-with-local-llms-b2f943eec7c4
- url
- https://medium.com/@chhatbarjignesh/stop-babysitting-your-tests-self-healing-selenium-with-local-llms-b2f943eec7c4
- canonical_url
- https://medium.com/@chhatbarjignesh/stop-babysitting-your-tests-self-healing-selenium-with-local-llms-b2f943eec7c4
- author_url
- https://medium.com/@chhatbarjignesh
- status
- ok
- fetched_at
- 2026-08-26 14:43:54