The Page Object Model helps keep test code readable by separating page interactions from test intent.

In This Repository

The active page object classes live under page-objects/.

The pattern used here generally includes:

  • a page class per area or page

  • locators and page actions kept together

  • page-level assertions such as assertOnPage()

  • reuse through shared base behavior where it helps

Example

import { expect, Page } from '@playwright/test';

export class LoginPage {
  constructor(private page: Page) {}

  async goto(): Promise<void> {
    await this.page.goto('/login');
  }

  async login(username: string, password: string): Promise<void> {
    await this.page.getByLabel('UserName').fill(username);
    await this.page.getByLabel('Password').fill(password);
    await this.page.getByRole('button', { name: 'Login' }).click();
  }

  async assertOnPage(): Promise<void> {
    await expect(this.page.getByRole('heading', { name: 'Login' })).toBeVisible();
  }
}

Why It Helps

  • keeps tests focused on behavior rather than selector details

  • reduces duplication across specs

  • makes UI updates easier to absorb in one place