Advanced Page Objects and Screen Models

As your Playwright suite grows, ad hoc locators and inline flows quickly become hard to maintain. Advanced page objects and screen models give you a structured way to model the UI so tests stay readable and resilient to changes.

Designing Page Objects and Screen Models

A page object represents a logical screen or feature in your app and exposes high-level actions and assertions. Screen models are a variant that focus on states and transitions rather than strict URL pages.

// models/profile-page.ts
import { Page, expect } from '@playwright/test';

export class ProfilePage {
  constructor(private readonly page: Page) {}

  async goto() {
    await this.page.goto('https://demo.myshop.com/profile');
  }

  async updateDisplayName(name: string) {
    await this.page.getByRole('textbox', { name: 'Display name' }).fill(name);
    await this.page.getByRole('button', { name: 'Save changes' }).click();
  }

  async expectUpdateSuccess() {
    await expect(this.page.getByText('Profile updated')).toBeVisible();
  }
}
// profile-page.spec.ts
import { test } from '@playwright/test';
import { ProfilePage } from './models/profile-page';

test('user can update profile name', async ({ page }) => {
  const profile = new ProfilePage(page);

  await profile.goto();
  await profile.updateDisplayName('New Name');
  await profile.expectUpdateSuccess();
});
Note: Good page objects avoid exposing raw locators to tests; instead they provide intent-revealing methods for common actions and expectations.
Tip: Keep page objects thin and focused; cross-page flows belong in higher-level helpers or test code, not inside a single object.
Warning: Very large page objects that model entire applications become hard to understand and defeat the purpose of abstraction.

Screen models can go further by modelling states like β€œcart-empty”, β€œcart-has-items” or β€œcheckout-complete” and providing transitions between them, which aligns well with complex business flows.

Common Mistakes

Mistake 1 β€” Treating page objects as simple locator bags

This leaks implementation details.

❌ Wrong: Exposing every locator and having tests call low-level methods directly.

βœ… Correct: Expose meaningful actions like updateDisplayName or addItemToCart.

Mistake 2 β€” Over-abstracting before patterns stabilise

This adds unnecessary complexity.

❌ Wrong: Designing a deep hierarchy of base pages before you have real tests.

βœ… Correct: Start simple, then refactor shared behaviour into base classes or mixins as duplication appears.

🧠 Test Yourself

What makes a good Playwright page object or screen model?