# 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
