playwright-skill について
FixMyBerlin/FMC プロジェクトで Playwright を使うためのスキルです。プロジェクトの E2E テスト、エージェントによる探索との使い分け、一時的な自動化を扱い、地図や認証を含む TanStack Start の設定とテストパターンを示します。
主な機能
- 01プロジェクト E2E テストの設定
- 02TanStack Start のサーバー設定
- 03スモーク、認証、地図のテストパターン
- 04コンソールとサーバーエラーのヘルパー
- 05スキルランナーによる一時的な自動化
活用シーン
- 01プロジェクトへの回帰テスト追加
- 02ルートと認証フローのテスト
- 03地図の描画とタイルリクエストの確認
- 04単発のブラウザー自動化
MCP 対応
デバッグや UI の簡易確認には agent-browser MCP を対話型探索の選択肢として説明し、Playwright のプロジェクト E2E や一時スクリプトと区別します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ fixmyberlin/ fixmyskills --skill playwright-skillインストール後、Claude Code で/playwright-skillを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
package.jsonplaywright.config.ts.templaterun.jslib/helpers.jsreferences/tilda-patterns.md詳細
まずプロジェクトの tests/README.md を読んでください — 環境変数、Docker、スクリプトはここに記載されています。
関連するFMCスキル: tanstack-router-conventions(ルート/検索)、tanstack-start-auth(セッション)、tanstack-start-conventions。
公式ドキュメント(取得して参照してください。内容を重複させないでください)
Playwrightには公式の llms.txt はありません(リクエストはクローズ済みです)。
| トピック | URL |
|---|---|
| 概要とテストの作成 | https://playwright.dev/docs/intro |
ロケーター(getByRole など) | https://playwright.dev/docs/locators |
| テスト設定 | https://playwright.dev/docs/test-configuration |
| ベストプラクティス | https://playwright.dev/docs/best-practices |
| CI | https://playwright.dev/docs/ci |
| エージェント(CLI) | https://playwright.dev/docs/getting-started-cli |
| TanStackドキュメントのインデックス | https://tanstack.com/llms.txt |
| TanStack StartのE2E例 | https://github.com/TanStack/router/tree/main/e2e/react-start |
| マップの操作(任意) | https://mapgrab.github.io/docs/getting-started/stage-two/playwright |
3つのレイヤー(適切なツールを選択)
| レイヤー | 用途 | 場所 |
|---|---|---|
| プロジェクトE2E | テストスイート、CI、リグレッション | @playwright/test を tests/*.spec.ts で使用、リポジトリの playwright.config.ts |
| エージェントによる探索 | 対話的なデバッグ、ハイドレーション、Reactツリー、簡易UIチェック | agent-browser MCP — スキル tech-stack、スキル tech-stack → references/agent-browser-mcp.md |
| アドホック(このスキル) | 単発スクリプト、外部サイト、MCPなし | run.js 経由の /tmp/playwright-test-*.js |
| DBスキーマ/クエリ | テーブルの確認 | Postgres MCP — スキル tech-stack → references/postgres-mcp.md |
リポジトリ内の作業では、リグレッションを防ぐ必要があるものにはプロジェクトE2Eを優先してください。
適用範囲(Playwrightとagent-browser)
| 対象 | @playwright/test(このスキル) | agent-browser(tech-stack) |
|---|---|---|
| リグレッション、CI、認証のスタブ化、マップのテストフック | ✓ | — |
| ハイドレーション、Reactツリー、簡易UIデバッグ | — | ✓ |
| マップ(WebGL) | waitForMapLoad、タイル/ネットワークヘルパー、MapGrab | 注釈付きスクリーンショット、eval |
tilda-geoのスモークテスト/認証スタブ/マップのテスト仕様: 作成時には references/tilda-patterns.md を読んでください(環境変数による実行制御、スモークテストスイート、スタブ化されたセッションのフロー、マップの手順、ルートフィクスチャ)。
今後も活用すべき探索結果は、tests/*.spec.ts に追加して bun run e2e を実行してください。
TanStack Start — playwright.config.ts
リファレンス実装:tilda-geo の app/playwright.config.ts。
環境変数の読み込み
defineConfig より前に環境変数を読み込み、webServer が DATABASE_* などを受け取れるようにします。読み込み順は、リポジトリの .env、アプリの .env(任意)、.env.test(テスト専用)です。
サーバーの階層
| 階層 | 用途 | webServer.command | 備考 |
|---|---|---|---|
| ローカル/スモーク | すばやいフィードバック(TILDA のデフォルト) | bun run dev | Vite 開発サーバー。例:http://127.0.0.1:5173 |
| CI/リリース | 本番に近い環境 | bun run build && bun run start | TanStack e2e のように PORT/VITE_SERVER_PORT を設定します |
| プレビュー | ビルド済みアセット+SSR プレビュー | bun run build && bun run preview --port … | TanStack の vite preview モード |
Docker/DB: アプリで Postgres やタイルが必要な場合は、Playwright の外部で compose を起動します(docker compose up db tiles -d)。CI で動作がすでに確認されていない限り、webServer.command に compose を詰め込まないでください。
設定テンプレート
このスキルディレクトリの playwright.config.ts.template をコピーします(baseURL は http://127.0.0.1:5173、webServer: bun run dev、chromium プロジェクト)。
FMC/TILDA のパターン
tilda-geo の標準パス(app/):
| 項目 | 場所 |
|---|---|
| 設定 | playwright.config.ts |
| セットアップドキュメント | tests/README.md |
| スモーク(公開ルート) | tests/smoke/public-routes.spec.ts |
| スモーク(末尾のスラッシュ) | tests/smoke/trailing-slash-redirect.spec.ts |
スモーク(リージョンの beforeLoad) | tests/smoke/region-before-load.spec.ts |
| スタブ化された管理者/ロール認証 | tests/pages/admin.stubbed-auth.spec.ts |
| リージョン+マップ(実際の OAuth) | tests/pages/regions.spec.ts(RUN_OAUTH_E2E=1) |
| ドキュメントのリージョンダウンロード | tests/pages/docs-region-downloads.spec.ts |
| 連絡先プロフィールのモーダル | tests/pages/contact-profile-modal.spec.ts |
| 認証フィクスチャ | tests/fixtures/auth.ts |
| ルート一覧 | tests/fixtures/routes.ts |
| コンソール/サーバーエラー | tests/utils/console.ts、tests/utils/server.ts |
| マップの待機/描画ヘルパー | tests/utils/maps.ts |
| マップのネットワーク検証 | tests/utils/network.ts |
| 動的 URL の正規表現エスケープ | tests/utils/regex.ts |
| アプリのテストフック | src/components/shared/utils/playwright.ts |
VITE_PLAYWRIGHT_ENABLED
リポジトリの .env(.env.example を参照)に設定します。
VITE_PLAYWRIGHT_ENABLED=true
テスト ID とマップシグナルを E2E でのみ有効にします。本番 HTML では有効になりません。
アプリのフック(playwright.ts)
import { createIsomorphicFn } from '@tanstack/react-start'
export function playwrightTestId(testId: string) {
return import.meta.env.VITE_PLAYWRIGHT_ENABLED === 'true' ? testId : undefined
}
export const exposeMainMapForDebugging = createIsomorphicFn()
.server((_map?: MaplibreMap) => {})
.client((map?: MaplibreMap) => {
const playwrightEnabled =
import.meta.env.VITE_PLAYWRIGHT_ENABLED === 'true' || window.__PLAYWRIGHT_ENABLED === 'true'
if (import.meta.env.DEV || playwrightEnabled) {
window.__mainMap = map
}
})
export const firePlaywrightMapLoadedEvent = createIsomorphicFn()
.server(() => {})
.client(() => {
const playwrightEnabled =
import.meta.env.VITE_PLAYWRIGHT_ENABLED === 'true' || window.__PLAYWRIGHT_ENABLED === 'true'
if (!playwrightEnabled) return
window.dispatchEvent(new CustomEvent('mapLoaded'))
window.__mapLoaded = true
})
マップの onLoad ハンドラーから、両方のヘルパーを呼び出します:exposeMainMapForDebugging(event.target) と firePlaywrightMapLoadedEvent()。window.__mainMap は開発モードと Playwright モードで利用できますが、mapLoaded イベントは引き続き Playwright モードに限定されます。マップを公開する理由と onLoad の設定については、スキル react-map-gl → references/map-debug-exposure.md を参照してください。テストでは tests/utils/maps.ts(waitForMapLoad、verifyMapRendered、checkMapTilesLoaded、getMapLayerIds)を使用します。地域ページでタイル/API のカバレッジを確認する場合は、waitForMapLoad の後に tests/utils/network.ts の verifyMapNetworkRequests を使用してください。
マップキャンバスのクリック/ドラッグには、MapGrab をご検討ください(従来の Trassenscout のアンケートで使用。これらのフローを Start に移行する際に導入してください)。
スモークテスト(移行後)
Next → TanStack Start の移行後、スモークテストの仕様を追加または実行します:
baseURLを使用してpage.goto(route)を実行- pathname が変わっていないことを確認(クラッシュによるリダイレクトがないこと)
expect(page.locator('main').first()).toBeVisible()を確認expectNoConsoleErrors(page)を確認(utils を参照)
ルート一覧は tests/fixtures/routes.ts(PUBLIC_SMOKE_ROUTES、ADMIN_ROUTES、ADMIN_REDIRECT_SMOKE_ROUTE など)にあります。実行方法:bun run e2e -- tests/smoke。
認証
| 戦略 | 使用場面 | TILDA |
|---|---|---|
| スタブ管理者 | 管理ページ、検索パラメーターの UI | createStubbedAdminSession(page, baseURL, { identityKey }) — Better Auth の Cookie + Prisma ユーザー |
| スタブユーザー | 管理者以外/モーダルのフロー | createStubbedUserSession(page, baseURL, { identityKey }) |
| 実際の OAuth | マップ + 地域のリグレッション | .env.test に RUN_OAUTH_E2E=1 + TEST_OSM_* がある場合の auth-setup.spec.ts + regions.spec.ts |
並列実行の安全性: スタブ管理者のテストスイートは DB の行を共有するため、mode: 'serial' を使用し、ルートごとにネストした test.describe を設定してください。これにより、afterEach のクリーンアップで別のワーカーのセッションが削除されるのを防げます(cleanupStubbedSessionData('ADMIN' | 'USER', identityKey))。
動的 URL: ? や特殊文字を含む可能性のあるフィクスチャのパスから toHaveURL(new RegExp(...)) を作成する際は、tests/utils/regex.ts の escapeRegExp(route) を使用してください。
品質ヘルパー
goto の前にコレクターを登録し、ナビゲーション後にアサーションを行います:
- コンソール:
collectConsoleErrors→KNOWN_ACCEPTABLE_ERRORSでフィルター →errorがあれば失敗 - サーバー:
collectServerErrors(page, baseURL)— 同一オリジンの 5xx とrequestfailed
既知の無害なエラーが発生した場合は、util ファイルの許可リストを拡張します。
ロケーター
ロール/ラベル/テキストのロケーターでは不十分な場合に限り、playwrightTestId('…') を使用してください。
プロジェクトの E2E ワークフロー
package.json スクリプト(TILDA の慣例):
"e2e": "playwright test --project=chromium"
bun run e2e→ chromium プロジェクト(ローカル/CI のデフォルト実行)bun run e2e -- --ui/bun run e2e -- --debug→--の後に Playwright のフラグを渡すbun run e2e -- tests/smoke→ 仕様の一部のみを実行
bun add -d @playwright/test dotenv
bunx playwright install chromium
# Start DB/tiles if required (see tests/README.md)
アドホックな自動化(スキルランナー)
セットアップ(初回のみ):
cd ${CLAUDE_SKILL_DIR} && bun run setup
ワークフロー:
-
localhost の場合:まず開発サーバーを検出します。
bun -e "require('${CLAUDE_SKILL_DIR}/lib/helpers').detectDevServers().then(s => console.log(JSON.stringify(s)))" -
スクリプトを
/tmp/playwright-test-*.jsに作成します(アドホックなスクリプトをスキルディレクトリにコミットしないでください)。 -
ファイルの先頭で
TARGET_URLをパラメーター化します。 -
プロジェクトディレクトリ(スキルフォルダーではなく)から実行します:
bun ${CLAUDE_SKILL_DIR}/run.js /tmp/playwright-test-*.js。run.jsは相対スクリプトパスとtakeScreenshotの出力先を、実行元のディレクトリを基準に解決します。生のpage.screenshot({ path })には絶対パスを使用してください。
ヘッダー(自動化されたトラフィックを識別します):
PW_HEADER_NAME=X-Automated-By PW_HEADER_VALUE=playwright-skill \
bun ${CLAUDE_SKILL_DIR}/run.js /tmp/my-script.js
複数のヘッダー:PW_EXTRA_HEADERS='{"X-Automated-By":"playwright-skill"}'。
デフォルト: デフォルトではヘッドレスで実行します(エージェントはウィンドウを見られません)。人間が表示を確認する場合にのみ headless: false を使用します。
ヘルパー(lib/helpers.js):detectDevServers、createContext / getExtraHeadersFromEnv、takeScreenshot。