Phaser Test Seam Patterns
Overview
Test seams (window.__TEST__) are the PRIMARY method for testing Phaser games. DOM-based interactions (text search, keyboard simulation) do not work reliably with canvas-rendered content.
Discovery
Always check for test seam before attempting DOM interactions:
if (window.__TEST__ && window.__TEST__.commands) {
// Test seam available - use it
} else {
// Test seam not available - check source code or add it
}
Where to find test seams:
- Check scene
create()methods forwindow.__TEST__setup - Look for
window.__TEST__.commandsin scene files - Document discovered commands in progress.txt
Direct Property Access Patterns (Preferred)
Prefer Direct Property Checks Over Polling
PREFERRED: Use direct property checks instead of polling readiness flags
# ✅ CORRECT: Direct property check (immediate)
agent-browser eval "window.__TEST__?.sceneKey === 'GameScene'"
agent-browser eval "window.__TEST__?.commands?.clickStartGame"
# ❌ INEFFICIENT: Polling readiness flag
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.ready) {
resolve(true);
} else {
setTimeout(check, 100);
}
};
check();
})
"
Why Direct Property Access is Better:
- Immediate check: No polling delay
- More reliable: Readiness flags may not be reliable
- Simpler code: No Promise chains
- Faster execution: No async overhead
Direct Property Access Examples
Example 1: Check Scene Key
# ✅ CORRECT: Direct property check
agent-browser eval "window.__TEST__?.sceneKey || 'unknown'"
# ❌ INEFFICIENT: Polling ready flag
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.ready) {
resolve(window.__TEST__.sceneKey);
} else {
setTimeout(check, 100);
}
};
check();
})
"
Example 2: Check Command Availability
# ✅ CORRECT: Direct property check
agent-browser eval "Object.keys(window.__TEST__?.commands || {}).includes('clickStartGame')"
# ❌ INEFFICIENT: Polling ready flag
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.ready) {
resolve('clickStartGame' in window.__TEST__.commands);
} else {
setTimeout(check, 100);
}
};
check();
})
"
Example 3: Get Game State
# ✅ CORRECT: Direct property check
agent-browser eval "window.__TEST__?.gameState?.() || null"
# ❌ INEFFICIENT: Polling ready flag
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.ready) {
resolve(window.__TEST__.gameState());
} else {
setTimeout(check, 100);
}
};
check();
})
"
Readiness Flag Reliability
Important: window.__TEST__?.ready may not be reliable. Prefer direct property checks:
# ✅ PREFERRED: Direct property check
agent-browser eval "window.__TEST__?.sceneKey || false"
agent-browser eval "Object.keys(window.__TEST__?.commands || {}).length > 0"
# ⚠️ LESS RELIABLE: Readiness flag
agent-browser eval "window.__TEST__?.ready || false"
When Readiness Flags May Not Work:
- Scene transitions (flag may lag)
- Complex initialization (flag may not update)
- Test seam setup issues (flag may not be set)
Solution: Use direct property checks instead
Timeout Handling
Include timeout handling (max 5 seconds) before fallback:
# Timeout-based check with direct property access
check_test_seam_with_timeout() {
local max_wait=5 # 5 seconds max
local elapsed=0
while [ $elapsed -lt $max_wait ]; do
# Direct property check (not polling ready flag)
if agent-browser eval "window.__TEST__?.sceneKey || false"; then
echo "Test seam available"
return 0
fi
sleep 1
elapsed=$((elapsed + 1))
done
echo "Test seam not available after $max_wait seconds"
return 1
}
If test seam isn't available after timeout:
- Document limitation in progress.txt
- Proceed with alternative verification (code review, TypeScript compilation)
- Don't wait indefinitely - test seams may not be available in all contexts
Discovery Techniques
Technique 1: Source Code Search
Search for test seam setup in source code:
# Search for test seam setup
grep -r "window.__TEST__" src/
grep -r "__TEST__\.commands" src/
grep -r "TestManager" src/
# Search for scene create methods
grep -r "create\(\)" src/scenes/
What to look for:
window.__TEST__ = { ... }- Test seam initializationwindow.__TEST__.commands = { ... }- Command definitionsTestManager- Centralized test seam management- Scene
create()methods - Where test seams are set up
Technique 2: Browser Inspection
Inspect test seam in browser:
# Check if test seam exists
agent-browser eval "typeof window.__TEST__ !== 'undefined'"
# List available commands
agent-browser eval "Object.keys(window.__TEST__?.commands || {})"
# Check current scene
agent-browser eval "window.__TEST__?.sceneKey"
# Get full test seam structure
agent-browser eval "JSON.stringify(window.__TEST__, null, 2)"
Technique 3: Console Log Discovery
Use console logs to discover test seam:
# Check console for test seam logs
agent-browser console | grep -i "test\|__TEST__"
# Look for initialization logs
agent-browser console | grep -i "test seam\|testmanager"
Technique 4: Framework-Specific Discovery
Phaser 3 Games:
- Check scene files for
window.__TEST__setup - Look for
TestManagersingleton pattern - Check
create()methods for test seam initialization
React/Web Apps:
- Check component files for test seam setup
- Look for test utilities or test helpers
- Check for test mode flags (
?test=1)
Technique 5: Unknown Test Seam API Discovery
When test seam API is unknown:
Inspect structure:
agent-browser eval "Object.keys(window.__TEST__ || {})"List commands:
agent-browser eval "Object.keys(window.__TEST__?.commands || {})"Check function signatures:
agent-browser eval "window.__TEST__?.commands?.clickStartGame?.toString()"Document discovered API:
## Test Seam API Discovery **Available Commands**: - clickStartGame() - No parameters - setTimer(seconds) - Takes number parameter - gameState() - Returns object **Documented in**: progress.txt
Graceful Degradation When Test Seams Unavailable
If test seams aren't available:
Document limitation:
## Test Seam Limitation Test seam not available after 5 second timeout. Using alternative verification: TypeScript compilation + code review.Use alternative verification:
- TypeScript compilation check
- Code review
- DOM inspection (if applicable)
- Screenshot comparison
Proceed with caution:
- Note limitation in progress.txt
- Assess risk of incomplete verification
- Document fallback method used
Common Commands
See references/common-commands.md for a catalog of common test seam commands.
Typical commands include:
clickStartGame()- Navigate to game scenemovePlayerToExit()- Complete levelsetTimer(seconds)- Manipulate timergameState()- Access game statecollectAnyCoin()- Test coin collectionsimulateDragSlider()- Simulate dragging sliders (Settings scene)
Drag Simulation
For testing Phaser UI components that use pointer events (sliders, draggable objects), use drag simulation commands.
Quick Start:
# Drag music slider from 0% to 100%
agent-browser eval "window.__TEST__.commands.simulateDragSlider('music', 0, 1, 10)"
Why drag simulation?
- Programmatic value setting bypasses drag interaction flow
- Errors that only occur during dragging cannot be reproduced without simulation
- Tests actual pointer event handling (
pointerdown,pointermove,pointerup)
See references/drag-simulation.md for comprehensive guide to drag simulation patterns, including:
- Test seam drag commands (recommended)
- Agent-browser mouse command patterns
- Coordinate conversion considerations
- Best practices and troubleshooting
Known Issues
See references/troubleshooting.md for detailed troubleshooting.
Key issues:
sceneKeymay lag on scene transitions (use console logs as fallback)- Test seams are created per-scene in
create()method - Wait for scene initialization before accessing test seam
Best Practices
- Use direct property access - Prefer
window.__TEST__?.sceneKeyover pollingwindow.__TEST__?.ready - Prefer test seam over keyboard simulation - More reliable and faster
- Prefer standalone component test scenes for UI - Test Phaser UI components in dedicated scenes (one scene per component, booted via
?scene=...) rather than only on the full game/scene page; see phaser-component-test-scenes skill - Create test seam helpers for common game actions
- Document test seam commands in progress.txt when discovered
- Use console logs as fallback when sceneKey doesn't update
- Use timeout handling - Max 5 seconds before fallback
- Discover test seam API - Use discovery techniques when API is unknown
- Graceful degradation - Use alternative verification when test seams unavailable
Workflow
- Check for
window.__TEST__availability - If not available, check source code for test seam setup
- Document available commands
- Use test seam commands for testing
- Use console logs as fallback verification
Resources
references/test-seam-discovery.md- How to find and use test seamsreferences/common-commands.md- Catalog of common test seam commandsreferences/drag-simulation.md- Comprehensive guide to drag simulation patternsreferences/troubleshooting.md- Known issues and solutions