Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. [MANDATORY] Before saying "implementation complete", you MUST use this skill to run tests and verify functionality. Completion reports without verification are PROHIBITED.
View on GitHubSelect agents to install to:
npx add-skill https://github.com/kazuph/reviw/blob/main/plugin/skills/webapp-testing/SKILL.md -a claude-code --skill webapp-testingInstallation paths:
.claude/skills/webapp-testing/# Web Application Testing
To test local web applications, write TypeScript E2E tests using **Playwright Test** (`@playwright/test`).
**CRITICAL: E2E Test File Placement**
- **ALWAYS** place E2E test files in `tests/e2e/` or `e2e/` directory at the project root
- **NEVER** place test scripts in `.artifacts/` - that's for evidence only (screenshots, videos)
- E2E tests should be permanent project assets, not disposable artifacts
## Decision Tree: Choosing Your Approach
```
User task → Is it static HTML?
├─ Yes → Read HTML file directly to identify selectors
│ ├─ Success → Write Playwright test using selectors
│ └─ Fails/Incomplete → Treat as dynamic (below)
│
└─ No (dynamic webapp) → Is the server already running?
├─ No → Use webServer config in playwright.config.ts
│ to auto-start the dev server
│
└─ Yes → Reconnaissance-then-action:
1. Navigate and wait for networkidle
2. Take screenshot or inspect DOM
3. Identify selectors from rendered state
4. Execute actions with discovered selectors
```
## Playwright Test Setup
### playwright.config.ts
```typescript
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
},
});
```
### Example Test: tests/e2e/login.spec.ts
```typescript
import { test, expect } from '@playwright/test';
test.describe('Login Flow', () => {