← Back to Tutorials

14. Page Object Pattern & Data Parameterization

Page Object Model

// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';

export class LoginPage {
  readonly page: Page;
  readonly usernameInput: Locator;
  readonly passwordInput: Locator;
  readonly loginButton: Locator;

  constructor(page: Page) {
    this.page = page;
    this.usernameInput = page.locator('#user-name');
    this.passwordInput = page.locator('#password');
    this.loginButton = page.locator('#login-button');
  }

  async goto() {
    await this.page.goto('https://www.saucedemo.com');
  }

  async login(username: string, password: string) {
    await this.usernameInput.fill(username);
    await this.passwordInput.fill(password);
    await this.loginButton.click();
  }
}

Using Page Objects

import { test } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';
import { InventoryPage } from './pages/InventoryPage';

test('standard login flow', async ({ page }) => {
  const login = new LoginPage(page);
  const inventory = new InventoryPage(page);

  await login.goto();
  await login.login('standard_user', 'secret_sauce');
  await inventory.expectLoaded();
});

Data Parameterization

// Parameterized test with multiple data sets
const users = [
  { username: 'standard_user', password: 'secret_sauce', expected: 'inventory' },
  { username: 'locked_out_user', password: 'secret_sauce', expected: 'error' },
  { username: 'problem_user', password: 'secret_sauce', expected: 'inventory' },
];

for (const user of users) {
  test(`login as ${user.username}`, async ({ page }) => {
    const login = new LoginPage(page);
    await login.goto();
    await login.login(user.username, user.password);

    if (user.expected === 'error') {
      await expect(page.locator('.error')).toBeVisible();
    } else {
      await expect(page).toHaveURL(/inventory/);
    }
  });
}
✏️ Exercise: Create Page Objects for a checkout flow (CartPage, CheckoutPage, ConfirmationPage). Write a parameterized test that checks out with different user profiles.