game-qa について
ブラウザーゲーム向けのPlaywright QAスキルです。ゲームプレイ、画面、性能、アクセシビリティのテストパターンに加え、検査用にゲーム状態を公開する方法を紹介します。
主な機能
- 01ゲームプレイとスコアのテストパターン
- 02スクリーンショット回帰テスト
- 03性能とFPSの確認
- 04axeによるアクセシビリティテスト
- 05ゲーム状態の検査フック
- 06モバイル入力のテストパターン
活用シーン
- 01ゲームシーンとプレイヤー入力の検証
- 02画面変更前後のスクリーンショット確認
- 03性能基準とアクセシビリティのテスト
- 04状態データによるゲーム動作の検査
MCP 対応
付属ガイドでは、MCPサーバーの設定とスクリプトテストではなくMCPを使う場面を説明しています。視覚評価にMCPを使う方法も記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ hungify/ playables-skills --skill game-qaインストール後、Claude Code で/game-qaを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
clock-control.mdgameplay-invariants.mditerate-client.mdmobile-tests.mdplaywright-mcp.mdtest-patterns.mdvisual-regression.md詳細
Playwright によるゲーム QA
ブラウザーゲームを専門とする QA エンジニアです。Playwright を使用して、ビジュアルの正確性、ゲームプレイの動作、パフォーマンス、アクセシビリティを検証する自動テストを作成します。
パフォーマンスに関する注意事項
- 各手順には十分な時間をかけてください。速度より品質が重要です。
- 検証手順を省略しないでください。問題を早期に発見できます。
- 変更を加える前に、各ファイルの全体を確認してください。
- ページが読み込まれることだけでなく、ゲームプレイを検証するテストを作成してください。
参考ファイル
詳細については、このディレクトリにある関連ファイルを参照してください。
test-patterns.md— カスタムフィクスチャコード、起動テスト、ゲームプレイ検証テスト、スコアリングテストgameplay-invariants.md— 7 つの主要なゲームプレイ不変条件パターンすべて(スコアリング、死亡、ボタン、render_game_to_text、デザイン意図、エンティティ監査、ミュート)visual-regression.md— スクリーンショット比較テスト、動的要素のマスキング、パフォーマンス/FPS テスト、アクセシビリティテスト、決定論的テストのパターンclock-control.md— フレーム単位で正確なテストを行うための Playwright Clock API パターンplaywright-mcp.md— MCP サーバーのセットアップ、MCP とスクリプトによるテストの使い分け、検査フローiterate-client.md— スタンドアロンの iterate クライアントの使い方、アクション JSON 形式、出力の解釈mobile-tests.md— モバイル入力のシミュレーションとレスポンシブレイアウトのテストパターン
技術スタック
- テストランナー:Playwright Test(
@playwright/test) - ビジュアルリグレッション:Playwright 標準の
toHaveScreenshot() - アクセシビリティ:
@axe-core/playwright - ビルドツールとの統合:
webServer設定による Vite 開発サーバー - 言語:JavaScript ES モジュール
プロジェクトのセットアップ
ゲームプロジェクトに Playwright を追加する場合:
npm install -D @playwright/test @axe-core/playwright
npx playwright install chromium
package.json のスクリプトに追加します。
{
"scripts": {
"test": "npx playwright test",
"test:ui": "npx playwright test --ui",
"test:headed": "npx playwright test --headed",
"test:update-snapshots": "npx playwright test --update-snapshots"
}
}
必須のディレクトリ構成
tests/
├── e2e/
│ ├── game.spec.js # Core game tests (boot, scenes, input, score)
│ ├── visual.spec.js # Visual regression screenshots
│ └── perf.spec.js # Performance and FPS tests
├── fixtures/
│ ├── game-test.js # Custom test fixture with game helpers
│ └── screenshot.css # CSS to mask dynamic elements for visual tests
├── helpers/
│ └── seed-random.js # Seeded PRNG for deterministic game behavior
playwright.config.js
Playwright の設定
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [['html', { open: 'never' }], ['list']],
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure'
},
expect: {
toHaveScreenshot: {
maxDiffPixels: 200,
threshold: 0.3
}
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'mobile-chrome', use: { ...devices['Pixel 5'] } }
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 30000
}
});
重要なポイント:
webServerはテストの前に Vite を自動起動します。reuseExistingServerはローカルで実行中の開発サーバーを再利用します。baseURLはvite.config.jsで設定された Vite のポートに合わせます。- スクリーンショットの許容差は大きめに設定します(ゲームでは描画にわずかな差が生じるため)。
テスト可能にするための要件
Playwright でゲームの状態を検査できるように、ゲームは main.js 内で次のグローバル変数を window に公開する必要があります。
1. コアグローバル変数(必須)
// Expose for Playwright QA
window.__GAME__ = game;
window.__GAME_STATE__ = gameState;
window.__EVENT_BUS__ = eventBus;
window.__EVENTS__ = Events;
2. render_game_to_text()(必須)
AI エージェントがピクセルを解釈せずにゲームの状態を把握できるよう、現在のゲーム状態を簡潔な JSON 文字列で返します。座標系、ゲームモード、スコア、プレイヤーの状態を含める必要があります。
window.render_game_to_text = () => {
if (!game || !gameState) return JSON.stringify({ error: 'not_ready' });
const activeScenes = game.scene.getScenes(true).map((s) => s.scene.key);
const payload = {
coords: 'origin:top-left x:right y:down', // coordinate system
mode: gameState.gameOver ? 'game_over' : 'playing',
scene: activeScenes[0] || null,
score: gameState.score,
bestScore: gameState.bestScore
};
// Add player info when in gameplay
const gameScene = game.scene.getScene('GameScene');
if (gameState.started && gameScene?.player?.sprite) {
const s = gameScene.player.sprite;
const body = s.body;
payload.player = {
x: Math.round(s.x),
y: Math.round(s.y),
vx: Math.round(body.velocity.x),
vy: Math.round(body.velocity.y),
onGround: body.blocked.down
};
}
// Extend with visible entities as you add them:
// payload.entities = obstacles.map(o => ({ x: o.x, y: o.y, type: o.type }));
return JSON.stringify(payload);
};
render_game_to_text() のガイドライン:
- ペイロードは簡潔に保ちます。現在表示されている、操作可能な要素のみを含めます。
- 座標系の注記(原点と軸の方向)を含めます。
- プレイヤーの位置/速度、アクティブな障害物/敵、収集アイテム、タイマー、スコア、モードフラグを含めます。
- 大量の履歴は避け、現在関連する情報のみを含めます。
- iterate クライアントと AI エージェントは、スクリーンショットを使わずにゲームの動作を検証するためにこれを使用します。
3. advanceTime(ms)(必須)
テストスクリプトでゲームを正確な時間だけ進められるようにします。ゲームループは RAF で通常どおり実行され、実時間が経過するまで待機します。
window.advanceTime = (ms) => {
return new Promise((resolve) => {
const start = performance.now();
function step() {
if (performance.now() - start >= ms) return resolve();
requestAnimationFrame(step);
}
requestAnimationFrame(step);
});
};
@playwright/test でフレーム単位の正確な制御を行うには、page.clock.install() と page.clock.runFor() を使用してください。advanceTime フックは主にスタンドアロンの iterate クライアント(scripts/iterate-client.js)で使われます。
Three.js ゲームの場合も、同様に Game オーケストレーターのインスタンスを公開してください。
カスタムフィクスチャコード、起動テスト、ゲームプレイ検証テスト、スコアリングテストについては、test-patterns.md を参照してください。
7 つの主要なゲームプレイ不変条件パターンすべて(スコアリング、死亡、ボタン、render_game_to_text、デザイン意図、エンティティ監査、ミュート)については、gameplay-invariants.md を参照してください。
ゲームに QA を追加する場合
- Playwright をインストールします:
npm install -D @playwright/test @axe-core/playwright && npx playwright install chromium - ゲームの開発サーバーのポートを指定して
playwright.config.jsを作成します main.jsでwindow.__GAME__、window.__GAME_STATE__、window.__EVENT_BUS__を公開しますgamePageフィクスチャを含むtests/fixtures/game-test.jsを作成します- 決定論的な動作を実現するために
tests/helpers/seed-random.jsを作成します tests/e2e/にテストを記述します:game.spec.js— 起動、シーン遷移、入力、スコアリング、ゲームオーバーvisual.spec.js— 各シーンのスクリーンショット回帰テストperf.spec.js— 読み込み時間、FPS の予算
- npm スクリプトを追加します:
test、test:ui、test:headed、test:update-snapshots - 初期ベースラインを生成します:
npm run test:update-snapshots
自動テストの対象にしないもの
- アニメーションするオブジェクトの正確なピクセル位置(クロックを制御しないと非決定的になります)
- ゲームプレイ中のスクリーンショット — オブジェクトが動くため、安定したスクリーンショットを撮影できません。代わりに MCP を使用します
- 音声の再生(Playwright では音声を検査できません。evaluate を使って音声オブジェクトが存在することをテストします)
- モック化していない外部 API 呼び出し(例:Play.fun SDK —
page.route()でモック化します) - 主観的なビジュアル品質 — 「見栄えがよいか」の評価には MCP を使用します