Playwright·Cookbook Field Manual
Part 02 · Locators & Structure Card 11

Login Flow (Forms & Navigation)

Card 11: Login Flow (Forms & Navigation)

What This Pattern Solves

Most real applications have forms, navigation, and multi-page flows. This card teaches you how to interact with form elements, submit them, and assert on navigation - going beyond the read-only tests from earlier cards.

How It Works

  1. Navigate to the login page
  2. Use getByLabel() to find form inputs (accessibility-friendly)
  3. Use fill() to enter text
  4. Use Promise.all() to wait for navigation while clicking submit
  5. Assert on the new URL and page content

This demonstrates user interaction patterns - clicking, typing, and navigating - that you’ll use in most real-world tests.

Code Example

test('fills login form and navigates to protected page', async ({ page }) => {
  await page.goto('/login');

  // Fill form using accessible labels
  await page.getByLabel('Username').fill('testuser');
  await page.getByLabel('Password').fill('password');

  // Submit and wait for navigation
  await Promise.all([
    page.waitForURL(/protected/),
    page.getByRole('button', { name: 'Log in' }).click(),
  ]);

  // Assert we're on protected page
  await expect(page).toHaveURL(/protected/);
  await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});

Run This Example

pnpm test src/11-login-flow

Prerequisites

Key Concepts

When to Use This Pattern

Common Mistakes

Flow Diagram

sequenceDiagram
    participant Test
    participant Browser
    participant LoginPage
    participant ProtectedPage

    Test->>Browser: page.goto('/login')
    Browser->>LoginPage: Load login page
    Test->>LoginPage: fill('Username', 'testuser')
    Test->>LoginPage: fill('Password', 'password')
    Test->>LoginPage: click('Log in') + waitForURL
    LoginPage->>LoginPage: Store auth in localStorage
    LoginPage->>Browser: Navigate to /protected
    Browser->>ProtectedPage: Load protected page
    Test->>ProtectedPage: expect URL /protected ✓
    Test->>ProtectedPage: expect heading 'Dashboard' ✓

Live Demo

👇 This login form is what the Playwright test interacts with:

Log in

Run This Example

pnpm test src/11-login-flow