# Phaser Test Seam Patterns

> Comprehensive guide to Phaser game test seam usage, including discovery, common commands, troubleshooting, and best practices. Use when testing Phaser games, interacting with canvas-rendered content, or when DOM-based testing fails. Test seams are the PRIMARY method for Phaser game testing - DOM text search does not work with canvas-rendered text.

- Skill: `pmarashian/phaser-test-seam-patterns` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add pmarashian/phaser-test-seam-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pmarashian/phaser-test-seam-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Product & Planning
- Author: pmarashian (https://skillmd.com/u/pmarashian)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/pmarashian/phaser-test-seam-patterns

---


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

```javascript
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 for `window.__TEST__` setup
- Look for `window.__TEST__.commands` in 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**

```bash
# ✅ 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**

```bash
# ✅ 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**

```bash
# ✅ 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**

```bash
# ✅ 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:

```bash
# ✅ 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**:

```bash
# 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**:
1. Document limitation in progress.txt
2. Proceed with alternative verification (code review, TypeScript compilation)
3. 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**:

```bash
# 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 initialization
- `window.__TEST__.commands = { ... }` - Command definitions
- `TestManager` - Centralized test seam management
- Scene `create()` methods - Where test seams are set up

### Technique 2: Browser Inspection

**Inspect test seam in browser**:

```bash
# 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**:

```bash
# 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 `TestManager` singleton 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**:

1. **Inspect structure**:
   ```bash
   agent-browser eval "Object.keys(window.__TEST__ || {})"
   ```

2. **List commands**:
   ```bash
   agent-browser eval "Object.keys(window.__TEST__?.commands || {})"
   ```

3. **Check function signatures**:
   ```bash
   agent-browser eval "window.__TEST__?.commands?.clickStartGame?.toString()"
   ```

4. **Document discovered API**:
   ```markdown
   ## 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**:

1. **Document limitation**:
   ```markdown
   ## Test Seam Limitation
   
   Test seam not available after 5 second timeout.
   Using alternative verification: TypeScript compilation + code review.
   ```

2. **Use alternative verification**:
   - TypeScript compilation check
   - Code review
   - DOM inspection (if applicable)
   - Screenshot comparison

3. **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 scene
- `movePlayerToExit()` - Complete level
- `setTimer(seconds)` - Manipulate timer
- `gameState()` - Access game state
- `collectAnyCoin()` - Test coin collection
- `simulateDragSlider()` - 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:**
```bash
# 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**:
- `sceneKey` may 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

1. **Use direct property access** - Prefer `window.__TEST__?.sceneKey` over polling `window.__TEST__?.ready`
2. **Prefer test seam over keyboard simulation** - More reliable and faster
3. **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
4. **Create test seam helpers** for common game actions
5. **Document test seam commands** in progress.txt when discovered
6. **Use console logs as fallback** when sceneKey doesn't update
7. **Use timeout handling** - Max 5 seconds before fallback
8. **Discover test seam API** - Use discovery techniques when API is unknown
9. **Graceful degradation** - Use alternative verification when test seams unavailable

## Workflow

1. Check for `window.__TEST__` availability
2. If not available, check source code for test seam setup
3. Document available commands
4. Use test seam commands for testing
5. Use console logs as fallback verification

## Resources

- `references/test-seam-discovery.md` - How to find and use test seams
- `references/common-commands.md` - Catalog of common test seam commands
- `references/drag-simulation.md` - Comprehensive guide to drag simulation patterns
- `references/troubleshooting.md` - Known issues and solutions

