playwright-e2e-tester について
playwright-e2e-testerは、Playwrightのエンドツーエンドテストを作成・保守するチーム向けのスキルです。テスト設計、設定、デバッグ、CIに加え、ブラウザー、API、ビジュアルテストの手法を扱います。
主な機能
- 01ユーザーストーリーからテストを生成
- 02ページオブジェクトとフィクスチャの活用
- 03ブラウザー、ビューポート、レポーターの設定
- 04APIモックとネットワークリクエストの検証
- 05GitHub Actionsとシャーディングの設定
- 06トレース分析と不安定なテストの低減
活用シーン
- 01重要なユーザーフローのE2Eテスト作成
- 02断続的に発生するテスト失敗の調査
- 03スクリーンショット比較によるビジュアル回帰の確認
- 04CIパイプラインでのブラウザーテスト実行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill playwright-e2e-testerインストール後、Claude Code で/playwright-e2e-testerを入力して読み込まれたか確認します。
同梱ファイル.claude-plugin/plugin.json
詳細
Playwright E2E テスター
概要
最新のクロスブラウザテストフレームワークである Playwright を使用したエンドツーエンドテストの専門家です。テストの生成、ページオブジェクトパターン、ビジュアルリグレッションテスト、CI/CD との統合を専門としています。認証フロー、API モック、モバイルエミュレーションなど、複雑なテストシナリオにも対応します。
使用するタイミング
- 新規または既存のプロジェクトに Playwright を設定するとき
- 重要なユーザーフローの E2E テストを作成するとき
- 不安定なテストやテストの失敗をデバッグするとき
- ビジュアルリグレッションテストを実装するとき
- CI/CD パイプライン用に Playwright を設定するとき
- Cypress、Selenium、Puppeteer から移行するとき
- セッション管理を伴う認証済みフローをテストするとき
- クロスブラウザテストを実施するとき(Chromium、Firefox、WebKit)
機能
テストの生成と作成
- ユーザーストーリーや受け入れ条件から Playwright テストを生成します
- ベストプラクティス(ロケーター、アサーション、待機)に従ってテストを作成します
- Page Object Model(POM)パターンを実装します
- 再利用可能なテストフィクスチャとユーティリティを作成します
- 動的コンテンツや競合状態に対応します
設定とセットアップ
- 環境ごとに
playwright.config.tsを設定します - 複数のブラウザーとビューポート用のプロジェクトを設定します
- ベース URL、タイムアウト、再試行を設定します
- 認証用のグローバルセットアップ/ティアダウンを実装します
- テストレポーター(HTML、JSON、JUnit)を設定します
高度なパターン
route()とfulfill()による API モック- ネットワークのインターセプトとリクエストの検証
toHaveScreenshot()によるビジュアルリグレッション@axe-core/playwrightによるアクセシビリティテスト- モバイルエミュレーションとデバイステスト
- 位置情報と権限のモック
CI/CD との統合
- GitHub Actions のワークフロー設定
- シャーディングによるテストの並列実行
- 成果物の収集(トレース、スクリーンショット、動画)
- 不安定なテストの検出と再試行戦略
- テスト結果のレポートと通知
デバッグとメンテナンス
- Playwright Inspector と Trace Viewer を使用します
page.pause()とヘッド付きモードでデバッグします- テストトレースを分析して失敗の原因を調べます
- 適切な待機処理によってテストの不安定さを軽減します
- 長期にわたりテストの安定性を維持します
依存関係
以下と相性よく動作します:
vitest-testing-patterns- E2E を補完するユニットテストのパターンgithub-actions-pipeline-builder- CI/CD パイプラインのセットアップaccessibility-auditor- アクセシビリティテストの拡張api-architect- E2E と並行して行う API コントラクトテスト
例
基本的なテスト構造
import { test, expect } from '@playwright/test';
test.describe('User Authentication', () => {
test('should allow user to sign in', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('[email protected]');
await page.getByLabel('Password').fill('securepassword');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
await expect(page).toHaveURL('/dashboard');
});
});
ページオブジェクトパターン
// pages/LoginPage.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly signInButton: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel('Email');
this.passwordInput = page.getByLabel('Password');
this.signInButton = page.getByRole('button', { name: 'Sign In' });
}
async goto() {
await this.page.goto('/login');
}
async signIn(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.signInButton.click();
}
}
認証セットアップ用フィクスチャ
// fixtures/auth.ts
import { test as base } from '@playwright/test';
export const test = base.extend({
authenticatedPage: async ({ page }, use) => {
// Perform authentication
await page.goto('/login');
await page.getByLabel('Email').fill(process.env.TEST_USER!);
await page.getByLabel('Password').fill(process.env.TEST_PASS!);
await page.getByRole('button', { name: 'Sign In' }).click();
// Wait for auth to complete
await page.waitForURL('/dashboard');
// Use the authenticated page in tests
await use(page);
},
});
GitHub Actions CI
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run E2E tests
run: npx playwright test
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
ビジュアルリグレッションテスト
test('homepage matches snapshot', async ({ page }) => {
await page.goto('/');
// Full page screenshot comparison
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
maxDiffPixelRatio: 0.01,
});
// Component-level screenshot
const hero = page.getByTestId('hero-section');
await expect(hero).toHaveScreenshot('hero-section.png');
});
API モック
test('displays products from API', async ({ page }) => {
// Mock the API response
await page.route('**/api/products', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([
{ id: 1, name: 'Product A', price: 29.99 },
{ id: 2, name: 'Product B', price: 49.99 },
]),
});
});
await page.goto('/products');
await expect(page.getByText('Product A')).toBeVisible();
await expect(page.getByText('$29.99')).toBeVisible();
});
ベストプラクティス
- ロールベースのロケーターを使う - CSS セレクターよりも
getByRole()、getByLabel()、getByText()を優先します - 固定時間の待機を避ける -
waitForTimeout()ではなく、waitForSelector()、waitForURL()、またはアサーションを使用します - テストを分離する - 各テストは独立させ、ほかのテストの状態に依存しないようにします
- フィクスチャを使う -
beforeEachフックではなく、フィクスチャを通じてセットアップロジックを共有します - テストの対象を絞る - 1つのテストにつき1つのユーザーフローをテストし、無関係な複数の項目をまとめてテストしないようにします
- 不安定さに先回りして対処する - 適切な待機、再試行、安定したロケーターを使用します
- ページオブジェクトで整理する - 保守性を高めるため、ページの操作をカプセル化します
- CI で実行する - マージ前に必ず CI で E2E テストを実行します
よくある落とし穴
- 不安定なロケーター:
nth-child(3)や自動生成されたクラス名など、壊れやすいセレクターは避けます - 競合状態:操作する前に、要素やナビゲーションを必ず待機します
- 共有状態:テストの実行順に依存しないようにします
- テストの遅さ:可能であれば、UI 操作の代わりに API 呼び出しで状態をセットアップします
- クリーンアップ漏れ:実行間でテストデータが残らないよう、データをクリーンアップします
コメント
Markdown 対応