UI 検証手順 (webapp_client / templates) — ローカル検証フロー
UI 改修時にローカル検証を必ず実施するためのガイドライン。CLAUDE.md「変更時テスト」表の詳細手順を本ファイルに集約。
適用範囲
| 対象 | 検証フロー |
|---|---|
webapp_client/src/**/*.{ts,tsx,css} (Vite SPA) | 本ガイド §1〜§4 |
templates/*.html (GAS Web App) | 本ガイド §5 |
§1. type-check (必須)
cd webapp_client
npm run type-check
tsc --noEmit で型エラーを検出。0 件でなければ次に進まない。
§2. snapshot test で regression 検知 (必須)
cd webapp_client
npm run test:ui
webapp_client/tests/cockpit-visual.spec.ts (Playwright + visual snapshot) を実行。既存スナップショットとの差分があれば失敗。
GitHub Actions の .github/workflows/ui-test.yml も同じ spec を PR 時に自動実行する (本ステップで先行検知することで PR fail を防ぐ)。
snapshot mismatch が意図した変更の場合
npm run test:ui:update # 新しい snapshot で上書き
git add webapp_client/tests/**/*.png
git commit -m "test(ui): snapshot 更新 (理由: <理由>)"
意図しない mismatch は実装バグ。snapshot 上書きで隠蔽してはいけない。
§3. 新規動作には新規 spec を追加 (動作変更がある場合)
新機能・新挙動の検証は**webapp_client/tests/ に Playwright spec を追加**する。/tmp/ への ad-hoc スクリプトは禁止 (再現性なし・CI 連携なし・後続セッションが利用不可)。
spec 雛形
// webapp_client/tests/<feature>.spec.ts
import { test, expect } from '@playwright/test';
test('<feature> が期待通り動作する', async ({ page }) => {
await page.goto('/financial_cockpit.html');
await page.waitForLoadState('networkidle');
// クリック・入力等の操作
await page.click('text=月次財務諸表');
// DOM 状態を計測 (computed style / 属性 / テキスト)
const stickyZIndex = await page.evaluate(() => {
const el = document.querySelector('thead .pl-col-num--sticky');
return getComputedStyle(el).zIndex;
});
expect(stickyZIndex).toBe('3');
// または visual snapshot
await expect(page).toHaveScreenshot('<feature>.png');
});
playwright.config.ts の webServer 設定により npm run test:ui 時に dev サーバが自動起動する (port 5173 既定)。
§4. dev サーバでブラウザ目視 (視覚確認が必要な場合のみ)
snapshot だけでは UX が確認できない場合 (アニメーション・スクロール挙動・体感的な使いやすさ) に限定。
cd webapp_client
npm run dev:cockpit # cockpit ターゲット (financial_cockpit)
# または
npm run dev:multiyear # multiyear ターゲット
npm run dev # sidebar ターゲット
ブラウザで http://localhost:5173/financial_cockpit.html 等を開く。
port 競合 (5173 が使用中) の対処
Vite は自動で次の port (5174, 5175, ...) に切替えるが、Claude が混乱するので明示的に port を指定するのが安全:
npm run dev:cockpit -- --port 5173 --strictPort
--strictPort で port 競合時はエラー終了 → 既存プロセスを kill してから再実行する。
Claude Code セッション内での目視
Claude Code 自身はブラウザを操作できない (ヘッドレス環境)。open コマンドで実機ブラウザを起動する手段はあるが、視覚確認は人間に依頼するのが正しい。Claude は npm run test:ui で snapshot 比較するか、Playwright で computed style を検査することで代替する。
人間確認ゲート (必須)
UI 変更がある場合、Claude は以下のフローを厳守する:
- 実装完了後、dev サーバを起動し、確認 URL を人間に提示
例: dev サーバを起動しました。 http://localhost:5173/financial_cockpit.html を開き、 「月次タブで通期列が sticky 固定されている」ことを確認してください。 OK / NG をお知らせください。 - 人間から OK 受領を確認するまで
git pushおよび PR 作成を実施しない - NG の場合は修正 → ① に戻る (修正→確認のループ)
- 段階的修正中は
git commit(ローカル) は OK だが、git pushは OK 受領後のみ
なぜ必要か
npm run test:uiの snapshot pass = 既存挙動の自動退行検知 のみ。新機能・新挙動の妥当性は判定できない- type-check pass = 型エラーなし のみ。視覚的・UX 的な妥当性とは無関係
- Playwright での computed style 検査 = Claude が予測した DOM 状態の検証のみ。人間が期待する見え方 とは別物
- 結果として 新機能・新挙動の最終承認は人間目視のみ が信頼できる
Claude が暴走しないためのチェックリスト
git push 前に Claude 自身が確認すべき:
- UI 変更がある場合、人間に「OK / NG」を尋ねたか
- 人間から 明示的な OK を受領したか (snapshot pass や type-check pass を OK と誤認していないか)
- NG が来た場合、修正後に再度 OK を尋ねたか
このチェックを通過しない限り、git push および mcp__github__create_pull_request を呼ばない。
§5. templates/*.html (GAS Web App) の検証
templates/financial_cockpit.html multiyear_cockpit.html *_sidebar.html 等は GAS Web App 経由で配信される。Vite dev サーバでは動作しない (GAS API バインディング google.script.run が未定義のため)。
検証フロー
npm run push:dev # 開発用 GAS にデプロイ
その後、開発用 GAS の Web App /exec URL をブラウザで開いて目視確認。Env.isDev() が true の状態で挙動を確認する。
prod URL への直接 push は permissions.deny でブロック済 (scripts/hooks/pre_bash_guard.sh 参照)。
§6. 共通の地雷・避けるべきパターン
| パターン | 問題 | 対処 |
|---|---|---|
/tmp/verify*.mjs で ad-hoc Playwright | 再現性なし、CI 未連携 | webapp_client/tests/ に spec として追加 |
| Playwright を絶対パスで import | 環境依存・他マシンで動かない | webapp_client/ 内で npx playwright test を使う |
open コマンドで GUI 起動 | headless 環境で失敗、Claude 検証不可 | snapshot test or computed style 検査 |
| port 5173/5174 を場当たり的に切替 | 確認 URL の不一致 | --strictPort で明示的に管理 |
| snapshot mismatch を上書きで隠蔽 | 退行を見逃す | mismatch の原因を分析、意図的なら理由付きで update |
§7. CI との関係
.github/workflows/ui-test.ymlが PR 時にnpm run test:uiを自動実行する (webapp_client/src/**webapp_client/tests/**の変更で発火)- ローカル検証 = PR 時 CI で fail することを事前に防ぐための前段チェック
- 「ローカルで通った」≠「CI で通る」(OS / browser version 差異あり) ので CI 結果も必ず確認する
関連ドキュメント
CLAUDE.md「変更時テスト」表 — 本ガイドへの参照元webapp_client/playwright.config.ts— Playwright 設定の正準ソース.github/workflows/ui-test.yml— CI ワークフロー定義