Browser Test Seam Optimization
Optimize browser testing workflows with test seams to reduce execution time by 40-50%. Reduces testing overhead from 30-60% of total time to 10-20%.
Overview
Problem: Sequential individual commands for each verification step (20-80 commands per task)
Solution: Composite test functions, command batching, and optimized wait strategies
Impact: Save 20-40 seconds per testing phase
Core Patterns
Pattern 1: Composite Test Functions
Instead of 10+ individual commands, create composite functions:
// ❌ INEFFICIENT: Multiple sequential commands
agent-browser eval "window.__TEST__.commands.clickStartGame()"
agent-browser wait 2000
agent-browser eval "window.__TEST__.commands.setTimer(5)"
agent-browser eval "window.__TEST__.commands.collectAnyCoin()"
agent-browser eval "window.__TEST__.gameState()"
// ✅ EFFICIENT: Composite test function
window.__TEST__.commands.testPlayAgainFlow = () => {
// Complete play again scenario in one call
this.scene.start('GameScene');
this.setTimer(5);
this.collectAnyCoin();
return this.gameState();
};
// Use composite function
agent-browser eval "window.__TEST__.commands.testPlayAgainFlow()"
Common composite functions:
// Test complete play again flow
window.__TEST__.commands.testPlayAgainFlow = () => {
this.scene.start('GameScene');
this.setTimer(5);
this.collectAnyCoin();
return this.gameState();
};
// Test level complete flow
window.__TEST__.commands.testLevelCompleteFlow = () => {
this.movePlayerToExit();
return this.gameState();
};
// Test scene transition
window.__TEST__.commands.testSceneTransition = (from, to) => {
this.scene.start(to);
return { from, to, sceneKey: this.scene.key };
};
// Test game state reset
window.__TEST__.commands.testGameStateReset = () => {
this.reset();
return this.gameState();
};
Pattern 2: Batch Independent Checks
Use Promise.all() for parallel evaluations:
// ❌ INEFFICIENT: Sequential checks
agent-browser eval "window.__TEST__.gameState().score"
agent-browser eval "window.__TEST__.gameState().timer"
agent-browser eval "window.__TEST__.gameState().player.x"
// ✅ EFFICIENT: Batch independent checks
agent-browser eval "
const state = window.__TEST__.gameState();
Promise.all([
Promise.resolve(state.score),
Promise.resolve(state.timer),
Promise.resolve(state.player.x)
]).then(results => ({
score: results[0],
timer: results[1],
playerX: results[2]
}))
"
Or simpler batching:
// ✅ EFFICIENT: Single eval for multiple checks
agent-browser eval "
const state = window.__TEST__.gameState();
JSON.stringify({
score: state.score,
timer: state.timer,
playerX: state.player?.x,
playerY: state.player?.y
})
"
Pattern 3: Optimize Wait Strategies
Use simple property checks instead of Promise polling:
// ❌ INEFFICIENT: Complex Promise polling
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.ready) {
resolve(true);
} else {
setTimeout(check, 100);
}
};
check();
})
"
// ✅ EFFICIENT: Simple property check
agent-browser eval "window.__TEST__?.ready || false"
Use timeout-based checks with max wait:
// ✅ EFFICIENT: Timeout-based check
agent-browser eval "
(() => {
const maxWait = 5000;
const start = Date.now();
while (Date.now() - start < maxWait) {
if (window.__TEST__?.ready) return true;
}
return false;
})()
"
Pattern 4: Test Seam Readiness Patterns
Check window.TEST?.sceneKey directly:
// ❌ INEFFICIENT: Promise-based polling
agent-browser eval "
new Promise((resolve) => {
const check = () => {
if (window.__TEST__?.sceneKey === 'GameScene') {
resolve(true);
} else {
setTimeout(check, 100);
}
};
check();
})
"
// ✅ EFFICIENT: Direct property check
agent-browser eval "window.__TEST__?.sceneKey === 'GameScene'"
Use Object.keys() for verification:
// ✅ EFFICIENT: Check command availability
agent-browser eval "
Object.keys(window.__TEST__?.commands || {}).includes('clickStartGame')
"
Complete Optimization Examples
Example 1: Test Play Again Flow
Before (Inefficient):
agent-browser eval "window.__TEST__.commands.clickStartGame()"
agent-browser wait 2000
agent-browser eval "window.__TEST__.commands.setTimer(5)"
agent-browser eval "window.__TEST__.commands.collectAnyCoin()"
agent-browser eval "window.__TEST__.gameState().score"
agent-browser eval "window.__TEST__.gameState().timer"
# 6 commands, ~12 seconds
After (Optimized):
# Single composite function call
agent-browser eval "
const result = window.__TEST__.commands.testPlayAgainFlow();
JSON.stringify(result)
"
# 1 command, ~2 seconds
Example 2: Verify State Changes
Before (Inefficient):
agent-browser eval "const before = window.__TEST__.gameState()"
agent-browser eval "window.__TEST__.commands.collectAnyCoin()"
agent-browser eval "const after = window.__TEST__.gameState()"
agent-browser eval "after.score > before.score"
# 4 commands, ~8 seconds
After (Optimized):
agent-browser eval "
const before = window.__TEST__.gameState();
window.__TEST__.commands.collectAnyCoin();
const after = window.__TEST__.gameState();
after.score > before.score
"
# 1 command, ~2 seconds
Example 3: Scene Navigation Testing
Before (Inefficient):
agent-browser eval "window.__TEST__.commands.goToScene('GameScene')"
agent-browser wait 2000
agent-browser eval "window.__TEST__.sceneKey"
agent-browser eval "window.__TEST__.gameState()"
# 4 commands, ~6 seconds
After (Optimized):
agent-browser eval "
window.__TEST__.commands.goToScene('GameScene');
setTimeout(() => {
const state = window.__TEST__.gameState();
return JSON.stringify({ scene: window.__TEST__.sceneKey, state });
}, 500)
"
# 1 command, ~1 second
Wait Strategy Optimization
Minimal Waits
Use minimal waits for known operations:
- Scene transitions: 500ms (not 2000ms)
- State checks: 100ms (not 500ms)
- DOM updates: 200ms (not 1000ms)
- Network requests: Poll until complete (not fixed wait)
// ❌ INEFFICIENT: Fixed 2-second wait
agent-browser eval "window.__TEST__.commands.clickStartGame()"
agent-browser wait 2000
// ✅ EFFICIENT: Minimal wait (500ms for scene transition)
agent-browser eval "window.__TEST__.commands.clickStartGame()"
agent-browser wait 500
Polling Instead of Fixed Waits
Use polling with timeout instead of fixed waits:
// ❌ INEFFICIENT: Fixed wait
agent-browser eval "window.__TEST__.commands.clickStartGame()"
agent-browser wait 2000 // May be too long or too short
// ✅ EFFICIENT: Poll for readiness
agent-browser eval "
(() => {
const maxWait = 5000;
const start = Date.now();
while (Date.now() - start < maxWait) {
if (window.__TEST__?.ready && window.__TEST__.sceneKey === 'GameScene') {
return true;
}
}
return false;
})()
"
Performance Impact
Before Optimization
- Command count: 20-80 commands per task
- Execution time: 30-60 seconds per testing phase
- Wait time: 2-5 seconds per wait operation
- Total overhead: 30-60% of task time
After Optimization
- Command count: 5-10 batched commands
- Execution time: 10-20 seconds per testing phase
- Wait time: 100-500ms per wait operation
- Total overhead: 10-20% of task time
Savings
- 50-70% reduction in command count
- 40-50% reduction in testing time
- 20-40 seconds saved per testing phase
Best Practices
- Create composite test functions for common flows
- Batch independent checks with Promise.all() or single eval
- Use simple property checks instead of Promise polling
- Minimize wait times (500ms for transitions, 100ms for checks)
- Check test seam readiness directly (window.TEST?.sceneKey)
- Group related verifications in single calls
- Use Object.keys() for command availability checks
Integration with Other Skills
- phaser-game-testing: Uses these optimization patterns
- browser-testing-efficiency: Complements with additional patterns
- agent-browser: Tool that benefits from optimization
Related Skills
phaser-game-testing- Phaser testing methodologybrowser-testing-efficiency- Additional browser testing patternsagent-browser- Browser automation tool
Remember
- Create composite functions for common flows
- Batch related commands in single eval calls
- Use minimal waits (500ms for transitions)
- Check properties directly (no Promise polling)
- Group verifications together
- Save 40-50% of testing time