🤖 UI Automation: Selenium & Playwright
UI Automation: Selenium & Playwright: Asking Claude to generate a locator from a pasted HTML snippet is like asking a locksmith to cut a key from a PHOTOGRAPH of a lock instead o
Asking Claude to generate a locator from a pasted HTML snippet is like asking a locksmith to cut a key from a PHOTOGRAPH of a lock instead of the lock itself — the mechanism is exact: a photograph (a static HTML snippet) shows the lock's shape at one instant, but if the actual lock (the live DOM) has a slightly different keyway the next time the page renders (a re-ordered class list, a dynamically generated id), the cut key (the generated locator) may not fit. Here is the question worth sitting with: if Claude produced a working XPath from your snippet, why does it break on the next deploy when nothing about the FEATURE changed? Because a fragile locator (a deep XPath position, a framework-generated class hash) encodes the DOM's accidental structure, not the developer's intent — and Claude, working only from a frozen HTML snapshot, has no way to know which attributes are STABLE (a QA-owned data-testid) versus INCIDENTAL (a CSS-module hash) unless you tell it to prefer the former. Java comparison: this is the same fragility class as hardcoding a reflection call to a private field by its exact declaration order — it happens to compile and run today, but the contract you're actually relying on was never a guarantee. The QA stake: a CI suite full of Claude-generated XPath locators that quietly break on every unrelated frontend refactor is slower to maintain than the manual locators it replaced — the fix is prompting Claude to prefer data-testid, not accepting whatever selector it invents first.
From HTML Snippet to a Locator That Survives a Refactor
Paste the actual HTML element (not a description of it), and explicitly instruct Claude to prefer a stable attribute (data-testid, aria-label, a role) over positional/structural selectors (nth-child, deep XPath). If no stable attribute exists in the pasted HTML, ask Claude to flag that gap explicitly rather than silently inventing a fragile fallback.
Reasoning: why generate a full Page Object Model skeleton instead of one-off locators? A POM centralizes exactly the fragility risk above into ONE file per page — if a locator breaks, you fix it in one place instead of hunting through every test that duplicated it inline. Claude is good at the MECHANICAL skeleton (class structure, constructor, method names mirroring user actions) once you give it the page's HTML and the actions you need — but the actual selector STRINGS inside it still need your review for stability, exactly like the previous point.
Page Object Model: Java Selenium vs TypeScript Playwright
Why Is By.cssSelector("[data-testid=...]") More Resilient Than Position/XPath?
By.cssSelector("[data-testid='login-email']") finds…
By.cssSelector("[data-testid='login-email']") finds the element by a data-testid ATTRIBUTE the developer added ON PURPOSE, not by its POSITION in the DOM — this attribute exists ONLY for tests, no CSS/JS logic DEPENDS on it.
A frontend refactor often changes POSITION…
A frontend refactor often changes the element's POSITION in the DOM tree (which div index it is) or its class names (a CSS-module hash) — but a contract like data-testid stays STABLE unless the team breaks it ON PURPOSE.
The constructor STORES the driver reference…
The constructor STORES the driver reference (private WebDriver driver), so every call to login() SEARCHES for elements through the SAME driver session — no new connection is OPENED.
The login(email, password) method…
The login(email, password) method TURNS 3 findElement + sendKeys/click calls into ONE readable operation — the test itself now SPEAKS in terms of "log in", not "which CSS selector".