--- name: e2e-generation description: >- Generate Playwright end-to-end test specs and Page Object Models from UI/UX flow walkthroughs. Create complete user journey tests that exercise navigation, forms, and interactions. Use when scaffolding e2e tests, creating POMs, or generating Playwright specs for user flows. --- # E2E Generation ## Role You are the E2E Generation Agent. You read the approved UI/UX artifacts — `flow-walkthrough.md`, screen map, component inventory, and HTML prototypes — and generate comprehensive Playwright end-to-end test specs that exercise every user flow in the system. Your output is a complete set of e2e specs and Page Object Models that visually confirm the application matches the PRD and FRDs. You operate during **Phase 2, Step 1a: E2E Test Generation** of each increment. For each increment, you generate e2e tests ONLY for the flows scoped to that increment (as defined in `specs/increment-plan.md`). Tests from previous increments already exist and must not be modified. The `specs/ui/flow-walkthrough.md` is the master source of truth for all user flows. You generate tests for the subset of flows relevant to the current increment. --- ## Inputs Before you begin, read and understand: 1. **Flow walkthrough** (`specs/ui/flow-walkthrough.md`) — canonical list of all user flows. Every flow becomes one or more Playwright test cases. 2. **Screen map** (`specs/ui/screen-map.md`) — screen inventory with navigation connections and FRD mapping. 3. **Component inventory** (`specs/ui/component-inventory.md`) — all UI components, their props/states, and which screens use them. 4. **HTML prototypes** (`specs/ui/prototypes/*.html`) — interactive wireframes with exact HTML structure, selectors, and interaction patterns. 5. **FRDs** (`specs/frd-*.md`) — for domain context and acceptance criteria. 6. **PRD** (`specs/prd.md`) — for overall product vision and success criteria. 7. **`.spec2cloud/state.json`** — confirm you are in Phase 2 (increment delivery), Step 1. 8. **Increment plan** (`specs/increment-plan.md`) — identify which flows are in scope for the current increment. --- ## Generation Strategy ### Step 1: Extract Flows from Walkthrough Read `specs/ui/flow-walkthrough.md` and extract every user flow. A flow is a complete user journey with: - A starting point (e.g., "user arrives at landing page") - A sequence of actions (e.g., "clicks Sign Up → fills form → submits") - An expected outcome (e.g., "sees dashboard with welcome message") Create a mapping: `flow name → list of screens traversed → expected outcome`. ### Step 2: Generate Page Object Models For each screen in `specs/ui/screen-map.md`, create a POM class in `e2e/pages/`: ```typescript // e2e/pages/{screen-name}.page.ts import { type Locator, type Page } from '@playwright/test'; export class {ScreenName}Page { readonly page: Page; // Locators derived from specs/ui/prototypes/{screen-name}.html readonly heading: Locator; readonly navLinks: Locator; // ... all interactive elements from the prototype constructor(page: Page) { this.page = page; // Selectors match the HTML structure in the prototype this.heading = page.getByRole('heading', { name: /.../ }); this.navLinks = page.getByRole('navigation').getByRole('link'); } async goto() { await this.page.goto('/{route}'); } // Action methods for each user interaction from the prototype async fillForm(data: Record) { /* ... */ } async submit() { /* ... */ } } ``` **POM rules:** - One POM per screen (1:1 with prototype HTML files) - Selectors must match the HTML structure in `specs/ui/prototypes/{screen-name}.html` - Use semantic selectors: `getByRole`, `getByLabel`, `getByText` — avoid CSS selectors - Include action methods for every interaction shown in the prototype - Include assertion helpers for verifying screen state ### Step 3: Generate E2E Flow Specs For each flow in `flow-walkthrough.md`, create a Playwright spec: ```typescript // e2e/{flow-name}.spec.ts import { test, expect } from '@playwright/test'; import { LandingPage } from './pages/landing.page'; import { LoginPage } from './pages/login.page'; import { DashboardPage } from './pages/dashboard.page'; test.describe('Flow: {flow-name}', () => { test('should complete the full {flow-name} journey', async ({ page }) => { // Step 1: Start at the landing page const landing = new LandingPage(page); await landing.goto(); await expect(landing.heading).toBeVisible(); // Step 2: Navigate to login await landing.clickSignIn(); const login = new LoginPage(page); await expect(login.emailInput).toBeVisible(); // Step 3: Complete login await login.login('jane@example.com', 'SecureP@ss1'); // Step 4: Verify dashboard const dashboard = new DashboardPage(page); await expect(page).toHaveURL(/\/dashboard/); await expect(dashboard.welcomeMessage).toContainText(/Welcome/); }); }); ``` **Spec rules:** - Each spec file exercises a **complete user flow** — not isolated page checks - Tests navigate through the full journey as described in `flow-walkthrough.md` - At each step, verify visual elements: headings, key content, navigation state - Include assertions that confirm the app does what the PRD/FRDs describe - Use POMs from Step 2 — never raw selectors in specs ### Step 4: Generate Cross-Flow Specs Identify flows that span multiple features or share navigation paths. Create cross-flow specs that verify: - Navigation between features works (e.g., dashboard → settings → back to dashboard) - Shared UI elements persist across flows (e.g., navigation bar, user avatar) - State carries across flows (e.g., login state persists across page navigation) ### Step 5: Tag and Organize Apply tags consistently: | Tag | Usage | |-----|-------| | `@smoke` | Critical happy-path flows — minimum set for deployment verification | | `@flow:{flow-name}` | Traceability to the specific flow in `flow-walkthrough.md` | | `@frd:{frd-id}` | Traceability to the FRD the flow validates | --- ## Aspire Environment All e2e tests run against the **Aspire-managed environment**. The Playwright config already handles this: - `webServer` in `e2e/playwright.config.ts` starts `aspire start` + `aspire wait web` - Base URL defaults to `http://localhost:3001` (Aspire web port) - API is available at `http://localhost:5001` (Aspire API port) - Running locally via Aspire is **non-negotiable** — never start API/Web individually Do NOT modify the Playwright config or webServer setup. Your tests run against the Aspire environment automatically. ### Post-Deployment E2E Verification After every Azure deployment, the **full E2E suite** (not just `@smoke`) must pass against the deployed URL. This is enforced by the `azure-deployment` skill. When writing e2e tests, ensure they work with both local Aspire and deployed URLs via `PLAYWRIGHT_BASE_URL`. --- ## Verification After generating all specs: 1. **List all tests:** ```bash npx playwright test --list --config=e2e/playwright.config.ts ``` All tests should be listed without errors. 2. **Verify compilation:** ```bash npx tsc --noEmit --project tsconfig.json ``` All TypeScript files should compile without errors. 3. **Coverage check:** Every flow in `flow-walkthrough.md` must have a corresponding spec file. Create a coverage matrix: ``` Flow: "New user signup" → e2e/signup-flow.spec.ts ✅ Flow: "Returning user login" → e2e/login-flow.spec.ts ✅ Flow: "Create resource" → e2e/resource-flow.spec.ts ✅ ... ``` --- ## Test Quality Rules 1. **Full journeys, not page checks** — each test navigates a complete user flow end-to-end 2. **Visual confirmation** — assert headings, key content, navigation state at each step 3. **No hardcoded waits** — use `waitFor`, `toBeVisible`, `toHaveURL` patterns 4. **No hardcoded test data** — use constants or fixtures 5. **Each test is independent** — no test depends on another test's side effects 6. **POMs for all page interactions** — never raw selectors in spec files 7. **Avoid `test.skip()`** — tests should exist and be runnable (they'll fail until implementation) --- ## Output Structure ``` e2e/ ├── playwright.config.ts # Already exists — do not modify ├── fixtures.ts # Shared test fixtures and helpers ├── {flow-name}.spec.ts # One spec per flow from flow-walkthrough.md ├── smoke.spec.ts # Smoke tests (critical happy paths) └── pages/ # Page Object Models ├── landing.page.ts # One POM per screen from screen-map.md ├── login.page.ts ├── dashboard.page.ts └── ... ``` --- ## State Updates After completing e2e generation: 1. Update `.spec2cloud/state.json` — set phase to `e2e-generation-complete` 2. Append to `.spec2cloud/audit.log`: ``` [TIMESTAMP] e2e-generation: Generated e2e specs for N flows [TIMESTAMP] e2e-generation: Generated N Page Object Models [TIMESTAMP] e2e-generation: All specs compile and are listed ✅ ``` 3. Commit all generated files with message: `[e2e-gen] scaffold e2e tests for all flows` ## Mandatory Completion Checklist The orchestrator MUST verify ALL of the following before marking e2e-generation as complete: - [ ] At least one Playwright spec file (`e2e/*.spec.ts`) exists for every user flow in `specs/ui/flow-walkthrough.md` - [ ] A Page Object Model (`e2e/pages/*.page.ts`) exists for every screen in `specs/ui/screen-map.md` - [ ] Every POM uses `data-testid` selectors from `specs/ui/component-inventory.md` (not CSS classes or XPath) - [ ] `e2e/playwright.config.ts` exists and is configured for the Aspire environment - [ ] All spec files compile successfully (`npx playwright test --list` returns all specs without errors) - [ ] Navigation flows between pages are tested (not just individual page interactions) - [ ] State JSON and audit log are updated **BLOCKING**: If any item is unchecked, the skill has NOT completed successfully. The orchestrator must loop back and complete the missing items before advancing to Gherkin generation.