Playwright Page Objects
Modern POM architecture using Playwright's fixtures pattern, composition over inheritance, and role-based locators.
When to Apply
- Setting up E2E test architecture from scratch
- Creating new page objects or component helpers
- Implementing test fixtures for dependency injection
- Refactoring existing page objects for maintainability
- Writing reusable component-level test abstractions
Core Principles
- Fixtures over PageManager — On-demand instantiation, automatic setup/teardown, native TypeScript inference
- Composition over inheritance — Compose from focused components, avoid deep class hierarchies
- Role-based selectors first —
getByRole() > getByLabel() > getByText() > getByTestId()
- Tests own assertions — Page objects expose state via getters, tests make assertions
- Separate pages by workflow — ProductListPage ≠ ProductDetailsPage (different user interactions)
- Readonly locators — All page object locator properties should be
readonly
- Fluent interfaces — Methods return
this for chaining; navigation methods return target page object
- Private internals — Mark implementation details (spinners, retry logic, helpers) as
private
- Wait for stability — Use
waitForPageLoad(), waitForResponse() before assertions
- High-level actions — Create AppActions class for complex multi-page user flows
Quick Reference
Locator Priority
1. page.getByRole('button', { name: 'Add to Cart' }) // Preferred
2. page.getByLabel('Email') // Form inputs
3. page.getByText('Welcome back') // Non-interactive
4. page.getByPlaceholder('Search...') // When no label
5. page.getByTestId('cart-item-count') // Escape hatch
Anti-Patterns Summary
| Anti-Pattern | Problem | Solution |
|---|
| Assertions in POMs | Hidden test logic | Expose state, assert in tests |
| Fat page objects | 50+ locators unmaintainable | Split into components |
| Deep inheritance | Rigid, hard to modify | Use composition |
| CSS selectors | Break on styling changes | Use role-based selectors |
| Wrapping Playwright | Unnecessary abstraction | Use Playwright directly |
| All members public | Exposes internals | Mark internal members private |
References