From triqual-plugin
Comprehensive Playwright best practices and rules. Use when writing, reviewing, or debugging Playwright tests. 31 rules across 8 categories.
How this skill is triggered — by the user, by Claude, or both
Slash command
/triqual-plugin:rulesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Comprehensive rules and best practices for writing reliable, maintainable Playwright tests. 31 documented rules across 8 categories.
Comprehensive rules and best practices for writing reliable, maintainable Playwright tests. 31 documented rules across 8 categories.
| Rule | Category | Issue |
|---|---|---|
wait-no-timeout | Waits | Never use waitForTimeout() - causes flaky tests |
assert-web-first | Assertions | Use web-first assertions with auto-retry |
test-isolation | Organization | Tests must be independent for parallel execution |
parallel-worker-isolation | Parallel | Workers cannot share state |
parallel-shared-state | Parallel | No shared mutable state between tests |
selector-no-xpath | Locators | XPath is fragile and breaks easily |
locator-first | Locators | Use .first() explicitly when multiple match |
network-route-handlers | Network | Always resolve routes (continue/fulfill/abort) |
debug-slow-mo | Debugging | Never leave slowMo in CI |
Locators (Do → Don't)
// ✅ getByRole('button', { name: 'Submit' }) → ❌ locator('.btn-submit')
// ✅ getByTestId('user-avatar') → ❌ locator('#avatar-12345')
// ✅ getByLabel('Email') → ❌ locator('input[type="email"]')
// ✅ locator('.item').first() → ❌ locator('.item') when multiple
Waits (Do → Don't)
// ✅ await expect(el).toBeVisible() → ❌ await page.waitForTimeout(1000)
// ✅ await page.waitForURL('/dashboard') → ❌ await page.waitForLoadState('networkidle')
// ✅ await response.finished() → ❌ await page.waitForTimeout(500)
Assertions (Do → Don't)
// ✅ await expect(locator).toHaveText('Hi') → ❌ expect(await locator.textContent()).toBe('Hi')
// ✅ await expect(locator).toBeVisible() → ❌ expect(await locator.isVisible()).toBe(true)
// ✅ await expect(page).toHaveURL('/home') → ❌ expect(page.url()).toBe('/home')
Read the full documentation at ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/:
Finding elements reliably and maintainably.
# Read all locator rules
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/locator-*.md
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/selector-*.md
| Rule | Description |
|---|---|
locator-visibility | Verify element visibility before interactions |
locator-first | Use .first() explicitly or refine locators |
locator-chaining | Chain locators to narrow scope |
selector-testid | Prefer getByTestId over CSS selectors |
selector-no-xpath | Avoid fragile XPath expressions |
selector-role-based | Prefer role-based locators (getByRole) |
Handling asynchronous operations without flakiness.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/wait-*.md
| Rule | Description |
|---|---|
wait-no-timeout | CRITICAL - No hardcoded waitForTimeout |
wait-for-state | Prefer waitFor over networkidle |
wait-auto-waiting | Leverage Playwright's auto-waiting |
wait-explicit-conditions | Use explicit wait conditions |
Verifying outcomes with auto-retry.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/assert-*.md
| Rule | Description |
|---|---|
assert-web-first | CRITICAL - Use web-first assertions |
assert-specific | Use specific assertion methods |
assert-soft | Use soft assertions appropriately |
assert-timeout | Configure assertion timeouts properly |
Organizing locators and actions.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/page-object-*.md
| Rule | Description |
|---|---|
page-object-locators | Move inline locators to Page Objects |
page-object-actions | Encapsulate actions in methods |
page-object-composition | Compose Page Objects for complex pages |
page-object-no-assertions | Keep assertions in tests, not POs |
Structuring tests for maintainability and parallel execution.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/test-*.md
| Rule | Description |
|---|---|
test-isolation | CRITICAL - Tests must be independent |
test-hooks | Use beforeEach/afterEach properly |
test-fixtures | Leverage Playwright fixtures |
test-describe-grouping | Group related tests with describe |
test-naming | Use descriptive test names |
Mocking and intercepting network requests.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/network-*.md
| Rule | Description |
|---|---|
network-mock-api | Mock external API calls |
network-route-handlers | CRITICAL - Always resolve routes |
network-wait-response | Wait for specific responses |
network-abort-unnecessary | Abort unnecessary requests |
Troubleshooting and diagnosing test failures.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/debug-*.md
| Rule | Description |
|---|---|
debug-trace-on-failure | Enable traces for failed tests |
debug-screenshots | Capture screenshots strategically |
debug-video-recording | Configure video recording |
debug-slow-mo | CRITICAL - Never in CI |
Running tests safely in parallel.
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/parallel-*.md
| Rule | Description |
|---|---|
parallel-worker-isolation | CRITICAL - Ensure worker isolation |
parallel-shared-state | CRITICAL - No shared mutable state |
parallel-test-data | Use unique test data per worker |
parallel-serial-when-needed | Mark serial tests explicitly |
When reviewing test code, read the relevant rule files:
// If you see this in a test:
await page.waitForTimeout(2000);
// Reference: wait-no-timeout.md (ERROR severity)
// This is the #1 cause of flaky tests!
Each rule file includes:
Reference rules in code reviews:
This violates `wait-no-timeout` (ERROR) - use explicit conditions instead:
- Before: `await page.waitForTimeout(2000)`
- After: `await expect(element).toBeVisible()`
See: docs/playwright-rules/rules/wait-no-timeout.md
To read a specific rule:
# Read a specific rule
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/wait-no-timeout.md
# Read all rules in a category
cat ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/assert-*.md
# Search for patterns
grep -r "auto-fix" ${CLAUDE_PLUGIN_ROOT}/docs/playwright-rules/rules/
/test --explore - Apply rules when writing ad-hoc tests/test - Use patterns when creating production tests/test --ticket - Reference rules when generating from tickets/check --fix for auto-fixes)/test or /test --explore)/test)npx claudepluginhub montinou/triqual --plugin triqual-pluginReviews Playwright test files for 20 anti-patterns, best practices, and coverage gaps. Scores 1-10 per file, generates reports, and offers fixes for critical issues.
Writes maintainable Playwright E2E tests using page objects, accessible locators, fixtures, and parallel execution. Helps debug flaky tests and manage complex user flows.
Guides Playwright end-to-end testing: selectors, assertions, fixtures, auth, parallelism, CI, visual regression, and flake hunting. Activate with playwright/e2e/playwright config topics.