Files
claude-skills-reference/engineering-team/playwright-pro/reference/assertions.md
Alireza Rezvani d33d03da50 feat: add playwright-pro plugin — production-grade Playwright testing toolkit (#254)
Complete Claude Code plugin with:
- 9 skills (/pw:init, generate, review, fix, migrate, coverage, testrail, browserstack, report)
- 3 specialized agents (test-architect, test-debugger, migration-planner)
- 55 test case templates across 11 categories (auth, CRUD, checkout, search, forms, dashboard, settings, onboarding, notifications, API, accessibility)
- TestRail MCP server (TypeScript) — 8 tools for bidirectional sync
- BrowserStack MCP server (TypeScript) — 7 tools for cross-browser testing
- Smart hooks (auto-validate tests, auto-detect Playwright projects)
- 6 curated reference docs (golden rules, locators, assertions, fixtures, pitfalls, flaky tests)
- Leverages Claude Code built-ins (/batch, /debug, Explore subagent)
- Zero-config for core features; TestRail/BrowserStack via env vars
- Both TypeScript and JavaScript support throughout

Co-authored-by: Leo <leo@openclaw.ai>
2026-03-05 13:50:05 +01:00

2.2 KiB

Assertions Reference

Web-First Assertions (Always Use These)

Auto-retry until timeout. Safe for dynamic content.

// Visibility
await expect(locator).toBeVisible();
await expect(locator).not.toBeVisible();
await expect(locator).toBeHidden();

// Text
await expect(locator).toHaveText('exact text');
await expect(locator).toHaveText(/partial/i);
await expect(locator).toContainText('partial');

// Value (inputs)
await expect(locator).toHaveValue('entered text');
await expect(locator).toHaveValues(['option1', 'option2']);

// Attributes
await expect(locator).toHaveAttribute('href', '/dashboard');
await expect(locator).toHaveClass(/active/);
await expect(locator).toHaveId('main-nav');

// State
await expect(locator).toBeEnabled();
await expect(locator).toBeDisabled();
await expect(locator).toBeChecked();
await expect(locator).toBeEditable();
await expect(locator).toBeFocused();
await expect(locator).toBeAttached();

// Count
await expect(locator).toHaveCount(5);
await expect(locator).toHaveCount(0); // element doesn't exist

// CSS
await expect(locator).toHaveCSS('color', 'rgb(255, 0, 0)');

// Screenshots
await expect(locator).toHaveScreenshot('button.png');
await expect(page).toHaveScreenshot('full-page.png');

Page Assertions

await expect(page).toHaveURL('/dashboard');
await expect(page).toHaveURL(/\/dashboard/);
await expect(page).toHaveTitle('Dashboard - App');
await expect(page).toHaveTitle(/Dashboard/);

Anti-Patterns (Never Do This)

// BAD — no auto-retry
const text = await locator.textContent();
expect(text).toBe('Hello');

// BAD — snapshot in time, not reactive
const isVisible = await locator.isVisible();
expect(isVisible).toBe(true);

// BAD — evaluating in page context
const value = await page.evaluate(() =>
  document.querySelector('input')?.value
);
expect(value).toBe('test');

Custom Timeout

// Override timeout for slow operations
await expect(locator).toBeVisible({ timeout: 30_000 });

Soft Assertions

Continue test even if assertion fails (report all failures at end):

await expect.soft(locator).toHaveText('Expected');
await expect.soft(page).toHaveURL('/next');
// Test continues even if above fail