Module 3 of 5

Assertions & Validations

Write robust assertions using Playwright's built-in expect library with auto-retry.

🔍 The expect() API

Unlike Selenium where you had to write your own waits, Playwright's expect() automatically retries until the condition is met or a timeout occurs.

assertions.spec.ts
import { test, expect } from '@playwright/test';

test('common assertions', async ({ page }) => {
  await page.goto('/login');

  // Element visibility
  await expect(page.getByRole('button', { name: 'Login' })).toBeVisible();

  // Text content
  await expect(page.getByRole('heading')).toHaveText('Welcome Back');

  // Input value
  await expect(page.getByLabel('Email')).toHaveValue('user@example.com');

  // URL check
  await expect(page).toHaveURL('/dashboard');

  // Element count
  const items = page.getByRole('listitem');
  await expect(items).toHaveCount(5);

  // CSS class check
  await expect(page.locator('.alert')).toHaveClass(/error/);
});

🧊 Soft Assertions — Don't Stop on First Failure

With regular assertions, the test stops on the first failure. Soft assertions let ALL checks run, then report all failures together.

test('dashboard checks', async ({ page }) => {
  await page.goto('/dashboard');

  // These all run even if one fails
  await expect.soft(page.getByText('Welcome')).toBeVisible();
  await expect.soft(page.locator('.stats-card')).toHaveCount(4);
  await expect.soft(page.getByRole('button', { name: 'Logout' })).toBeEnabled();

  // Test fails at the end with ALL soft assertion errors listed
});

✅ Best Practice: Use soft assertions when validating a dashboard or multiple UI components in a single test — it gives you the full picture faster.

📸 Visual Comparisons (Screenshot Testing)

test('homepage looks correct', async ({ page }) => {
  await page.goto('/');

  // Takes a screenshot on first run (baseline), then compares on next runs
  await expect(page).toHaveScreenshot('homepage.png');

  // Specific element screenshot
  await expect(page.locator('.hero-banner')).toHaveScreenshot('hero.png', {
    maxDiffPixels: 100, // Allow minor differences
  });
});

// Update snapshots when the UI intentionally changes:
// npx playwright test --update-snapshots
First run creates the baseline screenshots automatically
Subsequent runs compare against the saved baseline
CI fails if visual drift exceeds your threshold
--update-snapshots refreshes the baseline when UI changes
📝 Module Quiz

Test Your Knowledge

Score 70%+ to advance to the next module

Question 1 of 4
0 answered

Q1. What makes Playwright's expect() different from a regular if-statement check?

Q2. What is a "soft assertion"?

Q3. Which assertion checks whether the page navigated to a specific URL?

Q4. How do you update screenshot baselines when the UI intentionally changes?