/generate-uat
Generate a User Acceptance Test file from a feature specification.
Announce at start: "I'm using the /generate-uat skill to extract testable criteria from the spec."
Usage
/generate-uat <path-to-spec> [--format full|minimal] [--output <path>]
Examples:
- •
/generate-uat features/p61_events_complete_tech_spec.md - •
/generate-uat features/p70_new_feature.md --format minimal
What This Skill Does
- •Read the spec — Parse the entire specification file
- •Extract success criteria — Find testable statements from these sections (in priority order):
- •"Success Criteria"
- •"Acceptance Criteria"
- •"Requirements"
- •"User Stories"
- •Bullet points under "Goals" or "Objectives"
- •Categorize tests — Group by feature area and test type
- •Convert to Given/When/Then — Transform each criterion into a structured test
- •Generate scorecard — Create tracking table with checkboxes
- •Add ralph-loop instructions — Include execution guidance
- •Output — Save to
features/p{N}_uat.md(where N is the feature number from spec filename)
Process
Step 1: Read the Spec
Read the entire spec file provided as argument.
If no file path provided, ask:
Which spec file should I generate a UAT for? (e.g.,
features/p70_new_feature.md)
Step 2: Find Success Criteria
Search for sections containing testable criteria. Look for these headers (case-insensitive):
Explicit sections (highest priority):
- •
## Success Criteria - •
## Acceptance Criteria - •
## Requirements - •
### Tests
User story format:
As a [user], I want [action] so that [outcome] → Convert to: "User can [action]"
Requirements tables:
| Requirement | Priority | |-------------|----------| | Events have title | Must | → Convert to: "Events have title"
Implicit in description (lowest priority):
The events page shows upcoming events with title, date, and location. → Extract: "Events show title", "Events show date", "Events show location"
Step 3: Categorize Tests
Assign each criterion to a category based on keywords:
| Keywords in criterion | Category |
|---|---|
| table, column, migration, SQL, RLS, database | Database |
| page, render, display, show, UI, component, screen | UI |
| login, auth, session, permission, role, authenticated | Auth |
| API, endpoint, request, response, fetch | API |
| form, input, validation, submit, field | Forms |
| navigation, route, link, redirect, URL | Navigation |
| error, fail, invalid, edge case | Error Handling |
| test, unit, e2e, playwright | Testing |
If no keywords match, use "General".
Group tests by category, then number sequentially: UAT-{category}.{sequence}
Step 4: Convert to Given/When/Then
For each criterion, create a structured test:
### UAT-{N}.{M}: {Short description}
**Given:** {precondition/context}
**When:** {action (if applicable)}
**Then:** {expected outcome}
**Verify:** {how to verify - Playwright MCP, DB query, visual inspection, etc.}
Rules:
- •If criterion is a state (e.g., "Events table exists"), omit "When"
- •For UI tests, verification is typically "Playwright MCP screenshot"
- •For database tests, verification is "Run query in Supabase dashboard" or "npm run build"
- •For API tests, verification is "Playwright MCP network tab" or "curl command"
Step 5: Generate Output
Use this template:
# {Feature Name} — Acceptance Tests
**Purpose:** Testable acceptance criteria for {feature} implementation.
**Usage:** Ralph Loop iterates until ALL tests pass (score 100%).
**Source:** {spec_path}
**Generated:** {date}
**Generated by:** /generate-uat
---
## Test Scoring
\`\`\`
Score = passed_tests / {total} (shown as X/{total} or N%)
Total tests: {total}
Pass threshold: {total}/{total} (100% — all tests must pass)
\`\`\`
---
## Pre-Checks (must pass before UAT)
\`\`\`bash
npm run lint # No errors
npm run build # Compiles successfully
npm test # All unit tests pass
\`\`\`
---
{For each category}
## Category {N}: {Category Name} ({count} tests)
{For each test in category}
### UAT-{N}.{M}: {Short description}
**Given:** {precondition}
**When:** {action}
**Then:** {expected outcome}
**Verify:** {verification method}
{End for each test}
---
{End for each category}
## Test Execution Log
| Test | Status | Notes |
|------|--------|-------|
| UAT-1.1 | ⬜ | |
| UAT-1.2 | ⬜ | |
| ... | ... | ... |
**Legend:** ⬜ Not tested | ✅ Pass | ❌ Fail | ⏭️ Skipped (blocked — add note)
---
## Success Criteria
Ralph Loop completes when:
1. All {total} UAT tests show ✅
2. `./scripts/pre-commit-checks.sh` passes
3. No console errors during Playwright verification
Output `<promise>{Feature ID} UAT COMPLETE</promise>` when done.
---
## Notes for Agent
- **Use Playwright MCP** for visual verification
- **Use Chrome DevTools MCP** if network issues
- **Commit after each category passes** — Progress is preserved
- **Update scorecard** after each test — This file is your state
Step 6: Confirm and Save
Before saving, show the user:
- •Number of tests extracted: {N}
- •Categories: {list}
- •Output path:
features/p{N}_uat.md
Ask: "Does this look correct? Should I save the UAT file?"
If approved, save to features/p{N}_uat.md (or custom path if --output specified).
Options
| Flag | Default | Description |
|---|---|---|
--output <path> | features/p{N}_uat.md | Custom output path |
--format full | full | Include Given/When/Then for each test |
--format minimal | - | Scorecard table only (no detailed tests) |
Edge Cases
| Scenario | Behavior |
|---|---|
| Spec has no success criteria section | Warning: "No explicit success criteria found. Extracting from description. Review generated tests carefully." |
| Spec is too vague to extract tests | Error: "Couldn't extract testable criteria. Add a 'Success Criteria' section to the spec." |
| UAT file already exists | Ask: "UAT file exists at {path}. Overwrite / Merge / Cancel?" |
| Spec has 50+ criteria | Warning: "Large spec ({N} criteria). Consider breaking into smaller features." |
| Category has no tests | Skip the category, don't create empty sections |
Example Input → Output
Input spec excerpt:
## Success Criteria | Criteria | Threshold | How to Verify | |----------|-----------|---------------| | Unit tests | 100% pass | `npm test` | | Events persist on reload | Yes | Create event, refresh, still there | | Profile links work | Yes | Click attendee → `/p/:slug` loads |
Output UAT excerpt:
## Category 1: Testing (1 test) ### UAT-1.1: Unit tests pass **Given:** Code is implemented **Then:** `npm test` returns 0 exit code (100% pass) **Verify:** Run `npm test` in terminal --- ## Category 2: UI (2 tests) ### UAT-2.1: Events persist on reload **Given:** Event created in database **When:** Page is refreshed **Then:** Event still appears in list **Verify:** Playwright MCP navigation + screenshot ### UAT-2.2: Profile links work **Given:** Event has attendees **When:** User clicks attendee name **Then:** Navigates to `/p/:slug` and profile loads **Verify:** Playwright MCP click + URL check
Related Skills
- •
/prep-spec— Calls/generate-uatwhen ralph-loop is recommended - •
/loop— Consumes UAT files to execute tests iteratively
Validation
This skill was validated against the manually-created P61 acceptance tests:
The extraction rules were derived from patterns that would have correctly generated that file from the P61 spec.