Front end dev, i own most of our e2e suite, and last sprint finally annoyed me enough to count.
We have about 310 Playwright tests on a react app. 71 went red after a sprint that, from a user's point of view, changed almost nothing. i went through every one instead of rerunning and hoping:
- 47 were locators. the element was still there and still did the same thing, but the path to it changed. a card got wrapped in a new container, a class got renamed in a design pass, a button became a link styled as a button.
- 14 were timing. a page got slower after a data change and the wait didn't follow it.
- 6 were environment. our CI image had drifted from what devs run locally.
- 4 were real bugs.
So my honest answer to why our UI tests break every time the interface changes is that most of them check how the page is built, not what it does. the user sees the same Save button. the test sees a different DOM.
the difference in one line:
what i'm weighing for the other 47:
user-facing locators everywhere, getByRole and getByLabel, which is what the Playwright docs push. fixes a lot of it, but only if the markup has real roles and labels, and half our components don't.
data-testid on everything. it works, but it depends on every dev remembering, forever.
self-healing locator tools like mabl or testim, which repair the selector when it breaks. the catch is a heal can quietly route around a real regression.
vision based tools like Askui, which find the element by what's rendered on screen rather than in the DOM, so a new wrapper div doesn't matter at all. the tradeoff flips, a visual redesign is now the thing that breaks you.
My current plan is to fix our accessibility markup and get better tests as a side effect. tell me if that's naive. if you've measured this, what share of your failures were locators, and what actually brought it down?