← Blog

"Playwright Studio Assertion Builder — All 30+ Assertion Types Explained"

Click any element on the page and instantly generate typed Playwright assertions. This guide covers every assertion type available in the Assertion Builder with real examples.

reading now
views
comments

Series Navigation

Recorder Guide — SPAs, Shadow DOM, Iframes

Network Mock Studio


Why Assertions Matter More Than Actions

Recording actions is the easy part — any recorder can capture a click sequence. Assertions are what turn a script into a test. Without them you're just replaying actions with no verification.

A test that clicks "Submit" but never checks whether the form actually submitted is worse than useless — it gives false confidence.


Using the Assertion Builder

  1. Record your actions (or type them manually)
  2. Click the Assertion Builder tab
  3. Move your mouse over the page — elements highlight as you hover
  4. Click the element you want to assert on
  5. The panel shows all available assertion types for that element
  6. Select one → code is appended to the editor

Element Assertions

Visibility

// Element is visible on screen
await expect(page.locator('.success-message')).toBeVisible();

// Element exists in DOM but is hidden
await expect(page.locator('.error-panel')).toBeHidden();

// Element does NOT exist in DOM at all
await expect(page.locator('.loading-spinner')).not.toBeAttached();

Text Content

// Exact text match
await expect(page.locator('h1')).toHaveText('Welcome to Dashboard');

// Partial text (contains)
await expect(page.locator('.notification')).toContainText('saved successfully');

// Text matches a regex
await expect(page.locator('.user-greeting')).toHaveText(/Hello, \w+/);

// Inner text (strips HTML tags)
await expect(page.locator('.price')).toHaveText('$29.99');

Input Values

// Input field value
await expect(page.locator('#email')).toHaveValue('user@example.com');

// Textarea value
await expect(page.locator('textarea#notes')).toHaveValue('My note content');

// Empty input
await expect(page.locator('#search')).toHaveValue('');

State Assertions

// Button is enabled / disabled
await expect(page.locator('#submit')).toBeEnabled();
await expect(page.locator('#submit')).toBeDisabled();

// Checkbox / radio is checked
await expect(page.locator('#terms-checkbox')).toBeChecked();
await expect(page.locator('#terms-checkbox')).not.toBeChecked();

// Input is editable
await expect(page.locator('#name')).toBeEditable();

// Element is focused
await expect(page.locator('#email')).toBeFocused();

Attribute and Class Assertions

// Specific attribute value
await expect(page.locator('img.logo')).toHaveAttribute('alt', 'Company Logo');
await expect(page.locator('a.docs-link')).toHaveAttribute('href', '/docs');

// Attribute matches regex
await expect(page.locator('input')).toHaveAttribute('type', /text|email/);

// CSS class present
await expect(page.locator('.status-badge')).toHaveClass(/active/);
await expect(page.locator('.status-badge')).toHaveClass('badge badge-active');

CSS and Style

// CSS property value
await expect(page.locator('.alert')).toHaveCSS('background-color', 'rgb(255, 0, 0)');
await expect(page.locator('.modal')).toHaveCSS('display', 'block');

// Inline style — note: checks computed style, not inline attribute
await expect(page.locator('#panel')).toHaveCSS('visibility', 'visible');

List and Count Assertions

// Exact count of matching elements
await expect(page.locator('table tbody tr')).toHaveCount(10);
await expect(page.locator('.product-card')).toHaveCount(24);

// At least one match
await expect(page.locator('.error-message')).not.toHaveCount(0);

// Check text of all items in a list
await expect(page.locator('ul.nav li')).toHaveText([
  'Home', 'Products', 'About', 'Contact'
]);

// Partial match across list
await expect(page.locator('.tag')).toContainText(['JavaScript', 'TypeScript']);

Page-Level Assertions

// URL assertions
await expect(page).toHaveURL('https://app.example.com/dashboard');
await expect(page).toHaveURL(/dashboard/);
await expect(page).not.toHaveURL(/login/);

// Page title
await expect(page).toHaveTitle('Dashboard — My App');
await expect(page).toHaveTitle(/Dashboard/);

// Screenshot comparison (visual regression)
await expect(page).toHaveScreenshot('dashboard.png');
await expect(page.locator('.chart')).toHaveScreenshot('revenue-chart.png');

Soft Assertions — Check Multiple Without Stopping

By default, a failing assertion stops the test. Soft assertions collect all failures and report them at the end:

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

  // These all run even if one fails
  await expect.soft(page.locator('h1')).toHaveText('My Profile');
  await expect.soft(page.locator('.avatar')).toBeVisible();
  await expect.soft(page.locator('.email')).toContainText('@');
  await expect.soft(page.locator('.join-date')).toBeVisible();

  // This assertion is hard — stops if fails
  await expect(page.locator('#edit-button')).toBeEnabled();
});

Assertion Timeouts

Every expect() retries until the assertion passes or the timeout is reached (default: 5 seconds):

// Custom timeout for slow operations
await expect(page.locator('.report-generated')).toBeVisible({ timeout: 30000 });

// Global default in playwright.config.ts
export default defineConfig({
  expect: { timeout: 10000 },
});

What's Next

Discussion

Loading...

Leave a Comment

All comments are reviewed before appearing. No links please.

0 / 1000