Answer
Playwright Assertions with expect()
Playwright uses expect() from @playwright/test for web-first assertions — they automatically retry until the condition is true (up to the assertion timeout).
Common Assertions
Page Assertions
TypeScript
// URL checks
await expect(page).toHaveURL('https://example.com/dashboard');
await expect(page).toHaveURL(/dashboard/);
// Page title
await expect(page).toHaveTitle('My App - Dashboard');
await expect(page).toHaveTitle(/Dashboard/);
Element Visibility
TypeScript
await expect(page.locator('.success-msg')).toBeVisible();
await expect(page.locator('.loading-spinner')).toBeHidden();
await expect(page.locator('#submit-btn')).toBeEnabled();
await expect(page.locator('#submit-btn')).toBeDisabled();
Element Text
TypeScript
await expect(page.locator('h1')).toHaveText('Welcome');
await expect(page.locator('.error')).toContainText('required');
await expect(page.locator('.badge')).toHaveText(/\d+ items/);
Element Count
TypeScript
await expect(page.locator('li.product')).toHaveCount(5);
Input Value
TypeScript
await expect(page.getByLabel('Email')).toHaveValue('user@test.com');
Checkbox State
TypeScript
await expect(page.getByLabel('Remember me')).toBeChecked();
await expect(page.getByLabel('Newsletter')).not.toBeChecked();
CSS Classes and Attributes
TypeScript
await expect(page.locator('#menu')).toHaveClass(/active/);
await expect(page.locator('img')).toHaveAttribute('alt', 'Profile photo');
Negation with .not
TypeScript
await expect(page.locator('.error-banner')).not.toBeVisible();
await expect(page.locator('.spinner')).not.toBeVisible();
Soft Assertions (non-stopping)
TypeScript
// Test continues even if this assertion fails
await expect.soft(page.locator('.price')).toHaveText('$99');
await expect.soft(page.locator('.discount')).toBeVisible();
// All failures reported at end of test
Custom Timeout
TypeScript
await expect(page.locator('.chart')).toBeVisible({ timeout: 15000 });
Full Test Example
TypeScript
import { test, expect } from '@playwright/test';
test('login and verify dashboard', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@test.com');
await page.getByLabel('Password').fill('pass123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL('/dashboard');
await expect(page.getByRole('heading')).toHaveText('Welcome back');
await expect(page.locator('.avatar')).toBeVisible();
});
