Why framework structure matters
As your test suites grow, structure decides everything.
Either your tests stay:
- Fast
- Readable
- Easy to evolve
Or they turn into maintenance debt.
My go-to pattern: POM + PageManager
Clean dependency flow. Zero duplicate instantiation.
Visual architecture overview

Architecture breakdown
The framework follows a simple, predictable flow:
Tests → PageManager → Pages → HelperBase
Role of each layer
Tests
- Describe intent and user flow
- No selector noise
- No object creation
PageManager (central instance builder)
- Creates and exposes all page objects
- Ensures single instantiation per test
- Removes repeated imports across specs
Pages
- Encapsulate UI actions and business flows
- Avoid heavy assertions
- Expose meaningful actions and locators
HelperBase
- Smart waits
- Resilient interactions
- Shared utilities and selectors
Why PageManager matters
Without PageManager:
- Each spec imports 3–5 page objects
- Pages get instantiated repeatedly
- Tests become noisy and fragile
With PageManager:
- Everything stays centralized
- Specs stay clean and DRY
- Adding a new page changes only one file
Example usage
// spec
const pm = new PageManager(page);
await pm.homePage.open();
await pm.productPage.addItemToCart("MacBook");
await pm.checkoutPage.completeOrder("UPI");
Add a new page?
Only PageManager changes — tests remain untouched.
Where should assertions live?
Tests own the truth.
- Keep assertions in specs (
expectin Playwright Test) - Keep pages assertion-light
- Pages may expose small guards like
isLoaded()returning booleans
Assertion example
// ✅ good: spec owns validation
await pm.checkoutPage.completeOrder("UPI");
await expect(pm.checkoutPage.successToast())
.toHaveText("Order placed");
// page object returns data, not opinions
successToast() {
return this.page.getByRole("status");
}
Benefits seen in real projects
- Cleaner PRs and faster reviews
- Easier onboarding for new engineers
- Fewer flaky tests via centralized waits
- Scales cleanly with CI parallelism