mantimon-tcg/TESTING.md
Cal Corum 0d416028c0
Fix prize zone rendering in Mantimon TCG mode (#2)
* Fix hand card rotation direction

Cards now fan outward correctly instead of curling inward

* Update StateRenderer to require MatchScene type for type safety

- Change constructor parameter from Phaser.Scene to MatchScene
- Update scene property type to MatchScene
- Add import for MatchScene type
- Update JSDoc example to reflect type-safe constructor

* Defer Board creation to StateRenderer for correct rules config

- Make board property nullable (Board | null instead of Board?)
- Remove Board and createBoard imports (now handled by StateRenderer)
- Update setupBoard() to skip Board creation
- Add setBoard() method for StateRenderer to call
- Update clearBoard() to use null instead of undefined
- Add JSDoc explaining why Board creation is deferred

* Create Board in StateRenderer with correct layout options

- Add Board and createBoard imports
- Add board property to StateRenderer
- Create Board in render() on first call with correct rules_config
- Add debug logging for Board creation and zone creation
- Update clear() to destroy Board when clearing
- Board now created after we have rules_config from first state

* Add fatal error handling with toast notification and auto-redirect

- Add 'fatal-error' event to GameBridgeEvents type
- Import and initialize useToast in GamePage
- Listen for 'fatal-error' event from Phaser
- Show error toast that persists until redirect
- Show full-screen fatal error overlay with countdown
- Auto-redirect to /play after 3 seconds
- Update StateRenderer to emit 'fatal-error' when Board creation fails

* Gate debug logging with DEV flag

- Add DEBUG_RENDERER constant gated by import.meta.env.DEV
- Update all console.log statements in StateRenderer to only log in development
- Keep console.error and console.warn as they are (always show errors)
- Debug logs now only appear during development, not in production

* Fix code audit issues - add missing imports and improve error UX

Critical fixes:
- Add missing gameBridge import to StateRenderer (fixes runtime error in fatal error handler)
- Add missing Board type import to MatchScene (fixes TypeScript compilation error)

UX improvements:
- Replace fatal error auto-redirect with manual 'Return to Menu' button
- Add toast notification when resignation fails
- Give users unlimited time to read fatal errors before returning

Addresses issues found in frontend code audit:
- errors.missing-import (StateRenderer.ts:166)
- errors.missing-type-import (MatchScene.ts:84)
- errors.catch-only-console (GamePage.vue:145)
- architecture.missing-fatal-error-handling (GamePage.vue:261)

* Add CONTRIBUTING policy and fix pre-existing lint/test errors

- Add CONTRIBUTING.md with strict policy: never use --no-verify without approval
- Add comprehensive testing documentation (TESTING.md, VISUAL-TEST-GUIDE.md)
- Add test-prize-fix.md quick test checklist and verify-fix.sh script

Lint fixes (enables pre-commit hooks):
- Remove unused imports in 9 files
- Fix unused variables (underscore convention)
- Replace 'as any' type assertions with proper VisibleGameState types
- Add missing CARD_WIDTH_MEDIUM import in layout.spec.ts
- All ESLint errors now resolved (only acceptable warnings remain)

Test fixes (all 1000 tests now passing):
- Fix layout.spec.ts: Add missing CARD_WIDTH_MEDIUM import
- Fix PlayPage.spec.ts: Update test to use actual hardcoded UUIDs
- Fix useAuth.spec.ts: Mock API profile fetch in initialization tests
- Fix PhaserGame.spec.ts: Add scenes export to mock and update createGame call expectations

This ensures pre-commit hooks work properly going forward and prevents
bypassing TypeScript/lint checks that catch errors early.

* Add comprehensive test coverage improvement plan

- Create PROJECT_PLAN_TEST_COVERAGE.json with 25 structured tasks
- Create TEST_COVERAGE_PLAN.md with executive summary and roadmap
- Plan addresses critical gaps: game engine (0%), WebSocket (27%)
- 6-week roadmap to reach 85% coverage from current 63%
- Target: Phase 1 (weeks 1-3) - critical game engine and network tests
- Includes quick wins, production blockers, and success metrics

Based on coverage analysis showing:
- Strong: Composables (84%), Components (90%), Stores (88%)
- Critical gaps: Phaser game engine (~5,500 untested lines)
- High priority: WebSocket/multiplayer reliability

See TEST_COVERAGE_PLAN.md for overview and week-by-week breakdown.

* Add coverage tooling and ignore coverage directory

- Add @vitest/coverage-v8 package for coverage analysis
- Add coverage/ directory to .gitignore
- Used during test coverage analysis for PROJECT_PLAN_TEST_COVERAGE.json
2026-02-02 15:30:27 -06:00

308 lines
6.8 KiB
Markdown

# Testing Guide: Prize Zone Fix
Branch: `fix/defer-board-creation-until-state`
## What Was Fixed
**Bug:** Prize zone rectangles (2x3 grid) were appearing even when `use_prize_cards: false` (Mantimon TCG points mode).
**Root Cause:** Board was created during scene initialization before WebSocket state arrived, using default `usePrizeCards: true`.
**Fix:** Defer Board creation until StateRenderer receives first game state with correct `rules_config`.
---
## Quick Start
```bash
# Terminal 1: Start backend
cd backend && uv run uvicorn app.main:app --reload
# Terminal 2: Start frontend
cd frontend && npm run dev
# Terminal 3: Ensure Docker services running
docker-compose up -d
```
Open: `http://localhost:5173`
---
## Test 1: Visual Verification (CRITICAL)
**Game:** `/game/f6f158c4-47b0-41b9-b3c2-8edc8275b70c` (or any Mantimon mode game)
### What to Look For:
**BEFORE FIX (Bug):**
```
+-----------------+
| Opp Active |
| Opp Bench |
| [P][P] <---- Prize rectangles (WRONG!)
| [P][P]
| [P][P]
+-----------------+
| My Active |
| My Bench |
| [P][P] <---- Prize rectangles (WRONG!)
| [P][P]
| [P][P]
+-----------------+
```
**AFTER FIX (Correct):**
```
+-----------------+
| Opp Active |
| Opp Bench |
| (no prizes) | <---- CORRECT!
+-----------------+
| My Active |
| My Bench |
| (no prizes) | <---- CORRECT!
+-----------------+
```
### Expected Board Layout (Mantimon Mode):
```
Top (Opponent):
- Active Zone (1 large rectangle, center-top)
- Bench Slots (5 rectangles, horizontal row)
- Deck (small rectangle, top-right)
- Discard (small rectangle, next to deck)
- Energy Deck (small rectangle, top-left)
- Hand (row of card backs, very top)
Bottom (You):
- Active Zone (1 large rectangle, center-bottom)
- Bench Slots (5 rectangles, horizontal row)
- Deck (small rectangle, bottom-right)
- Discard (small rectangle, next to deck)
- Energy Deck (small rectangle, bottom-left)
- Hand (fanned cards, very bottom)
```
**What should NOT be there:**
- ❌ 2x3 grid of small rectangles (prize cards)
- ❌ Any 6-rectangle groups
- ❌ Empty bordered boxes on the left/right sides
---
## Test 2: Console Verification
Open DevTools Console (F12), look for these logs:
### ✅ CORRECT Logs:
```
[StateRenderer] Creating board with layout options: {
usePrizeCards: false, ← Should be FALSE
prizeCount: 4,
benchSize: 5,
energyDeckEnabled: true
}
[StateRenderer] ✓ Board created successfully
[StateRenderer] Creating zones with rules: {
usePrizeCards: false, ← Should be FALSE
energyDeckEnabled: true,
benchSize: 5
}
```
### ❌ WRONG Logs (indicates bug):
```
[StateRenderer] Creating board with layout options: {
usePrizeCards: true, ← WRONG! Should be false
...
}
```
---
## Test 3: Loading Overlay
1. Refresh the game page
2. Watch the loading sequence
**Expected:**
1. "Connecting to game..." overlay appears instantly
2. Overlay stays for 1-3 seconds
3. Overlay disappears, board is fully rendered
4. **No visual flash or flicker** of wrong state
**Bug would be:** Brief flash of prize rectangles before they disappear
---
## Test 4: Fatal Error Handling
### Setup (Temporary):
Edit `frontend/src/game/sync/StateRenderer.ts`, line 154:
```typescript
// Add this line temporarily:
throw new Error('Test fatal error')
this.board = createBoard(this.scene, this.layout)
```
### Test Steps:
1. Refresh game page
2. Observe error handling
### Expected:
- ✅ Toast appears (bottom-right): "Failed to initialize game board: Test fatal error"
- ✅ Full-screen overlay appears:
- Red error icon
- "Failed to initialize game board"
- "The game cannot continue. Please return to the menu."
- Blue "Return to Menu" button
-**NO auto-redirect** (wait 10+ seconds to verify)
- ✅ Click button → redirects to `/play`
### Console Expected:
```
[StateRenderer] ✗ Failed to create board: Error: Test fatal error
[GamePage] Fatal error from Phaser: {
message: 'Failed to initialize game board',
error: 'Test fatal error',
context: 'StateRenderer.render()'
}
```
### Cleanup:
**IMPORTANT:** Remove the `throw new Error()` line after testing!
---
## Test 5: Resign Failure Toast
### Setup:
1. Start a game
2. Open DevTools → Network tab → Set to "Offline"
### Test Steps:
1. Click exit button (X, top-right)
2. Click "Resign and Leave"
### Expected:
- ✅ Toast appears: "Could not confirm resignation with server. Leaving game anyway."
- ✅ Still redirects to `/play` (doesn't get stuck)
- ✅ Console: `[GamePage] Failed to resign: ...`
### Cleanup:
Turn network back to "Online"
---
## Test 6: TypeScript Compilation
```bash
cd frontend
npm run typecheck
```
### Expected Output:
```
> mantimon-tcg-frontend@0.1.0 typecheck
> vue-tsc --noEmit
✓ No errors
```
**Bug would be:**
```
error TS2304: Cannot find name 'gameBridge'
error TS2304: Cannot find name 'Board'
```
---
## Test 7: Classic Mode (Prize Cards Enabled)
**Note:** This requires a game with `use_prize_cards: true` in backend rules.
### Expected:
- ✅ 6 prize zone rectangles ARE visible (2x3 grid, left side)
- ✅ Same for opponent (top-left)
### Console Should Show:
```
[StateRenderer] Creating board with layout options: {
usePrizeCards: true, ← Should be TRUE for classic mode
prizeCount: 6,
...
}
```
---
## Test 8: Multiple Games
1. Play game 1 (Mantimon mode)
2. Exit
3. Start game 2 (any mode)
### Expected:
- ✅ Game 1: No prize rectangles
- ✅ Exit works cleanly
- ✅ Game 2: Board matches its rules
- ✅ No leftover visual artifacts
### Console Should Show:
```
[StateRenderer] Board destroyed ← From game 1
[StateRenderer] Creating board... ← For game 2
[StateRenderer] ✓ Board created successfully
```
---
## Pass/Fail Criteria
### ✅ ALL TESTS PASS IF:
1. **Visual:** No prize rectangles in Mantimon mode games
2. **Console:** `usePrizeCards: false` in logs
3. **Loading:** No visual flash of wrong state
4. **Fatal Error:** Manual button, no auto-redirect
5. **Resign:** Toast appears on failure
6. **TypeScript:** No compilation errors
7. **Classic Mode:** Prize rectangles appear when enabled
8. **Multiple Games:** Clean transitions
### ❌ FIX FAILED IF:
- Prize rectangles visible when `use_prize_cards: false`
- Console shows `usePrizeCards: true` for Mantimon games
- Fatal error auto-redirects after 3 seconds
- TypeScript compilation errors
---
## Reporting Issues
If any test fails, report:
1. **Which test failed**
2. **What you saw** (screenshot preferred)
3. **Console logs** (copy full output)
4. **Game ID** you tested with
5. **Browser** and version
---
## Success Criteria Summary
**The fix is working if:**
✓ No prize zone rectangles appear in your test game
✓ Console shows `usePrizeCards: false`
✓ Board renders correctly after loading overlay
✓ Fatal error requires manual button click
✓ TypeScript compiles without errors
**Ready for merge if all tests pass!**