mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
13 KiB
13 KiB
description
| description |
|---|
| Playwright を使用してエンドツーエンドテストを生成して実行します。テストジャーニーを作成し、テストを実行し、スクリーンショット/ビデオ/トレースをキャプチャし、アーティファクトをアップロードします。 |
E2E コマンド
このコマンドは e2e-runner エージェントを呼び出して、Playwright を使用してエンドツーエンドテストを生成、保守、実行します。
このコマンドの機能
- テストジャーニー生成 - ユーザーフローの Playwright テストを作成
- E2E テスト実行 - 複数ブラウザ間でテストを実行
- アーティファクトキャプチャ - 失敗時のスクリーンショット、ビデオ、トレース
- 結果アップロード - HTML レポートと JUnit XML
- 不安定なテスト識別 - 不安定なテストを分離
いつ使用しますするか
以下の場合に /e2e を使用します:
- 重要なユーザージャーニーをテスト(ログイン、取引、支払い)
- マルチステップフローがエンドツーエンドで機能することを検証
- UI インタラクションとナビゲーションをテスト
- フロントエンドとバックエンド間の統合を検証
- 本番環境デプロイメント向けの準備
動作方法
e2e-runner エージェントは:
- ユーザーフローを分析してテストシナリオを特定
- ページオブジェクトモデルパターンを使用して Playwright テストを生成
- 複数ブラウザ間(Chrome、Firefox、Safari)でテストを実行
- 失敗をキャプチャ(スクリーンショット、ビデオ、トレース含む)
- 結果とアーティファクトを含むレポートを生成
- 不安定なテストを特定して修正を推奨
使用します示例
User: /e2e マーケット検索と表示フローをテスト
Agent (e2e-runner):
# E2Eテスト生成: マーケット検索と表示フロー
## 特定されたテストシナリオ
**ユーザージャーニー:** マーケット検索 → 結果表示 → マーケットクリック → 詳細表示
**テストカバレッジ:**
1. マーケットページに遷移
2. セマンティック検索を実行
3. 検索結果を検証
4. 最初の結果をクリック
5. マーケット詳細ページの読み込みを検証
6. チャートの描画を検証
## 生成されたテストコード
```typescript
// tests/e2e/markets/search-and-view.spec.ts
import { test, expect } from '@playwright/test'
import { MarketsPage } from '../../pages/MarketsPage'
import { MarketDetailsPage } from '../../pages/MarketDetailsPage'
test.describe('Market Search and View Flow', () => {
test('user can search markets and view details', async ({ page }) => {
// 1. Navigate to markets page
const marketsPage = new MarketsPage(page)
await marketsPage.goto()
// Verify page loaded
await expect(page).toHaveTitle(/Markets/)
await expect(page.locator('h1')).toContainText('Markets')
// 2. Perform semantic search
await marketsPage.searchMarkets('election')
// Wait for API response
await page.waitForResponse(resp =>
resp.url().includes('/api/markets/search') && resp.status() === 200
)
// 3. Verify search results
const marketCards = marketsPage.marketCards
await expect(marketCards.first()).toBeVisible()
const resultCount = await marketCards.count()
expect(resultCount).toBeGreaterThan(0)
// Take screenshot of search results
await page.screenshot({ path: 'artifacts/search-results.png' })
// 4. Click on first result
const firstMarketTitle = await marketCards.first().textContent()
await marketCards.first().click()
// 5. Verify market details page loads
await expect(page).toHaveURL(/\/markets\/[a-z0-9-]+/)
const detailsPage = new MarketDetailsPage(page)
await expect(detailsPage.marketName).toBeVisible()
await expect(detailsPage.marketDescription).toBeVisible()
// 6. Verify chart renders
await expect(detailsPage.priceChart).toBeVisible()
// Verify market name matches
const detailsTitle = await detailsPage.marketName.textContent()
expect(detailsTitle?.toLowerCase()).toContain(
firstMarketTitle?.toLowerCase().substring(0, 20) || ''
)
// Take screenshot of market details
await page.screenshot({ path: 'artifacts/market-details.png' })
})
test('search with no results shows empty state', async ({ page }) => {
const marketsPage = new MarketsPage(page)
await marketsPage.goto()
// Search for non-existent market
await marketsPage.searchMarkets('xyznonexistentmarket123456')
// Verify empty state
await expect(page.locator('[data-testid="no-results"]')).toBeVisible()
await expect(page.locator('[data-testid="no-results"]')).toContainText(
/no.*results|no.*markets/i
)
const marketCount = await marketsPage.marketCards.count()
expect(marketCount).toBe(0)
})
test('can clear search and see all markets again', async ({ page }) => {
const marketsPage = new MarketsPage(page)
await marketsPage.goto()
// Initial market count
const initialCount = await marketsPage.marketCards.count()
// Perform search
await marketsPage.searchMarkets('trump')
await page.waitForLoadState('networkidle')
// Verify filtered results
const filteredCount = await marketsPage.marketCards.count()
expect(filteredCount).toBeLessThan(initialCount)
// Clear search
await marketsPage.searchInput.clear()
await page.waitForLoadState('networkidle')
// Verify all markets shown again
const finalCount = await marketsPage.marketCards.count()
expect(finalCount).toBe(initialCount)
})
})
テスト実行
# 生成されたテストを実行
npx playwright test tests/e2e/markets/search-and-view.spec.ts
Running 3 tests using 3 workers
✓ [chromium] › search-and-view.spec.ts:5:3 › user can search markets and view details (4.2s)
✓ [chromium] › search-and-view.spec.ts:52:3 › search with no results shows empty state (1.8s)
✓ [chromium] › search-and-view.spec.ts:67:3 › can clear search and see all markets again (2.9s)
3 passed (9.1s)
Artifacts generated:
- artifacts/search-results.png
- artifacts/market-details.png
- playwright-report/index.html
テストレポート
╔══════════════════════════════════════════════════════════════╗
║ E2Eテスト結果 ║
╠══════════════════════════════════════════════════════════════╣
║ ステータス: ✅ 全テスト合格 ║
║ 合計: 3テスト ║
║ 合格: 3 (100%) ║
║ 失敗: 0 ║
║ 不安定: 0 ║
║ 所要時間: 9.1s ║
╚══════════════════════════════════════════════════════════════╝
アーティファクト:
📸 スクリーンショット: 2ファイル
📹 ビデオ: 0ファイル (失敗時のみ)
🔍 トレース: 0ファイル (失敗時のみ)
📊 HTMLレポート: playwright-report/index.html
レポート表示: npx playwright show-report
✅ E2E テストスイートは CI/CD 統合の準備ができました!
## テストアーティファクト
テスト実行時、以下のアーティファクトがキャプチャされます:
**全テスト共通:**
- タイムラインと結果を含むHTMLレポート
- CI統合用のJUnit XML
**失敗時のみ:**
- 失敗状態のスクリーンショット
- テストのビデオ録画
- デバッグ用トレースファイル (ステップバイステップ再生)
- ネットワークログ
- コンソールログ
## アーティファクトの確認
```bash
# ブラウザでHTMLレポートを表示
npx playwright show-report
# 特定のトレースファイルを表示
npx playwright show-trace artifacts/trace-abc123.zip
# スクリーンショットはartifacts/ディレクトリに保存
open artifacts/search-results.png
不安定なテスト検出
テストが断続的に失敗する場合:
⚠️ FLAKY TEST DETECTED: tests/e2e/markets/trade.spec.ts
テストは10回中7回合格 (合格率70%)
よくある失敗:
"Timeout waiting for element '[data-testid="confirm-btn"]'"
推奨修正:
1. 明示的な待機を追加: await page.waitForSelector('[data-testid="confirm-btn"]')
2. タイムアウトを増加: { timeout: 10000 }
3. コンポーネントの競合状態を確認
4. 要素がアニメーションで隠れていないか確認
隔離推奨: 修正されるまでtest.fixme()としてマーク
ブラウザ設定
デフォルトでは、テストは複数のブラウザで実行されます:
- ✅ Chromium(デスクトップ Chrome)
- ✅ Firefox(デスクトップ)
- ✅ WebKit(デスクトップ Safari)
- ✅ Mobile Chrome(オプション)
playwright.config.ts で設定してブラウザを調整します。
CI/CD 統合
CI パイプラインに追加:
# .github/workflows/e2e.yml
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run E2E tests
run: npx playwright test
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
PMX 固有の重要フロー
PMX の場合、以下の E2E テストを優先:
🔴 重大(常に成功する必要):
- ユーザーがウォレットを接続できる
- ユーザーが市場をブラウズできる
- ユーザーが市場を検索できる(セマンティック検索)
- ユーザーが市場の詳細を表示できる
- ユーザーが取引注文を配置できる(テスト資金使用します)
- 市場が正しく決済される
- ユーザーが資金を引き出せる
🟡 重要:
- 市場作成フロー
- ユーザープロフィール更新
- リアルタイム価格更新
- チャートレンダリング
- 市場のフィルタリングとソート
- モバイルレスポンシブレイアウト
ベストプラクティス
すべき事:
- ✅ 保守性を高めるためページオブジェクトモデルを使用します
- ✅ セレクタとして data-testid 属性を使用します
- ✅ 任意のタイムアウトではなく API レスポンスを待機
- ✅ 重要なユーザージャーニーのエンドツーエンドテスト
- ✅ main にマージする前にテストを実行
- ✅ テスト失敗時にアーティファクトをレビュー
すべきでない事:
- ❌ 不安定なセレクタを使用します(CSS クラスは変わる可能性)
- ❌ 実装の詳細をテスト
- ❌ 本番環境に対してテストを実行
- ❌ 不安定なテストを無視
- ❌ 失敗時にアーティファクトレビューをスキップ
- ❌ E2E テストですべてのエッジケースをテスト(単体テストを使用します)
重要な注意事項
PMX にとって重大:
- 実際の資金に関わる E2E テストはテストネット/ステージング環境でのみ実行する必要があります
- 本番環境に対して取引テストを実行しないでください
- 金融テストに
test.skip(process.env.NODE_ENV === 'production')を設定 - 少量のテスト資金を持つテストウォレットのみを使用します
他のコマンドとの統合
/planを使用してテストする重要なジャーニーを特定/tddを単体テストに使用します(より速く、より細粒度)/e2eを統合とユーザージャーニーテストに使用します/code-reviewを使用してテスト品質を検証
関連エージェント
このコマンドは ~/.claude/agents/e2e-runner.md の e2e-runner エージェントを呼び出します。
快速命令
# 全E2Eテストを実行
npx playwright test
# 特定のテストファイルを実行
npx playwright test tests/e2e/markets/search.spec.ts
# ヘッドモードで実行 (ブラウザ表示)
npx playwright test --headed
# テストをデバッグ
npx playwright test --debug
# テストコードを生成
npx playwright codegen http://localhost:3000
# レポートを表示
npx playwright show-report