Files
everything-claude-code/docs/ja-JP/commands/e2e.md

371 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
description: Playwright を使用してエンドツーエンドテストを生成して実行します。テストジャーニーを作成し、テストを実行し、スクリーンショット/ビデオ/トレースをキャプチャし、アーティファクトをアップロードします。
---
# E2E コマンド
このコマンドは **e2e-runner** エージェントを呼び出して、Playwright を使用してエンドツーエンドテストを生成、保守、実行します。
## このコマンドの機能
1. **テストジャーニー生成** - ユーザーフローの Playwright テストを作成
2. **E2E テスト実行** - 複数ブラウザ間でテストを実行
3. **アーティファクトキャプチャ** - 失敗時のスクリーンショット、ビデオ、トレース
4. **結果アップロード** - HTML レポートと JUnit XML
5. **不安定なテスト識別** - 不安定なテストを分離
## いつ使用しますするか
以下の場合に `/e2e` を使用します:
* 重要なユーザージャーニーをテスト(ログイン、取引、支払い)
* マルチステップフローがエンドツーエンドで機能することを検証
* UI インタラクションとナビゲーションをテスト
* フロントエンドとバックエンド間の統合を検証
* 本番環境デプロイメント向けの準備
## 動作方法
e2e-runner エージェントは:
1. **ユーザーフローを分析**してテストシナリオを特定
2. **ページオブジェクトモデルパターンを使用して Playwright テストを生成**
3. **複数ブラウザ間Chrome、Firefox、Safariでテストを実行**
4. **失敗をキャプチャ**(スクリーンショット、ビデオ、トレース含む)
5. **結果とアーティファクトを含むレポートを生成**
6. **不安定なテストを特定**して修正を推奨
## 使用します示例
````
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)
})
})
````
## テスト実行
```bash
# 生成されたテストを実行
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 パイプラインに追加:
```yaml
# .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 テストを優先:
**🔴 重大(常に成功する必要):**
1. ユーザーがウォレットを接続できる
2. ユーザーが市場をブラウズできる
3. ユーザーが市場を検索できる(セマンティック検索)
4. ユーザーが市場の詳細を表示できる
5. ユーザーが取引注文を配置できる(テスト資金使用します)
6. 市場が正しく決済される
7. ユーザーが資金を引き出せる
**🟡 重要:**
1. 市場作成フロー
2. ユーザープロフィール更新
3. リアルタイム価格更新
4. チャートレンダリング
5. 市場のフィルタリングとソート
6. モバイルレスポンシブレイアウト
## ベストプラクティス
**すべき事:**
* ✅ 保守性を高めるためページオブジェクトモデルを使用します
* ✅ セレクタとして 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` エージェントを呼び出します。
## 快速命令
```bash
# 全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
```