Playwright E2E Test

Page Object Model pattern with Playwright for maintainable E2E tests.

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

// Page Object
class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto('/login');
  }

  async login(email: string, password: string) {
    await this.page.getByLabel('Email').fill(email);
    await this.page.getByLabel('Password').fill(password);
    await this.page.getByRole('button', { name: 'Sign in' }).click();
  }

  async errorMessage() {
    return this.page.getByRole('alert').textContent();
  }
}

// Tests
test.describe('Login flow', () => {
  test('successful login redirects to dashboard', async ({ page }) => {
    const loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login('user@example.com', 'correct-password');

    await expect(page).toHaveURL('/dashboard');
    await expect(page.getByText('Welcome back')).toBeVisible();
  });

  test('invalid credentials shows error', async ({ page }) => {
    const loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login('user@example.com', 'wrong');

    const error = await loginPage.errorMessage();
    expect(error).toContain('Invalid credentials');
  });
});