Is XPath actually forbidden in a page object, or only discouraged?
Asked 7,060 views2 answers
22votes
Reviewer left "never XPath" on my proposal. The locator strategy page says CSS or XPath as a last resort inside a page object with a heal context, which reads like "allowed but grudgingly".
The element in question is a legacy table cell with no role, no test id and no stable class, and the only thing that identifies it is its position relative to a label. Which is it?
Both, and the difference is worth understanding rather than arguing about.
The order of preference is role and accessible name, then label, placeholder and text, then test id, then CSS. XPath sits below all of it. What makes it worse than CSS here is not aesthetics: the heal context supports description, role, name, testId, label, placeholder, text, title, altText and css. There is no XPath field. So when your XPath stops matching, the healer can only try what you wrote in the context — and if you were able to write a decent context, you were able to write a better primary locator in the first place.
For your legacy cell, the position-relative-to-a-label problem has a direct answer:
ts
readonly total = this.heal.locator(
this.page.getByRole('row', { name: 'Order total' }).getByRole('cell').last(),
{ description: 'order total cell' },
);
If even that is impossible, use CSS, give it a real description, and open a ticket against the application. To find out how much of this you are carrying, run analyze_locators over the project through the MCP server, or point the reviewer agent at it — both report CSS-only locators and strict-mode risks.
Speaking as someone who wrote XPath for years: the //div[contains(@class, 'row')][3]//span chains were the first thing to break in every redesign we ever survived, and they broke silently, matching something plausible instead of nothing.
The reviewer is saving you a bad afternoon in about eight months.