Element Not Found Again? How to Test When Selectors and Locators Fail
Element not found?Why selectors and locators break (dynamic IDs, shadow DOM, iframes, canvas) and how to test without a single locator to maintain.
"Element not found" means your test looked for an element with a locator and nothing matched in time.The fix is rarely a better locator: it is a test that checks what the user sees.
Every QA engineer knows the morning: twenty red tests, and not one real bug.A developer renamed a class, the design team moved a banner, a framework update changed the ids.This article explains why locators break, how to fix the error when it comes, where the usual fixes stop, and how to test without a selector to maintain.
What does "element not found" mean?
Definition
An "element not found" error means the test asked for an element with a locator and nothing on the page matched it before the timeout.
- A locator, also called a selector, is the address the test uses for the element: an id, a CSS selector, an XPath, a role and a name, a text.
- Selenium raises NoSuchElementException, Playwright ends the action with a timeout, and every other framework has its own name for it.
The message is always the same in the end: the test lost the element, whether or not the user did.
Selenium's own troubleshooting page gives three likely causes: you are looking in the wrong place, you are looking at the wrong time, or the locator has changed since you wrote the code.Only the last one is about the locator itself, and it is the one that grows with every release.
#save-8f3a2c
A new build generates another id
.btn-primary
A redesign renames the class
text=Save
The French version says Enregistrer
//div[3]/form/button[2]
A banner is added above the form
On the screen
SaveUnchanged for the user
Why do selectors and locators break?
A locator is a guess about how the application is built.Anything that changes the build without changing what the user sees can break it.
| What changed | Which locators break | Did the user notice? |
|---|---|---|
| Generated ids and class names | An id or a class written by the framework, different on every build or page load | No |
| A redesign or a refactor | CSS chains and XPaths that follow the page's structure | Often not |
| An A/B test | Any locator of the variant your test did not expect | Only the users in that variant |
| A translation | Locators by visible text or accessible name | No, if the translation is right |
| Shadow DOM and iframes | Locators that cannot cross into the component or the frame | No |
| A virtualised list | Locators for a row that is not drawn until it is scrolled into view | No |
| A canvas, a game or an app with no accessibility tree | Every locator: there is nothing inside to point at | No |
Dynamic ids and generated class names
Many frameworks write their own ids and class names, such as save-8f3a2c or css-1x7hq.They are unique, which makes them look like perfect locators, and they change with the next build.A test recorded against them passes today and fails after the next deployment, on a page nobody touched.
Redesigns, refactors and A/B tests
A CSS selector such as .form > div:nth-child(3) button or an XPath such as //div[3]/form/button[2] describes a path through the page.Wrap the form in a new container, add a banner above it, or reorder two fields, and the path leads somewhere else.An A/B test does the same on purpose: half the visitors get a page your locators were not written for.
Playwright's documentation says it plainly: XPath and CSS selectors can be tied to the DOM structure, and they can break when it changes.
Localization and text-based locators
Locators by text, label or accessible name survive a redesign, which is why they are recommended.They do not survive a translation.A button found by the name Save is not found when the French version says Enregistrer, so a localized product needs one locator per language, or a test id.
Shadow DOM and iframes
An iframe is a page inside the page, and a web component keeps its inner elements in a shadow root.Selenium is only aware of the elements in the top-level document, so a coded test must be told to step into the frame first, or it reports that the element does not exist.Some locators, such as XPath, cannot reach inside a component at all.
Virtualised lists and grids
A table of ten thousand rows is fast because it does not draw them all.AG Grid, a widely used data grid, explains that it only renders what you see on the screen, plus a small buffer of rows above and below.Row 500 is not in the page until someone scrolls to it, so a locator for it finds nothing, while a person would simply scroll.
How to fix an "element not found" error
In Selenium, Playwright or Cypress, fixing the error is your work, and it comes back after every release.In GUI Test Studio there is no locator to fix.
| What went wrong | In a coded framework | In GUI Test Studio |
|---|---|---|
| The element appears late | You write a wait for the right condition | Every check waits up to its timeout by itself |
| The element sits in a frame or a shadow root | You write the step into the frame or the component | The element is found where it is drawn on the screen |
| A redesign changed the ids or the structure | You rewrite the locator, often in many tests | Nothing to rewrite: another way, or its picture, finds it |
| The element changed on purpose | You edit the test code | One click in the report accepts the new look |
When a GUI Test Studio test does stop on an element, these five steps settle it, with nothing to code.
- 1
Open the run's Confidence Report
The report opens after every run, on the first failure.It shows the expected picture beside the screen at the moment the check gave up, so you see whether the element was missing, covered or somewhere else.
- 2
Check where the run started
A test starts from the screen its recording started from.If the app was on another page or held other data, put it back the way it was and run the test again.
- 3
Widen the search area if the element moved far
When nothing is found in a check's search area, the search already widens to the whole screen by itself.If the element now stands somewhere new for good, click Widen the Search Scope in the report and set the new area in GUI Test Studio.
- 4
Accept a change made on purpose
If the element looks different because the design changed, click Accept actual as expected in the Confidence Report and save.The test is up to date, with no code to edit.
- 5
Report the bug if it really disappeared
If the element is gone, the test did its job.Click Bug Report to file it as a PDF or a Jira issue, with the pictures attached.
CSS, XPath, role or test id: every locator has a weak spot
Teams that write coded tests choose a locator for every element they touch.Each kind fails in its own way.
| Locator | Example | It breaks when | It survives |
|---|---|---|---|
| Generated id or class | #save-8f3a2c | The next build | Almost nothing |
| CSS selector | .form button.primary | Classes or structure change | A new text or translation |
| XPath | //div[3]/form/button[2] | Anything is added above or around it | A new class |
| Role and accessible name | role=button, name=Save | The label changes or is translated | Redesigns and refactors |
| Test id | data-testid=save-order | A developer removes or renames it | Redesigns, translations, refactors |
Each strategy moves the risk rather than removing it.
- A role and a name depend on the words, which change with every translation and every copy edit.
- A test id depends on a habit: every developer must add it, keep it and never reuse it, in every component, for as long as the product lives.
- CSS and XPath depend on the structure, which is exactly what refactors change.
XPath versus CSS selector is the most asked question, and it matters less than it seems.CSS is shorter and easier to read; XPath can walk up the page and match text.Both describe how the page is built, so both break the same way.
In GUI Test Studio nobody chooses a locator.A recorded test keeps several ways to each element by itself, as the next sections show.
Does self-healing test automation fix broken locators?
Self-healing tools keep extra details about each element while a test passes.When the main locator stops matching, they look for the element with those details and continue.
Self-healing is useful, with three limits worth knowing.
It still starts from a locator, so it needs an element in the page to heal to.
It turns a change into a pass, so every heal needs a person to review it, or a real change hides behind it.
It cannot help where there is no element at all: a canvas, a game, a remote screen.
Where every locator stops: canvas, games and apps with no accessibility tree
Every strategy above assumes the application describes its elements.Many do not, and there is no locator to write, good or bad.
| Application | What a locator can reach |
|---|---|
| A canvas, a chart, a map, a WebGL scene | One element that holds a picture |
| A game | One window: the game draws its menus itself |
| Flutter on the web | Nothing until the app turns its accessibility on: Flutter draws its interface on a canvas, and its accessibility is opt-in on the web |
| Qt, Java Swing, Delphi and other custom-drawn desktop apps | Little or nothing, depending on how each control is drawn |
| Citrix, Remote Desktop and virtual machines | One window of pixels on your computer |
For Windows desktop apps, WinAppDriver alternatives for apps with no accessibility tree lists which programs describe themselves and which do not.
If your test can only see what the application describes, an application that describes nothing cannot be tested.The user still sees every button.
Test automation without selectors to maintain
GUI Test Studio, which automates end-to-end tests on Windows, takes a different route: nobody writes or maintains a selector.You record the test by doing the workflow yourself, or describe it in a prompt, and every check is about what the user sees.
| The check | What it checks |
|---|---|
| Visual Assert | An element is on the screen and looks as expected: its picture, found and compared |
| Text Assert | A text is on the screen, read where it should be |
| Dynamic Text Assert | A value has the right shape, such as a date, an amount or an order number, whatever its value |
| Layout Assert | Elements stand where they should in relation to each other |
To find each element, the GTS Engine + AI uses two ways.It asks the application first: the accessibility information a Windows app gives about its controls, or a web page's own elements.When the application says nothing, it finds the element by sight, on the screen.How GUI Test Studio finds elements on the screen explains both ways in detail.
On a web page: several ways to one element
For a web test, GUI Test Studio keeps several ways to each element it acts on, ranked: its test id, its id, its role and name, its label, its placeholder, its text, and its place in the page last.An id that looks generated by a framework is moved near the end of the list, after everything a person can read.
The ways to the Save button, tried in order
- 1Its test iddata-testid="save"Removed in a refactor
- 2Its role and namerole=button · name=SaveFound
- 3Its textSaveNot needed
- 4Its place in the pageform > button:nth-of-type(2)Not needed
So a removed test id or a renamed class does not stop the test: the next way still finds the element.The same ways reach elements inside a shadow root, and they let a test generated for a phone open the menu that hides a link there.
That last part is what lets one recorded web test run in Chrome, Edge, Firefox and on emulated phones, as cross-browser testing from one recording shows.
In a desktop app: the control first, then the screen
In a Windows app, a check made on a button keeps what the app said about that button: its name, its kind, where it stood.At every run, the engine asks the live app for it first, and looks for its picture inside the box the app gives.Among several identical buttons, it takes the one nearest to where the recorded one stood.
A text check asks the app what the element says before it reads the words on the screen, so a word that is hard to read on the screen is still checked against what the app really says.
Everywhere else: by sight
A game, a canvas, a Citrix session or a program with no accessibility tree is tested by sight, with nothing added to the application.The check looks for the element's picture in its search area, and a text check reads the words on the screen.
A dashboard draws its sales chart on a canvas, so no locator can reach a bar or a legend.You record a click on the March bar and add a Visual Assert of the legend.The click is aimed through the bar's picture, and the legend is checked as the user sees it.
What happens when the element moves or changes
A test that does not depend on one locator still has to cope with change.Here is what GUI Test Studio does at each step.
Ask
The application says where the element is
Look
Or its picture is found in its search area
Widen
Nothing there: the whole screen
Report
Where it was found, and why
Each step covers a different kind of change.
- A window that moved, a layout that shifted or a list that scrolled: the application says where the element is now, or its picture is found there.
- An element that left its search area: when nothing is found there, the search widens to the whole screen, and the Confidence Report says the element was found outside its area, with a link to widen it.
- A word the text recognition reads badly: a text check asks the application what the element says.
- A web element whose first locator broke: the next way finds it, and the run notes which way changed.
Clicks follow the element too: each click is aimed through the check in front of it, so when the button moves, the click moves with it.See visual checks and text checks for how each check is set.
What still needs you
No approach makes every change free.These are the cases where a person decides.
| Situation | What to do |
|---|---|
| An element's look changed on purpose | The check fails with the expected and the actual picture side by side.Click Accept actual as expected in the Confidence Report and save. |
| The screen size or scaling differs from the recording | A check by sight compares pictures, so run on the same screen size and scaling, or keep a baseline profile for each one. |
| The app does not start where the recording started | Put the application back in the state the recording started from: the same page, the same data, the same open windows. |
| An A/B test serves another variant | Pin the variant in your test environment, or keep a baseline profile for each variant. |
| The element really disappeared | That is a bug.The test fails, and the report shows what was expected where. |
Accept a new look walks through the one-click update, and flaky tests and false positives explains how a check tells harmless noise from a real change.
For the visual bugs a locator-based check passes without seeing, read visual bugs your automated tests miss.
Key takeaways
- 1"Element not found" is usually a test problem, not a bug: the locator, the timing or the context is wrong more often than the application.
- 2Locators break for ordinary reasons: generated ids, redesigns, A/B tests, translations, shadow DOM, iframes and virtualised lists.
- 3Every strategy moves the risk: CSS and XPath depend on the structure, roles and names on the words, test ids on a team habit, self-healing on a review.
- 4Some apps give a locator nothing: canvases, games, Citrix sessions and apps with no accessibility tree can only be tested by sight.
- 5GUI Test Studio has no selectors or locators to maintain: it asks the application first, finds the element by sight when the application does not say, and checks what the user sees.
Questions
What does "element not found" mean in test automation?
It means the test asked for an element with a locator, such as an id, a CSS selector or an XPath, and nothing on the page matched it in time.In Selenium it appears as NoSuchElementException, in Playwright as a timeout.The element may be missing, but more often the locator, the timing or the context is wrong.
Why does my test find the element locally but not in CI?
Usually because the run is different, not the code.A slower build agent shows the element later than your laptop, a smaller screen hides it behind a menu, other test data changes its text, or an A/B test serves another variant.Check the screenshot or video of the failed run before you change the locator.
Is XPath or a CSS selector better?
Neither is safe on its own.Both describe how the page is built, so both break when its structure changes, as Playwright's documentation warns.A role and a name or a test id last longer, but each one is still written and kept up to date by hand.In GUI Test Studio nobody writes either: the test keeps its own ways to each element.
How do I handle dynamic IDs in Selenium or Playwright?
Do not build a test on them: an id that changes on every build or every page load cannot find the same element twice.In a coded test that means writing and keeping another locator by hand.In GUI Test Studio there is nothing to write: a web test moves an id that looks generated to the end of its list of ways to the element, after everything a person can read.
Does self-healing test automation work?
It helps when an attribute changes and the element is still there.It cannot recover an element that is truly gone, and it still starts from a locator someone wrote and has to keep.Review every heal, or it may hide a real change.
How do you test an app that has no accessibility tree?
Test it by sight, on the screen.Games, canvases, charts, Citrix and Remote Desktop sessions and many custom-drawn programs expose nothing a locator can reach.GUI Test Studio finds their elements by their picture and checks the text read on the screen, with no change to the application.
Can I automate end-to-end tests without selectors or locators?
Yes.In GUI Test Studio you record a test or describe it in a prompt, and there are no selectors or locators to maintain.Each check is a picture, a text, a value's shape or an arrangement on the screen, and the GTS Engine + AI finds every element by asking the application first and by sight when it does not say.
What happens when a button changes on purpose?
The check fails and shows the expected and the actual picture side by side.If the change is wanted, click Accept actual as expected in the Confidence Report and save: the test is up to date, with no code to edit.
Selenium, Playwright, Cypress, AG Grid, Flutter, Qt, Java, Delphi, Citrix, Chrome, Edge, Firefox and Windows are trademarks of their respective owners.
Keep reading
All articles
Test reliability
Flaky Tests: Causes, Costs and How to Stop False Positives
12 min read

Visual testing
Pixel-Perfect Screenshot Testing: Why It Fails, and What Catches Real Visual Bugs
12 min read

Test automation
Manual Testing vs Automated Testing: Why Manual Testing Falls Short for End-to-End Tests
15 min read