# Playwright E2E Testing Guide ## Overview Playwright is now set up for end-to-end testing. This allows both developers and Claude AI to run browser tests and see complete output including console logs, network requests, and errors. ## Why Playwright? **For Developers:** - Automated testing prevents regressions - Catches bugs before they reach production - Tests serve as documentation for how features should work **For Claude AI:** - Can see browser console output without manual copy/paste - Can see network requests/responses - Can run tests to verify changes work - Screenshots and videos on test failures ## Running Tests ### Basic Commands ```bash # Run all tests (headless) npm test # Run tests with browser visible npm run test:headed # Run tests in debug mode (step through tests) npm run test:debug # Open Playwright UI (interactive test runner) npm run test:ui # Show test report npm run test:report ``` ### Running Specific Tests ```bash # Run a specific test file npx playwright test navigation.spec.ts # Run tests matching a pattern npx playwright test --grep "login" # Run a specific test by line number npx playwright test navigation.spec.ts:15 ``` ## Test Structure ### Test Files Location All tests are in `frontend/e2e/`: - `navigation.spec.ts` - Tests routing and navigation - `api.spec.ts` - Tests API calls and network requests - `accessibility.spec.ts` - Tests accessibility with axe-core - `auth.setup.ts` - Authentication helpers ### Example Test ```typescript import { test, expect } from '@playwright/test'; test('example test', async ({ page }) => { // Listen to console logs page.on('console', (msg) => { console.log(`[BROWSER ${msg.type()}]:`, msg.text()); }); // Listen to errors page.on('pageerror', (error) => { console.error('[BROWSER ERROR]:', error.message); }); // Navigate and test await page.goto('/login'); await expect(page.locator('text=VIP Coordinator')).toBeVisible(); }); ``` ## What Claude Can See When Claude runs Playwright tests, Claude can see: 1. **Browser Console Logs** ``` [BROWSER log]: User logged in [BROWSER error]: Cannot read property 'map' of undefined [BROWSER warn]: Deprecated API usage ``` 2. **Network Requests** ``` [→ REQUEST] GET http://localhost:3000/api/v1/users [← RESPONSE] 200 GET http://localhost:3000/api/v1/users [RESPONSE BODY] {"users": [...]} ``` 3. **Page Errors** ``` [PAGE ERROR]: TypeError: Cannot read property 'map' of undefined at VIPPage.tsx:45 ``` 4. **Screenshots** (on failure) - Saved to `test-results/` 5. **Videos** (on failure) - Saved to `test-results/` 6. **Traces** (on retry) - Full timeline of what happened - View with `npx playwright show-trace trace.zip` ## Writing New Tests ### Test Template Create a new file in `e2e/` directory: ```typescript import { test, expect } from '@playwright/test'; test.describe('Feature Name', () => { test('should do something', async ({ page }) => { // Enable logging page.on('console', (msg) => console.log(`[BROWSER]:`, msg.text())); page.on('pageerror', (error) => console.error('[ERROR]:', error.message)); // Your test code await page.goto('/your-page'); await expect(page.locator('selector')).toBeVisible(); }); }); ``` ### Best Practices 1. **Always add console listeners** - This helps Claude debug issues ```typescript page.on('console', (msg) => console.log(`[BROWSER]:`, msg.text())); page.on('pageerror', (error) => console.error('[ERROR]:', error)); ``` 2. **Add network listeners for API tests** ```typescript page.on('request', (req) => console.log(`[→] ${req.method()} ${req.url()}`)); page.on('response', (res) => console.log(`[←] ${res.status()} ${res.url()}`)); ``` 3. **Use descriptive test names** ```typescript test('should show error message when login fails', async ({ page }) => { // ... }); ``` 4. **Wait for network to be idle** ```typescript await page.goto('/dashboard'); await page.waitForLoadState('networkidle'); ``` 5. **Test user workflows, not implementation** ```typescript // Good await page.click('text=Add VIP'); await page.fill('input[name="name"]', 'John Doe'); await page.click('button:has-text("Save")'); // Bad (too implementation-specific) await page.locator('#vip-form > div > button.submit').click(); ``` ## Common Issues ### Tests Fail to Start **Problem:** `Error: No tests found` **Solution:** Make sure test files end with `.spec.ts` or `.test.ts` ### Can't Connect to Dev Server **Problem:** `Error: connect ECONNREFUSED` **Solution:** The dev server should start automatically. If not, check `playwright.config.ts` webServer config ### Auth0 Login Required **Problem:** Tests need to log in through Auth0 **Solution:** For now, tests can mock authentication. See `auth.setup.ts` for details. ## Configuration All configuration is in `playwright.config.ts`: ```typescript export default defineConfig({ testDir: './e2e', // Where tests live timeout: 30 * 1000, // Test timeout use: { baseURL: 'http://localhost:5173', trace: 'on-first-retry', // Capture trace on failure screenshot: 'only-on-failure', video: 'retain-on-failure', }, webServer: { command: 'npm run dev', // Start dev server automatically url: 'http://localhost:5173', reuseExistingServer: true, }, }); ``` ## Debugging Tests ### Method 1: Headed Mode See the browser as tests run: ```bash npm run test:headed ``` ### Method 2: Debug Mode Step through tests line by line: ```bash npm run test:debug ``` ### Method 3: UI Mode (Best for Development) Interactive test runner with time travel debugging: ```bash npm run test:ui ``` ### Method 4: Console Logs Add console.log in your test: ```typescript test('debug test', async ({ page }) => { console.log('Starting test...'); await page.goto('/login'); console.log('Navigated to login'); const title = await page.title(); console.log('Page title:', title); }); ``` ## CI/CD Integration Tests can run in continuous integration: ```yaml # .github/workflows/test.yml - name: Install dependencies run: npm ci - name: Install Playwright Browsers run: npx playwright install --with-deps - name: Run Playwright tests run: npm test - name: Upload test results uses: actions/upload-artifact@v3 with: name: playwright-report path: playwright-report/ ``` ## Tips for Claude When Claude runs tests, look for: 1. **Console errors** - Any red [BROWSER error] or [PAGE ERROR] messages 2. **Failed network requests** - 400, 500 status codes 3. **Test failures** - Which assertions failed and why 4. **Screenshots** - Visual evidence of what went wrong 5. **Traces** - Timeline of events leading to failure ## Resources - [Playwright Documentation](https://playwright.dev) - [Best Practices](https://playwright.dev/docs/best-practices) - [API Reference](https://playwright.dev/docs/api/class-playwright) - [Debugging Guide](https://playwright.dev/docs/debug) ## Next Steps 1. Add more tests for critical user flows 2. Set up CI/CD to run tests automatically 3. Add visual regression testing 4. Add performance testing with Lighthouse --- **Last Updated:** 2026-01-31 **Playwright Version:** 1.58.1