- Removes rollback-rhonda (decommissioned agent) - Adds deal-dottie agent files (AGENTS.md, mcp.json) - Updates .paperclip.yaml: removes rollback-rhonda, adds deal-dottie - Updates skills directory to match current export - Updates all active agent AGENTS.md files and memory/life files Co-Authored-By: Paperclip <noreply@paperclip.ing>
24 KiB
CTO UAT Playbook — CartSnitch
Owner: Savannah Savings (CTO) Last updated: 2026-03-30 Purpose: Single source of truth for all UAT test knowledge. Rhonda never reads this file. CTO uses it to create atomic task descriptions.
1. Environment Reference
| Item | Value |
|---|---|
| Dev URL | https://cartsnitch.dev.farh.net |
| Production URL | https://cartsnitch.farh.net — NEVER test here |
| Playwright MCP | playwright at http://playwright:8931/mcp |
| Mobile viewport | 375 x 812 (iPhone — mobile-first PWA) |
| Auth provider | Authentik at https://auth.farh.net |
2. Test Data
| Item | Value |
|---|---|
| Seed user email | uat@cartsnitch.com |
| Seed user password | CartSnitch-UAT-2026! |
| Registration email pattern | uat+{timestamp}@cartsnitch.com |
| Registration password | CartSnitch-UAT-2026! (meets strength requirements) |
| Registration display name | UAT Test |
3. User Journey Catalog
| ID | Area | Key Checks | Fragile? |
|---|---|---|---|
| J1 | Playwright Connectivity | browser_navigate to about:blank succeeds |
No |
| J2 | Environment Health | Dev loads, CartSnitch UI renders, no critical JS errors | Yes |
| J3 | Registration (happy path) | Form renders, POST returns 2xx, redirect works | Yes |
| J4 | Registration (validation) | Empty fields, bad email, weak password show errors | Yes |
| J5 | Registration (duplicate) | Same email twice shows proper error, not crash | Yes |
| J6 | Login (new account) | POST returns 2xx, session active, dashboard renders | Yes |
| J7 | Login (seed user) | uat@cartsnitch.com works, API returns 2xx |
Yes |
| J8 | Login (invalid creds) | Wrong password/email shows error, not crash | Yes |
| J9 | Session Persistence | Refresh page, still logged in | Yes |
| J10 | Forgot Password | Form renders, submit shows confirmation, API 2xx | No |
| J11 | Dashboard | Renders sections, no JS errors, mobile layout OK | No |
| J12 | Purchases | List or empty state, API 2xx | No |
| J13 | Purchase Detail | Detail page renders, API 2xx | No |
| J14 | Products | Catalog or empty state, API 2xx | No |
| J15 | Product Detail | Details render, price history visible | No |
| J16 | Store Comparison | Comparison data renders | No |
| J17 | Coupons | List or empty state, API 2xx | No |
| J18 | Alerts | List or empty state, API 2xx | No |
| J19 | Settings | Page renders, all tabs/sections work | No |
| J20 | Account Linking | Page renders, interactive elements work | No |
| J21 | Logout | Redirect to login or landing page | No |
| J22 | Access Control | All protected routes redirect when logged out | Yes |
| J23 | Navigation | Bottom nav works, back button works, no 404s | No |
| J24 | Console Error Audit | Session-accumulated errors documented | No |
4. Journey Details
J1: Playwright Connectivity
Preconditions: None (first test always)
Steps:
- Call
browser_navigatewith urlabout:blank - PASS: Page loads without error
If PASS: Proceed to J2. If FAIL: Block task. Comment: "Playwright MCP server unreachable — cannot perform UAT. Error: {exact error}." Assign to CTO with status todo.
J2: Environment Health
Preconditions: J1 passed
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net - PASS: Page loads (no DNS failure, no timeout, no 5xx)
- Call
browser_snapshot - PASS: Page contains recognizable CartSnitch UI (navigation, header, or login form)
- Call
browser_console_messages - PASS: No critical JS errors (Uncaught TypeError, ChunkLoadError, React render errors)
- Call
browser_take_screenshot
If PASS: Proceed to auth tests. If FAIL at step 2 (hard failure): Block task. Comment with exact error, URL, screenshot if partial load. Assign to CTO with status todo. If FAIL at step 4 (blank page): Take screenshot, capture console errors, block task. If FAIL at step 6 (JS errors but page loads): Note errors, continue testing, report as medium severity.
J3: Registration (happy path) [KNOWN FRAGILE]
Preconditions: J2 passed. Not logged in. 3 production escapes: CAR-126, CAR-128, CAR-147.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/register - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Registration form visible with name/display_name, email, and password fields
- Call
browser_fill_formwith: email =uat+{timestamp}@cartsnitch.com, password =CartSnitch-UAT-2026!, name/display_name =UAT Test - Call
browser_clickon the submit/register button - Call
browser_network_requests - PASS: POST to registration endpoint returned HTTP 2xx (not 4xx or 5xx)
- Call
browser_snapshot - PASS: User redirected to dashboard or login page, no error message visible
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Registration happy path. API returned 2xx. Screenshot attached." Mark done. If FAIL at step 8 (API error): This is CRITICAL. Comment: "Registration API returned {status code}. Auth contract may be broken. See CAR-126/CAR-128/CAR-147 history." Assign to CTO with status todo. If FAIL at step 10 (visual): Comment with screenshot and what was expected vs actual. Assign to CTO with status todo.
Note for CTO (decomposition): Always record the email used so subsequent login tasks can reference it.
J4: Registration (validation errors)
Preconditions: J2 passed. On /register page.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/register - Call
browser_resizewith width 375, height 812 - Call
browser_clickon submit button (empty fields) - Call
browser_snapshot - PASS: Field-level error messages visible
- Call
browser_fill_formwith email =notanemail, password =x, name =T - Call
browser_clickon submit button - Call
browser_snapshot - PASS: Validation errors for malformed email and/or weak password
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Registration validation errors display correctly." Mark done. If FAIL: Comment with which validation was missing and screenshot. Assign to CTO with status todo.
J5: Registration (duplicate email)
Preconditions: J3 passed (an account was created with a known email).
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/register - Call
browser_resizewith width 375, height 812 - Call
browser_fill_formwith the SAME email used in J3, password =CartSnitch-UAT-2026!, name =Duplicate Test - Call
browser_clickon submit button - Call
browser_network_requests - PASS: API returned an error status (409 or 422 expected, not 500)
- Call
browser_snapshot - PASS: User-friendly error message about duplicate email (not a crash, not a generic "something went wrong")
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Duplicate registration handled correctly." Mark done. If FAIL (500 or crash): CRITICAL. Comment with API response and screenshot. Assign to CTO with status todo.
J6: Login (new account) [KNOWN FRAGILE]
Preconditions: J3 passed (fresh account exists).
Steps:
- If logged in, navigate to logout first, then:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/login - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Login form visible with email and password fields
- Call
browser_fill_formwith email = (email from J3), password =CartSnitch-UAT-2026! - Call
browser_clickon login/submit button - Call
browser_network_requests - PASS: POST to login endpoint returned HTTP 2xx
- Call
browser_snapshot - PASS: Redirected to dashboard, authenticated state visible (user name/avatar, or logout button)
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Login with new account. API returned 2xx. Dashboard loaded." Mark done. If FAIL at step 9 (API error): CRITICAL. Comment: "Login API returned {status}. Credentials were valid (account created in J3)." Assign to CTO with status todo.
J7: Login (seed user) [KNOWN FRAGILE]
Preconditions: J2 passed. Logged out.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/login - Call
browser_resizewith width 375, height 812 - Call
browser_fill_formwith email =uat@cartsnitch.com, password =CartSnitch-UAT-2026! - Call
browser_clickon login/submit button - Call
browser_network_requests - PASS: POST to login endpoint returned HTTP 2xx
- Call
browser_snapshot - PASS: Dashboard renders, authenticated state visible
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Seed user login. API returned 2xx." Mark done. If FAIL at step 6 (API error): HIGH. Seed user may not exist in dev. Comment: "Seed user login failed, API returned {status}." Assign to CTO with status todo.
J8: Login (invalid credentials)
Preconditions: J2 passed. Logged out.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/login - Call
browser_resizewith width 375, height 812 - Call
browser_fill_formwith email =uat@cartsnitch.com, password =WrongPassword123! - Call
browser_clickon login/submit button - Call
browser_snapshot - PASS: Error message visible (not a crash, not a blank page, not a redirect to dashboard)
- Call
browser_fill_formwith email =nonexistent@cartsnitch.com, password =CartSnitch-UAT-2026! - Call
browser_clickon login/submit button - Call
browser_snapshot - PASS: Error message visible
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Invalid login attempts show proper error messages." Mark done. If FAIL: Comment with what happened instead. Assign to CTO with status todo.
J9: Session Persistence
Preconditions: Logged in (from J6 or J7).
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/settings - Call
browser_snapshot - PASS: Settings page renders (user is still authenticated)
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/ - Call
browser_snapshot - PASS: Dashboard renders (still authenticated after navigation)
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/(page refresh) - Call
browser_snapshot - PASS: Still authenticated after refresh (session persists)
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Session persists across navigation and page refresh." Mark done. If FAIL (session lost): HIGH. Comment: "Session did not persist. After {step}, user was logged out." Assign to CTO with status todo.
J10: Forgot Password
Preconditions: J2 passed. On login page or can navigate there.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/forgot-password - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Forgot password form renders with email field
- Call
browser_fill_formwith email =uat@cartsnitch.com - Call
browser_clickon submit button - Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_snapshot - PASS: Confirmation message visible (e.g., "Check your email")
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Forgot password flow works. API returned 2xx." Mark done. If FAIL: Comment with which step failed. Assign to CTO with status todo.
J11: Dashboard
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/ - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Dashboard renders with expected sections (not blank, not error page)
- Call
browser_console_messages - PASS: No critical JS errors
- PASS: No horizontal overflow, no overlapping elements at 375px width
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Dashboard renders correctly at mobile viewport." Mark done. If FAIL: Comment with what's broken and screenshot. Assign to CTO with status todo.
J12: Purchases Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/purchases - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Purchase list or empty state renders
- Call
browser_network_requests - PASS: API call for purchases returned 2xx
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Purchases page renders. API returned 2xx." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J13: Purchase Detail
Preconditions: Logged in. J12 passed.
Steps:
- If purchases exist from J12, click into one. If no purchases exist, skip this journey.
- Call
browser_snapshot - PASS: Purchase detail page renders with receipt/order information
- Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_take_screenshot
If ALL PASS (or skipped due to no data): Comment: "UAT PASS — Purchase detail renders." or "SKIP — No purchases to test." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J14: Products Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/products - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Product catalog or empty state renders
- Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Products page renders. API returned 2xx." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J15: Product Detail
Preconditions: Logged in. J14 passed.
Steps:
- If products exist from J14, click into one. If no products, skip.
- Call
browser_snapshot - PASS: Product detail renders with price information
- Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_take_screenshot
If ALL PASS (or skipped): Comment accordingly. Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J16: Store Comparison
Preconditions: Logged in. Product exists.
Steps:
- If a "Compare" link or
/compare/{productId}is accessible from J15, navigate there. If not, skip. - Call
browser_snapshot - PASS: Comparison data renders
- Call
browser_take_screenshot
If ALL PASS (or skipped): Comment accordingly. Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J17: Coupons Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/coupons - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Coupon list or empty state renders
- Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Coupons page renders. API returned 2xx." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J18: Alerts Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/alerts - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Alerts list or empty state renders
- Call
browser_network_requests - PASS: API returned 2xx
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Alerts page renders. API returned 2xx." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J19: Settings Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/settings - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Settings page renders
- Click any visible tabs or sections
- Call
browser_snapshot - PASS: Tab/section content loads
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Settings page renders, tabs work." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J20: Account Linking Page
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/account-linking - Call
browser_resizewith width 375, height 812 - Call
browser_snapshot - PASS: Account linking page renders (store connection UI or empty state)
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Account linking page renders." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J21: Logout
Preconditions: Logged in.
Steps:
- Call
browser_snapshotto identify logout button/link - Call
browser_clickon the logout element - Call
browser_snapshot - PASS: Redirected to login page or public landing page
- PASS: No authenticated UI elements visible
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Logout works, redirected to login." Mark done. If FAIL: Comment with details. Assign to CTO with status todo.
J22: Access Control (Unauthenticated)
Preconditions: Logged out (J21 passed).
Protected routes to test:
/purchases/products/coupons/alerts/settings/account-linking/(dashboard/root)
Steps (repeat for each route):
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/{route} - Call
browser_snapshot - PASS: Redirected to login page (not a blank page, not the actual protected content, not an error)
After all routes tested:
4. Call browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — All protected routes redirect to login when unauthenticated." Mark done.
If ANY route accessible without auth: HIGH severity. Comment: "Protected route /{route} is accessible without authentication." Assign to CTO with status todo.
J23: Navigation
Preconditions: Logged in.
Steps:
- Call
browser_navigatetohttps://cartsnitch.dev.farh.net/ - Call
browser_resizewith width 375, height 812 - Call
browser_snapshotto identify bottom nav / sidebar menu items - Click each navigation item one by one
- After each click, call
browser_snapshot - PASS: Each target page loads (no 404, no blank page)
- Call
browser_navigate_backseveral times - Call
browser_snapshot - PASS: App state is consistent after back navigation (no broken state)
- Call
browser_take_screenshot
If ALL PASS: Comment: "UAT PASS — Navigation works correctly at mobile viewport." Mark done. If FAIL: Comment with which nav item or back action failed. Assign to CTO with status todo.
J24: Console Error Audit
Preconditions: Last test — run after all other journeys.
Steps:
- Call
browser_console_messages - Review all accumulated errors from the session
- Document any:
Uncaughterrors,Failed to fetch,NetworkError,ChunkLoadError, React rendering errors - PASS: No undocumented critical errors exist
- If >5 unique console errors across session: note as MEDIUM severity
If PASS: Comment: "UAT PASS — Console audit. {N} unique errors found: {summary}." Mark done. If new critical errors found: Comment with full list. Assign to CTO with status todo.
5. Known Fragile Areas
| Area | History | Risk | Extra Verification |
|---|---|---|---|
| Authentication (registration + login) | 3 escapes: CAR-126 (basePath mismatch), CAR-128 (auth client config), CAR-147 (API contract mismatch) | Silent API failures behind working UI | Always check browser_network_requests for 2xx. A rendered form with a broken backend is a false positive. |
| Frontend/API contract | CAR-147: frontend sent wrong field name, expected wrong response shape | Fields renamed without frontend update | After every form submission, verify the POST/PUT returned 2xx via browser_network_requests. |
| Dev environment availability | CAR-127 (dev doesn't load), CAR-52 (CrashLoopBackOff) | Pods not running, image pull failures | Always run J1+J2 first. Never assume dev is healthy. |
| Auth service deployment | CAR-39 (image doesn't exist), CAR-141 (wrong env var) | Auth service up but misconfigured | Verify login actually works at the API level, not just that the form renders. |
6. Severity Definitions
| Severity | Definition | Blocks UAT? |
|---|---|---|
| critical | Core flow broken, app unusable. Login crashes, registration API returns 500, app won't load. | Yes |
| high | Major feature non-functional, security flaw. Protected routes accessible without auth, session doesn't persist, page shows wrong data. | Yes |
| medium | Feature degraded but usable. Slow load (>5s), unclear validation message, mobile layout broken, >5 console warnings. | No (warning) |
| low | Cosmetic. Typo, slight alignment, missing hover state. | No (warning) |
7. Defect Report Template
### Defect: {short description}
- **Severity:** critical | high | medium | low
- **Journey:** J{N} — {name}
- **Known Fragile Area:** yes/no
- **Steps to reproduce:**
1. {step}
2. {step}
- **Expected:** {what should happen}
- **Actual:** {what happened}
- **API response:** {status code from browser_network_requests, or N/A}
- **Console errors:** {from browser_console_messages, or none}
- **Screenshot:** attached
8. Decomposition Guide
Standard 5-Slot Pattern Per Deploy
| Slot | Subtask | Source Journeys | When |
|---|---|---|---|
| 1 | Playwright + environment readiness | J1 + J2 | Always first |
| 2 | Auth verification | J3-J10 (subset based on scope) | Always — auth is fragile |
| 3 | Feature-specific tests | J{scope} based on PR | Based on what changed |
| 4 | Navigation + access control smoke | J21 + J22 + J23 | Every deploy |
| 5 | Console error audit | J24 | Always last |
Sizing
- Small/targeted PR (e.g., auth fix, single page fix): 3-5 subtasks
- Medium PR (e.g., new feature, multi-page change): 5-8 subtasks
- Large PR (e.g., major refactor, auth overhaul): 8-12 subtasks
- Full regression (major release, post-infra change): All 24 journeys as individual tasks
Scope-Based Journey Selection
| Change Type | Required Journeys |
|---|---|
| Auth service change | J1-J10, J21-J22, J24 |
| Frontend-only change | J1-J2, J11-J20, J23-J24 |
| Full deployment (both services) | J1-J24 (all) |
| Infrastructure change | J1-J2, J7, J11, J24 (health + smoke) |
| Single page fix (e.g., /coupons) | J1-J2, J7, J{page}, J23-J24 |
Dependency Chains
- J3 creates account used by J5, J6
- J6 or J7 must pass before J9, J11-J20 (need authenticated session)
- J21 must run before J22 (need logged-out state)
- J24 is always last (aggregates session errors)
Parallelization
After auth (J3-J10) passes, page tests J11-J20 can run as independent parallel tasks (each logs in independently). J21-J23 should run sequentially after page tests.
Task Description Template
Every subtask CTO creates for Rhonda follows this format:
## What
{One sentence: specific test to run}
## Steps
1) Call `browser_navigate` to {url}
2) Call `browser_resize` with width 375, height 812
3) Call `browser_snapshot` — PASS: {what should be visible}
4) Call `browser_fill_form` with {exact fields and values}
5) Call `browser_click` on {exact element}
6) Call `browser_network_requests` — PASS: {endpoint} returned {expected status}
7) Call `browser_snapshot` — PASS: {expected visual state}
8) Call `browser_take_screenshot`
**If ALL PASS:** Mark issue done. Post comment: "UAT PASS — {journey name}. {key detail}. Screenshot attached."
**If ANY FAIL:** Set status todo. Assign to CTO (22731e25-f40f-48bd-a16e-28e1bbef5946). Post comment: "UAT FAIL — Step {N} failed. Expected: {X}. Actual: {Y}. Screenshot attached."
Rules for task descriptions:
- Every step is a single Playwright MCP tool call
- Inline PASS criteria after every verification step
- Include exact field values, URLs, credentials
- No references to external documents — task is fully self-contained
- No conditional logic — if auth fails in a page test, just report the failure
- No severity assessment — CTO determines severity from the report
9. Maturation Log
Track playbook changes here after each UAT cycle.
| Date | Change | Reason |
|---|---|---|
| 2026-03-30 | Initial playbook created | CAR-198: UAT overhaul |