重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
playwright-testing by chongdashu/phaserjs-oakwoods
npx skills add https://github.com/chongdashu/phaserjs-oakwoods --skill playwright-testing快速获得可靠信心:通过选择合适的测试层级、使应用可观察、消除非确定性,从而实现安全重构,让测试失败具有可操作性。
前端测试失败有两个原因:产品坏了,或者测试在撒谎。你的工作是最大化信号,最小化“测试撒谎”。
在编写测试前,请思考:
setTimeout,我可以等待什么“就绪”信号?核心原则:
选择能提供所需信心的最廉价层级:
| 层级 | 速度 | 用途 |
|---|---|---|
| 单元测试 | 最快 | 纯函数、reducer、验证器、数学、寻路、确定性模拟 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 组件测试 | 中等 | 使用模拟 IO 的 UI 行为(React Testing Library, Vue Testing Library) |
| 端到端测试 | 最慢 | 跨路由、存储、真实打包/运行时的关键用户流程 |
| 视觉测试 | 专用 | 布局/像素回归;对于 canvas/WebGL,仅在锁定确定性后使用 |
测试 Phaser/canvas 游戏的逐步流程:
1. mcp__playwright__browser_navigate
→ http://localhost:3000?test=1&seed=42
2. mcp__playwright__browser_evaluate
→ () => new Promise(r => { const c = () => window.__TEST__?.ready ? r(true) : setTimeout(c, 100); c(); })
(等待游戏就绪)
3. mcp__playwright__browser_console_messages
→ level: "error"
(如果有任何错误则失败)
4. mcp__playwright__browser_snapshot
→ 获取 UI 状态和引用
5. mcp__playwright__browser_click
→ element: "Start Button", ref: [from snapshot]
6. mcp__playwright__browser_evaluate
→ () => window.__TEST__.state()
(断言游戏状态正确)
7. mcp__playwright__browser_press_key
→ key: "ArrowRight" (或 WASD 用于移动)
8. mcp__playwright__browser_evaluate
→ () => window.__TEST__.state().player.x
(验证移动发生)
9. mcp__playwright__browser_take_screenshot
→ filename: "gameplay-state.png"
(确定性设置后的视觉证据)
为可测试性添加到应用中(只读、稳定、最小化):
window.__TEST__ = {
ready: false, // 在第一帧交互后变为 true
seed: null, // 当前 RNG 种子
sceneKey: null, // 当前场景/路由
state: () => ({ // JSON 可序列化的快照
scene: this.sceneKey,
player: { x, y, hp },
score: gameState.score,
entities: entities.map(e => ({ id: e.id, type: e.type, x: e.x, y: e.y }))
}),
commands: { // 可选的变更命令
reset: () => {},
seed: (n) => {},
skipIntro: () => {}
}
};
规则:暴露 ID + 关键字段,而非原始的 Phaser/引擎对象。
❌ 测试错误的层级:用端到端测试验证纯逻辑 为何诱人:“让我们通过浏览器测试所有东西” 更好的做法:逻辑用单元测试;端到端测试留给集成契约
❌ 测试实现细节:断言 DOM 结构/类名 为何诱人:断言在 DevTools 中能看到的东西很容易 更好的做法:断言对用户有意义的输出(文本、分数、HP 变化)
❌ 睡眠驱动的测试:等待 2 秒然后点击 为何诱人:简单且“在我的机器上有效” 更好的做法:等待明确的就绪信号(DOM 标记、window.__TEST__.ready)
❌ 不受控的随机性:断言中使用随机数/时间 为何诱人:“游戏使用随机,所以测试也应该用” 更好的做法:设定随机数种子(?seed=42)、冻结时间、断言稳定的不变量
❌ 没有确定性的像素快照:Canvas 截图不稳定 为何诱人:“我会自动捕获视觉错误” 更好的做法:先启用确定性模式;然后在已知的稳定帧截图
❌ 将重试作为策略:“把重试次数增加到 3 次” 为何诱人:让 CI 变绿的快速修复 更好的做法:修复不稳定的根源;重试掩盖了真正的问题
当测试失败时,按此顺序收集证据:
mcp__playwright__browser_console_messages({ level: "error" })mcp__playwright__browser_network_requests() → 检查非 2xx 状态码mcp__playwright__browser_take_screenshot() → 失败时的视觉状态mcp__playwright__browser_evaluate({ function: "() => window.__TEST__.state()" })最低可行的测试套件:
window.__TEST__)?test=1 启用种子设定)何时升级:
用于截图的像素比较:
# 比较基准与当前
python scripts/imgdiff.py baseline.png current.png --out diff.png
# 允许小的容差(抗锯齿差异)
python scripts/imgdiff.py baseline.png current.png --max-rms 2.0
退出码:0 = 相同,1 = 不同,2 = 错误
Canvas UI 问题(面板接缝、分段带状条、不可见的 HUD 填充)最好通过专用的 UI 测试工具捕获,而不是完整的游戏流程。
test.html/场景,仅加载 UI 资源。window.__TEST__ 及其 .commands.showTest(n),以便 Playwright 可以确定性地切换每种模式。有关确定性设置 + 截图工作流,请参见 references/phaser-canvas-testing.md。
根据上下文调整方法:
window.__TEST__.ready 等待references/phaser-canvas-testing.md)。需要时阅读:
references/playwright-mcp-cheatsheet.md:详细的 MCP 工具模式references/phaser-canvas-testing.md:Phaser 游戏的确定性模式references/flake-reduction.md:不稳定因素分类和修复方法你可以通过添加一个微小、稳定的接缝用于就绪状态 + 状态,使几乎任何前端(包括 canvas/WebGL 游戏)变得可测试。一个可靠的冒烟测试是基础。目标是维护起来枯燥的测试:确定性的、明确就绪状态的、失败时证据丰富的。目标是信心,而不是覆盖率数字。
每周安装量
51
仓库
GitHub Stars
54
首次出现
Jan 24, 2026
安全审计
安装于
opencode44
gemini-cli38
cursor36
codex35
github-copilot33
claude-code29
Unlock reliable confidence fast: enable safe refactors by choosing the right test layer, making the app observable, and eliminating nondeterminism so failures are actionable.
Frontend tests fail for two reasons: the product is broken, or the test is lying. Your job is to maximize signal and minimize "test is lying".
Before writing a test, ask :
setTimeout?Core principles :
Pick the cheapest layer that provides needed confidence:
| Layer | Speed | Use For |
|---|---|---|
| Unit | Fastest | Pure functions, reducers, validators, math, pathfinding, deterministic simulation |
| Component | Medium | UI behavior with mocked IO (React Testing Library, Vue Testing Library) |
| E2E | Slowest | Critical user flows across routing, storage, real bundling/runtime |
| Visual | Specialized | Layout/pixel regressions; for canvas/WebGL, only after locking determinism |
Step-by-step sequence for testing a Phaser/canvas game:
1. mcp__playwright__browser_navigate
→ http://localhost:3000?test=1&seed=42
2. mcp__playwright__browser_evaluate
→ () => new Promise(r => { const c = () => window.__TEST__?.ready ? r(true) : setTimeout(c, 100); c(); })
(Wait for game ready)
3. mcp__playwright__browser_console_messages
→ level: "error"
(Fail if any errors)
4. mcp__playwright__browser_snapshot
→ Get UI state and refs
5. mcp__playwright__browser_click
→ element: "Start Button", ref: [from snapshot]
6. mcp__playwright__browser_evaluate
→ () => window.__TEST__.state()
(Assert game state is correct)
7. mcp__playwright__browser_press_key
→ key: "ArrowRight" (or WASD for movement)
8. mcp__playwright__browser_evaluate
→ () => window.__TEST__.state().player.x
(Verify movement happened)
9. mcp__playwright__browser_take_screenshot
→ filename: "gameplay-state.png"
(Visual evidence after deterministic setup)
Add to the app for testability (read-only, stable, minimal):
window.__TEST__ = {
ready: false, // true after first interactive frame
seed: null, // current RNG seed
sceneKey: null, // current scene/route
state: () => ({ // JSON-serializable snapshot
scene: this.sceneKey,
player: { x, y, hp },
score: gameState.score,
entities: entities.map(e => ({ id: e.id, type: e.type, x: e.x, y: e.y }))
}),
commands: { // optional mutation commands
reset: () => {},
seed: (n) => {},
skipIntro: () => {}
}
};
Rule : Expose IDs + essential fields, not raw Phaser/engine objects.
❌ Testing the wrong layer : E2E tests for pure logic Why tempting : "Let's just test everything through the browser" Better : Unit tests for logic; reserve E2E for integration contracts
❌ Testing implementation details : Asserting DOM structure/classnames Why tempting : Easy to assert what you can see in DevTools Better : Assert user-meaningful outputs (text, score, HP changes)
❌ Sleep-driven tests : wait 2s then click Why tempting : Simple and "works on my machine" Better : Wait on explicit readiness (DOM marker, window.__TEST__.ready)
❌ Uncontrolled randomness : RNG/time in assertions Why tempting : "The game uses random, so the test should too" Better : Seed RNG (?seed=42), freeze time, assert stable invariants
❌ Pixel snapshots without determinism : Canvas screenshots that flake Why tempting : "I'll catch visual bugs automatically" Better : Deterministic mode first; then screenshot at known stable frames
❌ Retries as a strategy : "Just bump retries to 3" Why tempting : Quick fix that makes CI green Better : Fix the flake source; retries hide real problems
When a test fails, gather evidence in this order:
mcp__playwright__browser_console_messages({ level: "error" })mcp__playwright__browser_network_requests() → check for non-2xxmcp__playwright__browser_take_screenshot() → visual state at failuremcp__playwright__browser_evaluate({ function: "() => window.__TEST__.state()" })Minimum viable test suite:
window.__TEST__ with ready flag and state)?test=1 enables seeding)Level up when:
For pixel comparison of screenshots:
# Compare baseline to current
python scripts/imgdiff.py baseline.png current.png --out diff.png
# Allow small tolerance (anti-aliasing differences)
python scripts/imgdiff.py baseline.png current.png --max-rms 2.0
Exit codes: 0 = identical, 1 = different, 2 = error
Canvas UI issues (panel seams, segmented ribbons, invisible HUD fills) are best caught with a dedicated UI harness instead of the full gameplay flow.
test.html/scene that loads only the UI assets.window.__TEST__ with .commands.showTest(n) so Playwright can toggle each mode deterministically.See references/phaser-canvas-testing.md for the deterministic setup + screenshot workflow.
Adapt approach based on context:
window.__TEST__.readyreferences/phaser-canvas-testing.md).Read these when needed:
references/playwright-mcp-cheatsheet.md: Detailed MCP tool patternsreferences/phaser-canvas-testing.md: Deterministic mode for Phaser gamesreferences/flake-reduction.md: Flake classification and fixesYou can make almost any frontend (including canvas/WebGL games) testable by adding a tiny, stable seam for readiness + state. One reliable smoke test is the foundation. Aim for tests that are boring to maintain: deterministic, explicit about readiness, and rich in failure evidence. The goal is confidence, not coverage numbers.
Weekly Installs
51
Repository
GitHub Stars
54
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode44
gemini-cli38
cursor36
codex35
github-copilot33
claude-code29
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
52,700 周安装