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

6.8 KiB

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

# 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:

// 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

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!