Page Object Model Locator Strategy — Patterns That Scale
How senior SDETs organise locators inside Page Objects: naming conventions, base page classes, dynamic locators, and the mistakes that make POM unmaintainable.

2026-07-17 · By Avinash K
The Page Object Model (POM) works — until your POM classes turn into 2,000-line dumpsters that nobody wants to touch. These are the patterns that keep POMs healthy at scale.
Rule 1 — One class per meaningful UI area
Don't create one giant HomePage. Split by user intent: LoginPage, CheckoutPage, OrderSummary. A good rule: if two features would be released independently, they deserve separate POM classes.
Rule 2 — Locators as readonly fields, not methods
export class LoginPage {
constructor(private page: Page) {}
readonly email = this.page.getByRole('textbox', { name: 'Email' });
readonly password = this.page.getByRole('textbox', { name: 'Password' });
readonly submit = this.page.getByRole('button', { name: 'Sign in' });
}Fields are declarative and easy to scan. Methods for high-level actions only.
Rule 3 — Dynamic locators via functions
row(customerName: string) {
return this.page.getByRole('row').filter({ hasText: customerName });
}Use functions when the locator needs runtime data. Never string-concatenate raw XPath.
Rule 4 — Base page for cross-cutting concerns
Put navbar, footer, toast, and modal helpers in a BasePage. Every page extends it. Avoids the classic bug where three different POMs each define their own closeToast().
Rule 5 — No assertions inside Page Objects
POM methods return data or navigate; assertions live in tests. This lets one POM serve happy-path and error-path tests without duplicated logic.
Generate POM classes automatically
Paste any HTML block into the XPath & CSS Selector Generator and click "Export Page Object". It produces a fully typed class for Playwright TypeScript, Selenium Java, or Cypress JavaScript with sensible field names.