From triqual-plugin
Scan test files for Playwright best practice violations. Use when user says check my tests, lint tests, validate tests, or audit test code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/triqual-plugin:checkThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Scan your test files for violations of the 31 Playwright best practice rules and get actionable fix suggestions.
Scan your test files for violations of the 31 Playwright best practice rules and get actionable fix suggestions.
/test or /test --ticket/check # Check all test files in project
/check ./tests/auth # Check specific directory
/check --severity=error # Only show errors (not warnings)
/check --fix # Show and offer to apply auto-fixes
The checker scans for violations across 8 categories:
| Category | Rules | Focus |
|---|---|---|
| Selectors | 3 | data-testid, no XPath, role-based |
| Locators | 3 | visibility, .first(), chaining |
| Waiting | 4 | no hardcoded timeouts, auto-waiting |
| Assertions | 4 | web-first, specific, soft assertions |
| Test Structure | 5 | isolation, hooks, fixtures, naming |
| Page Objects | 4 | locators, actions, composition |
| Parallelization | 4 | worker isolation, shared state |
| Networking | 4 | mocking, route handlers, waiting |
Locate all test files to scan:
# Default: find all .spec.ts and .test.ts files
find . -name "*.spec.ts" -o -name "*.test.ts" | grep -v node_modules
Or use provided path argument.
For each test file, check for these common violations:
| Rule | Pattern to Detect | Why It's Bad |
|---|---|---|
wait-no-timeout | waitForTimeout( or page.waitFor(\d+) | Hardcoded waits cause flakiness |
selector-no-xpath | xpath= or // in locators | XPath is brittle |
locator-visibility | .nth(0) without :visible | Hidden elements shift indices |
assert-web-first | expect(await page. followed by ).toBe( | Should use web-first assertions |
test-isolation | Shared mutable state between tests | Tests must be independent |
| Rule | Pattern to Detect | Why It's Risky |
|---|---|---|
selector-testid | CSS selectors without data-testid | May break on styling changes |
assert-timeout | Assertions without timeout option | May timeout inconsistently |
locator-first | Multiple .first() calls chained | Usually indicates bad selector |
page-object-no-assertions | expect() inside Page Object class | Assertions belong in tests |
| Rule | Pattern to Detect | Suggestion |
|---|---|---|
test-naming | Test name doesn't start with "should" | Improve readability |
debug-trace | No trace configuration | Add for debugging |
For each violation found:
## Violations Report
### Summary
| Severity | Count |
|----------|-------|
| ERROR | 3 |
| WARN | 7 |
| INFO | 2 |
| **Total** | **12** |
---
### ERROR: wait-no-timeout
**File**: `tests/login.spec.ts:45`
**Rule**: Never use hardcoded waitForTimeout
```typescript
// Current (line 45):
await page.waitForTimeout(3000);
// Suggested fix:
await page.waitForSelector('.modal:visible');
// or
await expect(page.locator('.modal')).toBeVisible();
File: tests/checkout.spec.ts:23
Rule: Prefer data-testid over CSS selectors
// Current (line 23):
await page.locator('.btn-primary.submit').click();
// Suggested fix:
await page.locator('[data-testid="checkout-submit"]').click();
### Step 4: Offer Fixes (if --fix)
For auto-fixable violations:
```markdown
## Auto-Fixable Violations
Found 5 violations that can be auto-fixed:
1. `tests/login.spec.ts:45` - Add :visible to selector
2. `tests/login.spec.ts:52` - Replace waitForTimeout with waitForSelector
3. `tests/checkout.spec.ts:23` - [Manual] Add data-testid (requires code change)
4. `tests/dashboard.spec.ts:18` - Add timeout to assertion
5. `tests/dashboard.spec.ts:31` - Add timeout to assertion
**Apply auto-fixes for items 1, 2, 4, 5? (y/n)**
// Detects:
page.waitForTimeout(1000)
await page.waitFor(5000)
{ timeout: 30000 } // without getTimeout()
// Fix:
// Replace with waitForSelector, waitForLoadState, or assertion
await page.waitForLoadState('networkidle');
await expect(element).toBeVisible({ timeout: getTimeout() });
// Detects:
page.locator('xpath=//div[@class="content"]')
page.locator('//button[contains(text(), "Submit")]')
// Fix:
page.locator('[data-testid="content"]')
page.getByRole('button', { name: 'Submit' })
// Detects:
page.locator('.item').nth(0)
locator.nth(2).click()
// Fix:
page.locator('.item:visible').first()
locator.filter({ hasText: 'specific' }).first()
// Detects:
const text = await element.textContent();
expect(text).toBe('Hello');
// Fix:
await expect(element).toHaveText('Hello');
// Detects:
page.locator('.submit-button')
page.locator('button.primary')
// Suggest:
// Add data-testid="submit-button" to HTML
// Then use: page.locator('[data-testid="submit-button"]')
// Detects:
await expect(element).toBeVisible();
// Suggest:
await expect(element).toBeVisible({ timeout: getTimeout() });
If violations found:
/check to verify fixesIf tests are failing due to rule violations:
/check --severity=error # Find violations
# Apply fixes
npx playwright test # Re-run tests
Search for pattern documentation:
mcp__quoth__quoth_search_index({ query: "wait-no-timeout pattern" })
npx playwright test)/test)/test --ticket)This skill is for static analysis and linting only.
## Playwright Best Practices Audit
**Scanned**: 15 test files
**Total Tests**: 47
### Results
| Severity | Count | Status |
|----------|-------|--------|
| ERROR | 0 | ✅ |
| WARN | 3 | ⚠️ |
| INFO | 5 | ℹ️ |
### Warnings (3)
1. **tests/auth/login.spec.ts:34** - `selector-testid`
Using `.submit-btn` - consider adding data-testid
2. **tests/checkout/payment.spec.ts:67** - `assert-timeout`
Assertion missing explicit timeout
3. **tests/checkout/payment.spec.ts:72** - `assert-timeout`
Assertion missing explicit timeout
### Info (5)
1-5. Test naming suggestions (use "should ..." format)
---
**Overall**: Good! No critical violations found.
Consider addressing the 3 warnings when convenient.
Check:
.spec.ts or .test.ts?Start with:
/check --severity=error # Fix critical issues first
Some patterns may have valid uses. Use judgment and:
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.
Reviews Playwright E2E suites for flakiness, brittle selectors, isolation defects, and CI reliability issues without executing tests.
Plans, organizes, and optimizes Playwright regression test suites for web apps using TypeScript. Covers change-based test selection, sharding, parallel execution, GitHub Actions CI/CD, flaky test management, and suite monitoring.