e2e-test-conventions について
ブラウザー E2E テストの作成、変更、レビュー向けの Playwright と TypeScript の規約スキルです。ディレクトリー構成、テスト分離、認証、ナビゲーション、セレクター、環境設定を定めます。
主な機能
- 01Playwright と TypeScript の規約
- 02ブラウザーとスイートの構成
- 03独立性と並列実行への配慮
- 04Page Object Model の共通化指針
- 05セレクターとナビゲーション規則
- 06環境とテストデータの管理
活用シーン
- 01E2E テスト規約の統一
- 02テスト構成と信頼性のレビュー
- 03並列実行可能な独立テストの作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agentmantis/ test-skills --skill e2e-test-conventionsインストール後、Claude Code で/e2e-test-conventionsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/auth-setup.mdfolder-structure.mdselector-priority.md詳細
E2E テストの規約
これらの規約は、すべての Playwright E2E テストコードに適用されます。テストを作成、変更、レビューする際は、必ず読んで従ってください。
技術スタック
- ブラウザーの自動化とテストの実行には Playwright を使用します
- すべてのテストコードには TypeScript を使用します(プレーンな JavaScript は使用しません)
- フレームワークには依存しません。プロジェクトで使用している UI フレームワークに合わせて、セレクターとヘルパーを調整してください
プロジェクト構成
e2e/ ディレクトリは次の構成に従います。
e2e/
├── auth/ # Authentication setup (runs before all tests)
│ └── auth.setup.ts # Logs in and saves session state
├── fixtures/ # Custom Playwright fixtures
│ └── base.ts # Extends Playwright's test with custom fixtures
├── helpers/ # Shared utility functions (NOT page objects)
│ └── env-config.ts # Environment resolution
├── poms/ # Page Object Models (one file per page)
│ └── base.page.ts # Abstract base class — all POMs extend this
├── test-data/ # External test data (JSON files)
├── tests/ # Test specs organised by suite
│ ├── handover/ # Ticket-driven handover tests (temporary)
│ ├── regression/ # Full regression tests (permanent)
│ └── smoke/ # Quick critical-path checks
├── playwright.config.ts
├── tsconfig.json
└── .env.example # Template for environment variables
ルール:
- この構成以外にファイルを作成しないでください
- 明示的な許可なく既存のファイルを移動しないでください
各ディレクトリの詳細については、references/folder-structure.md を参照してください。
ブラウザー × スイートの設定
Playwright の設定では、{browser}:{suite} という命名規則でプロジェクトを定義します。
ブラウザー: chromium、firefox、webkit、mobile-chrome、mobile-safari
スイート:
| スイート | ディレクトリ | 目的 | ライフサイクル |
|---|---|---|---|
regression | tests/regression/ | 回帰テスト全般 | 永続 |
handover | tests/handover/ | チケット主導の引き継ぎ | 一時的 — 昇格または削除 |
smoke | tests/smoke/ | クリティカルパスの健全性確認 | 永続 |
すべてのプロジェクトは、認証を処理する setup プロジェクトに依存します。
テストの実行
# From e2e/ directory
npx playwright test # All browsers × all suites
npx playwright test --project="chromium:regression" # Single project
npx playwright test --project="*:smoke" # One suite, all browsers
npx playwright test --project="firefox:*" # One browser, all suites
命名規則
| 種類 | パターン | 例 |
|---|---|---|
| Page Object Model | poms/ 内の {feature}.page.ts | dashboard.page.ts |
| 回帰テストの spec | tests/regression/ 内の {feature}.spec.ts | dashboard.spec.ts |
| スモークテストの spec | tests/smoke/ 内の {feature}.spec.ts | dashboard.spec.ts |
| 引き継ぎテストの spec | tests/handover/ 内の {TICKET}-{description}.spec.ts | PROJ-123-bulk-delete.spec.ts |
| テストデータ | test-data/ 内の {feature}.json | dashboard.json |
{feature} の名前は、POM、spec、テストデータのファイル間で一致している必要があります。
テストの独立性と並列実行
すべてのテストは完全に独立している必要があります
- 各テストは分離された状態で、任意の順序で実行されます
- テストが前のテストで作成された状態に依存することは絶対に避けてください
- 各テストでは、POM のナビゲーションメソッドを使って対象ページに移動します
並列実行時の安全性
すべてのテストは、複数のワーカーで並列実行されます。競合を避けるため、次の点を守ってください。
- すべてのテストデータの値に、一意のサフィックス(タイムスタンプ+ランダム ID)を付けます
- テスト間で変更可能な状態を共有しないでください
- 各テストで独自のデータを作成し、検証してからクリーンアップします
認証
認証は、すべてのテストプロジェクトより前に実行されるセットアッププロジェクト(auth/auth.setup.ts)で一度だけ行います。セッション状態はファイルに保存され、Playwright の storageState 設定を使って再利用されます。
spec、POM、beforeEach、beforeAll にログイン処理を記述することは絶対に避けてください。認証はすでに処理されています。
アプリケーションが認証トークンを IndexedDB(Firebase Auth、Supabase、AWS Amplify など)に保存している場合は、indexedDB オプションを使用します。
await page.context().storageState({ path: authFile, indexedDB: true });
パターン全体については、references/auth-setup.md を参照してください。
ナビゲーション
- 常に直接 URL で移動します(
page.goto('/dashboard')) - メニューやサイドバーをクリックして移動しないでください。メニューの状態やアニメーションによってテストが不安定になる可能性があります
- 移動後に、URL と主要な見出しまたは要素が表示されていることをアサートします
BasePage と派生 POM メソッド
BasePage は、複数のページで役立つ再利用可能なヘルパーメソッドを集約する唯一の場所です。派生 POM は、ページ固有の動作だけに集中させてください。
メソッドを BasePage に配置する場合
次の条件に当てはまるヘルパーは、BasePage に移動します。
- 複数の POM で再利用できる — 例:モーダルの閉じる、トースト通知を待つ、読み込みスピナーを確認する
- 特定のページに強く依存しない — どのページがアクティブでも同じように動作する
- 継承しても問題のない汎用性がある — ページ固有のセレクターや前提条件がない
- 機能固有の POM に残すと重複する可能性が高い
BasePage のヘルパーの例:
waitForToast(message)— トースト通知を待ち、表示を確認しますdismissModal()— 開いているモーダルダイアログを閉じますwaitForLoadingComplete()— 読み込みスピナーが消えるのを待ちますgetTableRowCount()— 複数のページにあるデータテーブルの行数を数えます
メソッドを派生 POM に配置する場合
次の条件に当てはまるヘルパーは、特定の POM に残します。
- 1 つのページに固有である — 例:ページ固有のフォームに入力する
- ページ固有の構造に依存する — そのページにしか存在しないセレクターを使う
- 他の場所で再利用される見込みがない
重要な理由
- 重複を減らす — 共有ロジックを POM 間でコピーせず、1 か所にまとめられます
- 共有動作を一元管理する — 共通ヘルパーを更新すると、すべての POM に自動的に反映されます
- 派生 POM を小さく、目的に集中させる — 各 POM には、そのページ固有の内容だけを含めます
- 見つけやすくする — 開発者は共有ユーティリティを
BasePageで探せます
ルール
2 つ目の POM で同じヘルパーを書いていることに気づいたら、すぐに BasePage に移動してください。機能 POM のあちこちに重複したヘルパーを残さないでください。
セレクターとロケーターの戦略
次の優先順位を使用します。
getByRole()— ボタン、見出し、ダイアログ(最も堅牢)getByLabel()— フォームフィールドgetByText()— 表示されているテキストコンテンツgetByPlaceholder()— 入力欄のプレースホルダー- CSS を指定した
locator()/filter()— 最終手段
ヒント:
- 動的にレンダリングされる属性(ツールチップ、ポップオーバー)は、クエリ実行時に DOM に存在しない場合があります。子コンテンツに一致させるには
filter()を使用してください - アイコンボタンには表示テキストがないことがよくあります。
aria-labelまたは子アイコンのコンテンツで一致させてください - CSS クラスよりも、ロールベースおよびラベルベースのセレクターを優先してください(CSS クラスは壊れやすく、フレームワーク固有です)
例については、references/selector-priority.md を参照してください。
環境設定
各環境には、e2e/ ディレクトリ内に専用の .env.{env} ファイルがあります。
| ファイル | 環境 |
|---|---|
.env.local | ローカル開発 |
.env.dev | 開発サーバー |
.env.test | テストサーバー |
.env.uat | UAT サーバー |
.env.production | 本番環境 |
すべてのファイルで同じ変数名を使用します — 値だけが異なります。
BASE_URL="https://your-app.example.com"
LOGIN_EMAIL="[email protected]"
LOGIN_PASSWORD="your-password"
AUTH_FILE="e2e/.auth/user.json"
アクティブな環境の選択
TEST_ENV は必須です。設定されていない場合、env-config.ts はただちにエラーをスローし、テストは開始されません。これにより、変数の設定忘れによって誤って本番環境に対して E2E テストを実行することを防ぎます。
TEST_ENV=dev npx playwright test # loads .env then .env.dev
TEST_ENV=production npx playwright test # loads .env then .env.production
npx playwright test # ❌ ERROR — TEST_ENV is not set
2 層の読み込み
helpers/env-config.ts は TEST_ENV を読み取り、dotenv を使って 2 層で環境変数を読み込みます。
e2e/.env— ベースファイル(TEST_ENVとすべての変数を格納できます)e2e/.env.{env}— 任意の環境固有のオーバーライド
どちらのファイルも任意です。 どちらも存在しない場合、プロセスは環境内にすでに設定されている変数(CI やコンテナーから注入されたものなど)を使用します。dotenv はすでに設定されている変数を上書きしないため、CLI のエクスポート値と CI から注入された値が常に優先されます。
このモジュールは静的な定数ではなく、ヘルパー関数 — getEnvConfig()、getBaseUrl()、getCredentials()、getAuthFilePath() — をエクスポートします。読み込みはプロセスごとに 1 回実行され、その後の呼び出しでは何も行われません。
ルール
TEST_ENVは必須です — 設定されていない場合はエラーがスローされるため、E2E テストが気付かないうちに本番環境を対象にすることはありません- すべての変数(
BASE_URL、LOGIN_EMAIL、LOGIN_PASSWORD、AUTH_FILE)は必須です — 設定されていない場合はエラーがスローされます - 必須の環境変数にハードコードされたデフォルト値を使用しないでください。値が設定されていない場合はエラーをスローしてください
.env.*ファイルにはシークレットが含まれるため、Git の追跡対象外です- コミットする環境変数ファイルは
.env.exampleのみです — テンプレートとして使用します
テストデータ
- すべてのテストデータは
e2e/test-data/{feature}.jsonに格納します - spec ファイルや POM ファイルにデータをハードコードしないでください
- カスタムフィクスチャを使ってテストデータを読み込み、一意のサフィックスを付与します
@playwright/testではなく、必ずカスタムフィクスチャからtestをインポートしてください
spec ファイルのルール
- ページ操作はすべて POM 経由で行います — spec 内で
page.getByRole()、page.locator()などを直接呼び出さないでください - spec で
pageを使用できるのは、POM コンストラクターに渡す場合、またはbeforeAllでコンテキストを作成する場合のみです - 手動で作成したブラウザーコンテキストを使う
test.beforeAllで、クリーンアップのために POM のsetUp()を呼び出します - 各テストでは、POM のナビゲーションメソッドを使って個別にページ遷移します