# Playwright E2E 測試配置

> **版本**: v1.0
> **建立日期**: 2026-03-20
> **負責人**: CPO
> **CEO 指示 #5**: 啟用截圖與錄影加速除錯

---

## 配置檔案

```typescript
// apps/web/playwright.config.ts

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: [
    ['html', { outputFolder: 'playwright-report' }],
    ['json', { outputFile: 'playwright-report/results.json' }],
  ],

  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',

    // ⚠️ CEO 指示 #5: 截圖與錄影必須啟用
    screenshot: 'on',           // 每個測試都截圖
    video: 'on-first-retry',    // 失敗時錄影

    // 本地化設定
    locale: 'zh-TW',
    timezoneId: 'Asia/Taipei',
  },

  projects: [
    // Desktop Chrome (主要)
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        viewport: { width: 1920, height: 1080 },
      },
    },

    // Desktop Firefox
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },

    // Desktop Safari
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },

    // Mobile Chrome
    {
      name: 'Mobile Chrome',
      use: { ...devices['Pixel 5'] },
    },

    // Mobile Safari
    {
      name: 'Mobile Safari',
      use: { ...devices['iPhone 12'] },
    },
  ],

  // 本地開發伺服器
  webServer: process.env.CI ? undefined : {
    command: 'pnpm dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },

  // 輸出目錄
  outputDir: 'test-results/',

  // 截圖設定
  expect: {
    toHaveScreenshot: {
      // 允許 1% 像素差異
      maxDiffPixelRatio: 0.01,
    },
  },
});
```

---

## 截圖與錄影配置

### 截圖模式

| 模式 | 說明 | 建議場景 |
|------|------|---------|
| `'off'` | 不截圖 | - |
| `'on'` | 每個測試都截圖 | **開發/CI (建議)** |
| `'only-on-failure'` | 失敗時截圖 | 大規模測試 |

### 錄影模式

| 模式 | 說明 | 建議場景 |
|------|------|---------|
| `'off'` | 不錄影 | - |
| `'on'` | 每個測試都錄影 | 深度除錯 |
| `'retain-on-failure'` | 失敗時保留 | **CI (建議)** |
| `'on-first-retry'` | 重試時錄影 | **CI (建議)** |

---

## 視覺回歸測試

### 基準截圖

```typescript
// e2e/dashboard.spec.ts

import { test, expect } from '@playwright/test';

test('dashboard renders correctly', async ({ page }) => {
  await page.goto('/dashboard');
  await page.waitForLoadState('networkidle');

  // 全頁截圖比對
  await expect(page).toHaveScreenshot('dashboard-full.png', {
    fullPage: true,
    maxDiffPixelRatio: 0.01,
  });

  // 特定元素截圖
  const hostCard = page.locator('[data-testid="host-card"]').first();
  await expect(hostCard).toHaveScreenshot('host-card.png');
});
```

### 基準圖存放

```
apps/web/e2e/
├── dashboard.spec.ts
├── dashboard.spec.ts-snapshots/
│   ├── dashboard-full-chromium.png
│   ├── dashboard-full-firefox.png
│   ├── dashboard-full-webkit.png
│   └── host-card-chromium.png
└── ...
```

---

## CI 整合

### GitHub Actions

```yaml
# .github/workflows/e2e.yaml
name: E2E Tests

on:
  pull_request:
    branches: [main]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: pnpm install

      - name: Install Playwright browsers
        run: pnpm exec playwright install --with-deps

      - name: Run E2E tests
        run: pnpm exec playwright test
        env:
          BASE_URL: http://localhost:3000

      # 上傳測試報告
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: playwright-report
          path: apps/web/playwright-report/
          retention-days: 30

      # 上傳截圖與錄影
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: test-results
          path: apps/web/test-results/
          retention-days: 7
```

---

## 測試報告

### HTML 報告

```bash
# 本地查看報告
pnpm exec playwright show-report
```

### 報告內容

- 所有測試結果 (通過/失敗/跳過)
- 每個測試的截圖
- 失敗測試的錄影
- 錯誤堆疊追蹤
- 測試執行時間

---

## 除錯工作流程

### 失敗測試處理

1. 查看 CI Artifacts 下載測試報告
2. 開啟 HTML 報告查看失敗原因
3. 觀看錄影了解失敗時的畫面狀態
4. 比對截圖差異找出視覺問題
5. 本地重現並修復

### 本地除錯

```bash
# 有頭模式執行 (可看到瀏覽器)
pnpm exec playwright test --headed

# 除錯模式 (可暫停/單步)
pnpm exec playwright test --debug

# 只執行失敗的測試
pnpm exec playwright test --last-failed
```

---

## 變更記錄

| 日期 | 版本 | 變更 | 作者 |
|------|------|------|------|
| 2026-03-20 | v1.0 | 初版建立 | CPO |

---

*此文件由 CPO 維護，E2E 測試必須遵守此配置。*
