How to stop AI-healed locators from silently piling up, using one test run, one log line and Teamwork Graph CLI
Self-healing test automation feels like magic the first time you see it. A locator breaks, an AI model looks at the page, suggests a new selector, and the test goes green anyway.

Turn Self-Healing Tests Into Jira Tasks Automatically with the Atlassian Teamwork Graph CLI
The catch is that a healed test is not a fixed test. The broken locator is still in your page object. Every run pays the cost of another AI call, and the day the model guesses wrong, you get a confusing failure that nobody remembers the history of.
In this post I show how I closed that loop: every successful heal becomes a Jira work item, created from the terminal with twg , Atlassian’s Teamwork Graph CLI. No browser tabs, no copy and paste.
- Teamwork Graph, now in your terminal
- GitHub - aiqualitylab/SeleniumSelfHealing.Reqnroll: Selenium Self-Healing Tests with AI
The setup
The project is a C# test suite built on Selenium WebDriver, Reqnroll (the SpecFlow successor) and NUnit. A small self-healing layer wraps FindElement. When an element is not found, it sends the page context to an LLM, gets back a candidate selector, tries it, and logs the result.
To demonstrate it, the Wikipedia page object deliberately uses a wrong ID:
// Pages/WikipediaPage.cs
private readonly By _searchBox = By.Id("searchBox"); // real ID is searchInput
Running the suite with detailed console output:
dotnet test --logger "console;verbosity=detailed"
produces this sequence:
Element not found with By.Id: searchBox
Attempting self-healing for: Wikipedia search box
Asking AI for help (attempt 1/3)...
AI suggested: #searchInput
Self-healing successful! New locator works: #searchInput
The test passes. That last line is the signal I care about, because it carries everything a developer needs to make the fix permanent: the element name, the original locator and the replacement the AI found.
Why Teamwork Graph CLI
twg is a command line interface to Atlassian’s Teamwork Graph and cloud products. For this workflow it gives me three things in one binary:
JQL search over Jira work items
Create, update and delete for work items
OAuth device login, so nothing secret lives in the script
It also prints JSON on request, which makes it easy to drive from a script or from an AI coding agent.
Installing and signing in
Install with the official script:
curl -fsSL https://teamwork-graph.atlassian.com/cli/install | bash
On first use twg asks you to accept the Atlassian Customer Agreement and Privacy Policy. Then log in against your site:
twg login --site your-site
You get a verification URL and a short code. Approve it in the browser and confirm the token works:
twg doctor
Two lessons from running this inside a locked-down cloud container:
Allow the right hosts. The installer needs teamwork-graph.atlassian.com. Sign-in needs auth.atlassian.com, and API calls go through api.atlassian.com and your *.atlassian.net site. If your network uses an allowlist, add all of them up front.
Answer the browser prompt. In a headless shell, twg login asks whether to open a browser. If nothing answers, it waits there and never polls for your approval. Reply "n", open the link yourself, and it completes normally.
Know your project key
My first search returned nothing, and the reason was simple. The Jira space is named “Self Healing”, but its key is KAN. JQL wants the key. Check it with:
twg jira space get KAN
Step 1: search before you create
Duplicate tickets are how a good automation turns into noise. For each heal, search the project for anything that mentions the old locator, the new one, or the element:
twg jira workitem query --jql 'project = KAN AND (text ~ "searchBox" OR text ~ "searchInput" OR text ~ "search box" OR summary ~ "healed locator")'
An empty issues array means it is safe to create a new item.
Step 2: create the task
Keep the description in a small Markdown file so it reads well in Jira:
- **Element:** Wikipedia search box
- **Original locator:** `By.Id("searchBox")`
- **AI-suggested locator:** `#searchInput`
- **File:** `Pages/WikipediaPage.cs`
Update the locator so the test no longer depends on AI healing.
Then create the work item:
twg jira workitem create \
--space KAN \
--type Task \
--summary "Fix healed locator: Wikipedia search box" \
--description "$(cat desc.md)" \
--description-format markdown
twg returns the new key, and twg jira workitem get lets you check that the description landed as intended.
Step 3 (optional): replace instead of skip
Sometimes you want a fresh ticket rather than keeping an old one. twg can delete, provided your account has the Delete Issues permission:
twg jira workitem delete KAN-1
Deletion in Jira cannot be undone, so I only do this when the policy is explicit.
Putting it together
The whole loop is four moves:
Run the suite with detailed logging.
Collect every Self-healing successful line along with the original locator and AI suggestion logged just before it.
Search Jira with twg for a matching item.
Create a Task with twg when nothing matches.
Wrapped in a short script, this runs at the end of every CI job. Healed locators stop being invisible. They show up on the board, someone owns them, and the page object gets fixed for real.
Takeaways
A self-healed test is a warning, not a win. Track it.
Log the original locator, the suggested one and the element name together, so the ticket writes itself.
Search before you create, and use the project key, not the display name.
twg turns Jira into something your test pipeline can talk to directly, with plain commands and JSON output.
Self-healing buys you time. Feeding every heal into Jira makes sure you spend that time fixing the root cause.
Top comments (0)