## Context
If @.ralph/guides/AGENTS.md exists, study it for commands and patterns.
Study @.ralph/specs/$FEATURE.md for feature specification.
Study @.ralph/specs/$FEATURE-implementation-plan.md for E2E test scenarios.
{{#if frameworkVariant}}For detailed architecture, see @{{appDir}}/.claude/CLAUDE.md{{/if}}

## Learnings
Read @.ralph/LEARNINGS.md for E2E patterns and anti-patterns.
Pay special attention to "E2E Pitfalls" section to avoid known issues.

## Prerequisites
Before E2E testing, verify:
1. Build passes: `cd {{appDir}} && {{buildCommand}}`
2. All unit tests pass: `cd {{appDir}} && {{testCommand}}`
{{#unless isTui}}
3. Clear cache if issues: `rm -rf {{appDir}}/.next`
{{/unless}}

If either fails, fix issues before proceeding with E2E tests.

{{#if isTui}}
## Task
Execute automated E2E tests for the completed TUI feature using the xterm.js bridge and agent-browser.
Run ALL scenarios in a single session — do not end between scenarios.

### Step 1: Start Bridge
Check the bridge is running:
```bash
curl -s http://localhost:3999/health || (cd {{projectRoot}} && npm run e2e:bridge &)
sleep 3
curl -s http://localhost:3999/health
```

If bridge health still fails (for example `listen EPERM` / socket permission errors), do not keep retrying commands in this run:
- Mark each unchecked `- [ ] E2E:` scenario as `- [ ] E2E: ... - FAILED: bridge unavailable in sandbox`
- Add the concrete error text under each failed scenario
- Continue to Step 4 and record a clear blocked summary

### Step 2: Parse E2E Test Scenarios
Read E2E test scenarios from @.ralph/specs/$FEATURE-implementation-plan.md.
Each scenario is marked with `- [ ] E2E:` prefix and follows this format:

```
- [ ] E2E: [Scenario name]
  - **Command:** [wiggum command, e.g., init, new auth-flow]
  - **CWD:** [working directory, e.g., e2e/fixtures/bare-project]
  - **Steps:**
    1. [Action] -> [expected terminal output]
  - **Verify:** [text that should appear in terminal]
```

### Step 3: Execute Each Scenario

For each scenario:

1. **Open the TUI in the bridge:**
```bash
agent-browser open "http://localhost:3999?cmd=<command>&cwd=<path>"
```

2. **Wait for terminal ready:**
```bash
agent-browser wait --text "Ready" --source title --timeout 10000
```

3. **Read terminal content:**
```bash
agent-browser eval "document.getElementById('terminal-mirror').textContent"
```

4. **Interact with TUI:**
```bash
# Click to focus terminal
agent-browser snapshot -i
agent-browser click @<terminal-ref>

# Type text (Enter = press Enter after)
agent-browser type @<terminal-ref> "/help"
agent-browser key Enter

# Arrow navigation
agent-browser key ArrowDown
agent-browser key ArrowDown
agent-browser key Enter

# Escape
agent-browser key Escape
```

5. **Assert expected output:**
```bash
# Read terminal and check for expected text
CONTENT=$(agent-browser eval "document.getElementById('terminal-mirror').textContent")
# Verify CONTENT contains expected strings
```

6. **Reset between scenarios (without ending the browser session):**
```bash
# Re-open the next scenario URL directly in the same session.
agent-browser open "http://localhost:3999?cmd=<next-command>&cwd=<next-path>"
```

### TUI Interaction Cheatsheet

| Action | Command |
|--------|---------|
| Open TUI | `agent-browser open "http://localhost:3999?cmd=<cmd>&cwd=<path>"` |
| Read screen | `agent-browser eval "document.getElementById('terminal-mirror').textContent"` |
| Type/key press | `agent-browser type @ref "text"` / `agent-browser key Enter` |
| Close session | `agent-browser close` |

### Key Rules
- Always wait for expected text before asserting (TUI renders async via React)
- Use `agent-browser eval` with `terminal-mirror` for reliable text reading
- Take screenshots on failures for debugging
- Keep one browser session across all scenarios; do not call `agent-browser close` until all scenarios are done
- Each scenario should navigate to a fresh URL (clean state)
- Wait 500ms after key presses before reading (Ink re-render delay)

### Step 4: Report Results
Update @.ralph/specs/$FEATURE-implementation-plan.md for each scenario:

**Passed:**
```markdown
- [x] E2E: scenario name - PASSED
```

**Failed:**
```markdown
- [ ] E2E: scenario name - FAILED: [brief reason]
  - Error: [what went wrong]
  - Screenshot: [if captured]
  - Fix needed: [suggested action]
```

## Error Recovery

If a scenario fails:
1. Document the failure with specific error details
2. Take a screenshot: `agent-browser screenshot e2e-failure-<scenario>.png`
3. Note what fix is likely needed (code bug vs test spec issue)
4. Continue with remaining scenarios
5. At end, summary shows total passed/failed

Failures will trigger a fix iteration in the loop.

## Completion

When all scenarios are executed:
1. Update implementation plan with results for each scenario
2. Update the Implementation Summary status to `[PASSED]` if all passed
3. **Commit the updated implementation plan:**
   ```bash
   git -C {{appDir}} add -A && git -C {{appDir}} commit -m "test($FEATURE): E2E tests passed via agent-browser"
   ```
4. **Push to remote:**
   ```bash
   git -C {{appDir}} push origin feat/$FEATURE
   ```
5. If all passed: signal ready for PR phase
6. If any failed: failures documented, loop will retry after fix iteration
7. Close browser once at the end: `agent-browser close`

## Learning Capture
If useful E2E patterns found, append to @.ralph/LEARNINGS.md
{{else}}
## Task
Execute automated E2E tests for the completed feature using Playwright MCP tools.
Run ALL scenarios in a single session — do not end between scenarios.

### Step 1: Check Dev Server
Verify dev server is running at http://localhost:3000. If not accessible, start it:
```bash
cd {{appDir}} && {{devCommand}} &
```
Wait ~10 seconds for server startup, then verify with a simple browser_navigate.

{{#if hasSupabase}}### Step 1.5: Seed Test Data (if needed)

Check if test scenarios require specific data volumes (e.g., pagination needs >10 rows).

**Seeding with Supabase MCP:**
```
mcp__supabase__execute_sql
query: "INSERT INTO table_name (survey_id, data, created_at)
        SELECT '{survey_id}', '{"_test": true}'::jsonb, NOW() - (n || ' hours')::interval
        FROM generate_series(1, 25) n;"
```

**Mark test data for cleanup:**
- Add `"_test": true` to JSON data columns
- Use unique utm_source: `e2e_${FEATURE}_${timestamp}`

**Cleanup after tests:**
```
mcp__supabase__execute_sql
query: "DELETE FROM table_name WHERE data->>'_test' = 'true';"
```

**If seeding is impractical:** Document in implementation plan that E2E was skipped but unit tests provide coverage.
{{/if}}

### Step 2: Parse E2E Test Scenarios
Read E2E test scenarios from @.ralph/specs/$FEATURE-implementation-plan.md.
Each scenario is marked with `- [ ] E2E:` prefix and follows this format:

```
- [ ] E2E: [Scenario name]
  - **URL:** [starting URL]
  - **Preconditions:** [setup needed]
  - **Steps:**
    1. [Action] -> [expected result]
  - **Verify:** [final assertion]
  - **Database check:** [optional SQL]
```

### Step 3: Execute Each Scenario
For each E2E test scenario:

1. **Navigate** to starting URL:
   ```
   mcp__plugin_playwright_playwright__browser_navigate
   url: "http://localhost:3000/..."
   ```

2. **Capture page state** for element references:
   ```
   mcp__plugin_playwright_playwright__browser_snapshot
   ```
   This returns an accessibility tree with element refs (e.g., `button[3]`, `textbox[0]`).

3. **Execute actions** using refs from snapshot:
   - Click: `browser_click` with element description and ref
   - Type: `browser_type` with ref, text, and optionally `submit: true`
   - Fill form: `browser_fill_form` for multiple fields
   - Select: `browser_select_option` for dropdowns
   - Wait: `browser_wait_for` with text to appear/disappear

4. **Verify results**:
   - Call `browser_snapshot` to get current page state
   - Check that expected text/elements are present in the snapshot
   - Use `browser_wait_for` if async operations need time

5. **On failure**:
   - Take screenshot: `browser_take_screenshot`
   - Check console: `browser_console_messages` for JS errors
   - Document failure details

{{#if hasSupabase}}### Step 4: Database Verification
For scenarios with database checks, use Supabase MCP:
```
mcp__plugin_supabase_supabase__execute_sql
project_id: [project ID]
query: "SELECT * FROM survey_responses WHERE ..."
```

Verify returned data matches expected state.
{{/if}}

### Unique Test Data (for Parallel Execution)
When creating test data, use unique identifiers to avoid conflicts with other loops:
- Add feature-specific UTM params: `?utm_source=e2e_${FEATURE}_${timestamp}`
- Use unique names/emails: `test_${FEATURE}_${timestamp}@example.com`
- This ensures database queries find only this test's data

### Step 5: Report Results
Update @.ralph/specs/$FEATURE-implementation-plan.md for each scenario:

**Passed:**
```markdown
- [x] E2E: scenario name - PASSED
```

**Failed:**
```markdown
- [ ] E2E: scenario name - FAILED: [brief reason]
  - Error: [what went wrong]
  - Screenshot: [if captured]
  - Fix needed: [suggested action]
```

## Error Recovery

If a scenario fails:
1. Document the failure with specific error details
2. Note what fix is likely needed (code bug vs test spec issue)
3. Continue with remaining scenarios
4. At end, summary shows total passed/failed

Failures will trigger a fix iteration in the loop.

## Completion

When all scenarios are executed:
1. Update implementation plan with results for each scenario
2. Update the Implementation Summary status to `[PASSED]` if all passed
3. **Commit the updated implementation plan:**
   ```bash
   git -C {{appDir}} add -A && git -C {{appDir}} commit -m "test($FEATURE): E2E tests passed via Playwright"
   ```
4. **Push to remote:**
   ```bash
   git -C {{appDir}} push origin feat/$FEATURE
   ```
5. If all passed: signal ready for PR phase
6. If any failed: failures documented, loop will retry after fix iteration

## Rules
- Always get a fresh `browser_snapshot` after actions before making assertions
- Use `browser_wait_for` when waiting for async operations (form submission, API calls)
- Take screenshots only on failures to avoid clutter
- Verify database state for data-mutation features
- Keep scenarios independent when possible
- Document failures clearly so fix iteration knows what to address

## Learning Capture
If useful E2E patterns found, append to @.ralph/LEARNINGS.md
{{/if}}
