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>
59 lines
1.9 KiB
Bash
Executable File
59 lines
1.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Post-write hook: validates Playwright test files for common anti-patterns.
|
||
# Runs silently — only outputs warnings if issues found.
|
||
# Input: JSON on stdin with tool_input.file_path
|
||
|
||
set -euo pipefail
|
||
|
||
# Read the file path from stdin JSON
|
||
INPUT=$(cat)
|
||
FILE_PATH=$(echo "$INPUT" | python3 -c "
|
||
import sys, json
|
||
try:
|
||
data = json.load(sys.stdin)
|
||
print(data.get('tool_input', {}).get('file_path', ''))
|
||
except:
|
||
print('')
|
||
" 2>/dev/null || echo "")
|
||
|
||
# Only check .spec.ts and .spec.js files
|
||
if [[ ! "$FILE_PATH" =~ \.(spec|test)\.(ts|js|mjs)$ ]]; then
|
||
exit 0
|
||
fi
|
||
|
||
# Check if file exists
|
||
if [[ ! -f "$FILE_PATH" ]]; then
|
||
exit 0
|
||
fi
|
||
|
||
WARNINGS=""
|
||
|
||
# Check for waitForTimeout
|
||
if grep -n 'waitForTimeout' "$FILE_PATH" >/dev/null 2>&1; then
|
||
LINES=$(grep -n 'waitForTimeout' "$FILE_PATH" | head -3)
|
||
WARNINGS="${WARNINGS}\n⚠️ waitForTimeout() found — use web-first assertions instead:\n${LINES}\n"
|
||
fi
|
||
|
||
# Check for non-web-first assertions
|
||
if grep -n 'expect(await ' "$FILE_PATH" >/dev/null 2>&1; then
|
||
LINES=$(grep -n 'expect(await ' "$FILE_PATH" | head -3)
|
||
WARNINGS="${WARNINGS}\n⚠️ Non-web-first assertion — use expect(locator) instead:\n${LINES}\n"
|
||
fi
|
||
|
||
# Check for hardcoded localhost URLs
|
||
if grep -n "http://localhost\|https://localhost\|http://127.0.0.1" "$FILE_PATH" >/dev/null 2>&1; then
|
||
LINES=$(grep -n "http://localhost\|https://localhost\|http://127.0.0.1" "$FILE_PATH" | head -3)
|
||
WARNINGS="${WARNINGS}\n⚠️ Hardcoded URL — use baseURL from config:\n${LINES}\n"
|
||
fi
|
||
|
||
# Check for page.$() usage
|
||
if grep -n 'page\.\$(' "$FILE_PATH" >/dev/null 2>&1; then
|
||
LINES=$(grep -n 'page\.\$(' "$FILE_PATH" | head -3)
|
||
WARNINGS="${WARNINGS}\n⚠️ page.\$() is deprecated — use page.locator() or getByRole():\n${LINES}\n"
|
||
fi
|
||
|
||
# Output warnings if any found
|
||
if [[ -n "$WARNINGS" ]]; then
|
||
echo -e "\n🎭 Playwright Pro — Test Validation${WARNINGS}"
|
||
fi
|