# Create E2e Test

> Create Playwright E2E tests for user flows. Use when testing complete user journeys, protected routes, form submissions, or cross-page navigation.

- Skill: `majiayu000/create-e2e-test` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/create-e2e-test`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/create-e2e-test/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/create-e2e-test

---


# Create E2E Test

## When to Use

- Testing complete user flows
- Testing protected routes and middleware
- Verifying form submissions
- User asks to "add E2E test" or "test user flow"

## Test Location

```
tests/
├── authentication.spec.ts
├── dashboard.spec.ts
└── profile.spec.ts
```

## Basic Test

```typescript
import { test, expect } from '@playwright/test';

test.describe('Feature Name', () => {
    test('should do something', async ({ page }) => {
        await page.goto('/');
        await expect(page.getByRole('heading', { name: 'Title' })).toBeVisible();
    });
});
```

## Authentication Flow

```typescript
test('signs in and accesses dashboard', async ({ page }) => {
    await page.goto('/sign-in');
    await page.getByLabel(/email/i).fill('admin@iridium.com');
    await page.getByLabel(/password/i).fill('Admin123!');
    await page.getByRole('button', { name: /sign in/i }).click();

    await expect(page).toHaveURL(/dashboard/);
});
```

## Form Testing

```typescript
test('shows validation errors', async ({ page }) => {
    await page.goto('/sign-in');
    await page.getByRole('button', { name: /sign in/i }).click();

    await expect(page.getByText(/email is required/i)).toBeVisible();
});
```

## Selectors - Use Semantic

```typescript
// GOOD
page.getByRole('button', { name: /submit/i })
page.getByLabel(/email/i)
page.getByText(/success/i)

// BAD
page.locator('.btn-primary')
page.locator('#submit-button')
```

## Test Credentials

| Email | Password | Role |
|-------|----------|------|
| `admin@iridium.com` | `Admin123!` | ADMIN |
| `editor@iridium.com` | `Editor123!` | EDITOR |
| `user@iridium.com` | `User123!` | USER |

## Running Tests

```bash
npm run e2e           # Headless
npm run e2e:ui        # Visual UI (recommended)
npm run e2e:headed    # Browser visible
npm run e2e:debug     # Debug mode
```

## Common Assertions

```typescript
await expect(page).toHaveURL(/dashboard/);
await expect(page).toHaveTitle('Page Title');
await expect(page.getByText('Hello')).toBeVisible();
await expect(page.getByRole('button')).toBeDisabled();
```

## Checklist

1. [ ] Create `*.spec.ts` in `tests/` directory
2. [ ] Use semantic selectors (role, label, text)
3. [ ] Set up authentication if testing protected routes
4. [ ] Avoid hardcoded waits (`waitForTimeout`)

## Full Reference

See `.github/instructions/playwright.instructions.md` for:
- API response testing
- Role-based access testing
- CI/CD integration
- Debugging strategies

