Day 3: Assertions That Actually Catch Bugs — expect() Deep Dive
This is Day 3 of the 21-Day Playwright with TypeScript Challenge. One lesson per day. Zero to production-ready in 3 weeks.
🎭 Want to master this with real projects? Join the Playwright Automation Mastery course at The Testing Academy.
Playwright assertions auto-retry until condition met or timeout. This eliminates flaky assertions entirely — if you use them correctly.
Contents
Auto-Retry vs Non-Retry Assertions
// AUTO-RETRY (preferred — waits up to 5s by default)
await expect(page.getByText('Welcome')).toBeVisible();
await expect(page.getByRole('button')).toBeEnabled();
await expect(page).toHaveTitle(/Dashboard/);
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByTestId('count')).toHaveText('5');
// NON-RETRY (instant check — use sparingly)
expect(await page.title()).toBe('Dashboard');
expect(await page.getByText('x').count()).toBe(3);
Essential Assertions
| Assertion | What It Checks |
|---|---|
toBeVisible() | Element visible on page |
toBeHidden() | Element not visible |
toBeEnabled() | Not disabled |
toBeDisabled() | Has disabled attribute |
toBeChecked() | Checkbox/radio selected |
toHaveText('x') | Element contains text |
toContainText('x') | Partial text match |
toHaveValue('x') | Input value |
toHaveAttribute('k','v') | HTML attribute |
toHaveCount(n) | Number of matching elements |
toHaveURL(/pattern/) | Page URL matches |
toHaveTitle(/pattern/) | Page title matches |
🚀 Level Up Your Playwright
From locators to CI pipelines — build a production-grade Playwright + TypeScript framework step by step.
Soft Assertions
// Soft assertions don't stop test on failure — collect all failures
await expect.soft(page.getByTestId('name')).toHaveText('John');
await expect.soft(page.getByTestId('email')).toHaveText('john@test.com');
await expect.soft(page.getByTestId('role')).toHaveText('Admin');
// Test continues, reports ALL failures at end
Custom Timeout and Messages
// Custom timeout for slow operations
await expect(page.getByText('Report ready')).toBeVisible({ timeout: 30_000 });
// Custom error message
await expect(page.getByTestId('price'),
'Price should reflect 10% discount'
).toHaveText('$90.00');
Tomorrow (Day 4): Page interactions — click, fill, select, upload, keyboard.
🎓 Master Playwright End to End
Join hundreds of SDETs building real automation frameworks. Lifetime access, hands-on projects, and a job-ready portfolio.
