I'm building browser automation with Playwright and Stagehand, but selectors keep breaking after page re-renders or application releases introduce new build hashes and dynamic element IDs. For sites I control, I can use semantic locators or add test IDs, but some of my targets are third-party portals and legacy applications where the DOM is generated and I can't change the markup. How do you handle this in practice? Do you rely mainly on roles, labels, and visible text, build a selector-resilience layer, use specialized tooling, or simply accept some ongoing maintenance? I'd especially appreciate advice and real-world experience with applications that have few stable attributes.
3 Answers
The best default is to locate elements the way a user or assistive technology would: use roles, accessible names, labels, and stable visible text. These tend to survive build changes much better than CSS paths, generated IDs, or deeply nested selectors. If you control the application, adding dedicated test IDs can be a useful fallback, but they should usually come after semantic locators rather than replacing them.
AI-based selector repair can look convenient, but it shouldn’t be the foundation of a dependable automation suite. Automatically guessing a replacement element can hide real UI regressions and produce false positives. Explicit semantic locators, clear fallback rules, logging, and a small amount of targeted maintenance are generally safer. If a screen has no meaningful semantics at all, some maintenance cost is unavoidable unless the vendor improves the markup.
For third-party or poorly structured applications, there usually isn’t a magic selector strategy. Start with the most stable structure available, such as a nearby heading, table column, dialog title, or recognizable text, and keep the locator as short and intentional as possible. Avoid relying on generated IDs and brittle full CSS or XPath chains. It also helps to isolate selectors behind page-object or helper functions so a UI change requires updating one place instead of the whole test suite.

That makes sense for applications we own. The difficult cases are vendor portals and legacy systems where there are no test IDs, and sometimes the controls don’t expose useful roles or labels. In those cases, I’m wondering how much selector maintenance people consider normal.