All checks were successful
E2E Health Check / e2e-health (push) Successful in 15s
- playwright.config.ts: ignoreHTTPSErrors + deviceScaleFactor + maxDiffPixelRatio - global.setup.ts: 環境連通性驗證 + Storage State 結構 - .gitignore: 排除 .auth/ 目錄 支援: - 自簽憑證環境測試 - Visual Baseline 一致性 (deviceScaleFactor: 1) - 5% 比對容差 (避免字體渲染差異) - 未來 Auth 擴展點 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
/**
|
||
* Playwright Global Setup
|
||
* =======================
|
||
* Wave 4: E2E Auth Bypass + 全局初始化
|
||
*
|
||
* 功能:
|
||
* 1. 驗證測試環境連通性
|
||
* 2. 設置 Storage State (未來 Auth 擴展點)
|
||
* 3. 預熱 API 端點
|
||
*
|
||
* 使用方式:
|
||
* - 此檔案在所有測試執行前自動運行一次
|
||
* - 產生 .auth/state.json 供測試重用
|
||
*
|
||
* 建立: 2026-03-31 (台北時區)
|
||
* 建立者: Claude Code (Wave 4 E2E Hardening)
|
||
*/
|
||
|
||
import { chromium, FullConfig } from '@playwright/test'
|
||
|
||
const STORAGE_STATE_PATH = 'tests/e2e/.auth/state.json'
|
||
|
||
async function globalSetup(config: FullConfig) {
|
||
const baseURL = config.projects[0].use.baseURL || 'http://localhost:3000'
|
||
|
||
console.log(`[Global Setup] Starting with baseURL: ${baseURL}`)
|
||
|
||
const browser = await chromium.launch()
|
||
const context = await browser.newContext({
|
||
ignoreHTTPSErrors: true,
|
||
})
|
||
const page = await context.newPage()
|
||
|
||
try {
|
||
// Step 1: 驗證測試環境連通性
|
||
console.log('[Global Setup] Verifying environment connectivity...')
|
||
const response = await page.goto(baseURL, {
|
||
waitUntil: 'domcontentloaded',
|
||
timeout: 30000,
|
||
})
|
||
|
||
if (!response || !response.ok()) {
|
||
throw new Error(`Failed to reach ${baseURL}: ${response?.status()}`)
|
||
}
|
||
console.log(`[Global Setup] Environment OK: ${response.status()}`)
|
||
|
||
// Step 2: 預熱 API 端點 (可選)
|
||
// 確保 API 已就緒,避免首個測試因冷啟動而失敗
|
||
try {
|
||
const apiResponse = await page.request.get(`${baseURL}/api/v1/health`)
|
||
if (apiResponse.ok()) {
|
||
console.log('[Global Setup] API Health Check: OK')
|
||
}
|
||
} catch {
|
||
console.log('[Global Setup] API Health Check: Skipped (may not be available)')
|
||
}
|
||
|
||
// Step 3: 儲存 Storage State
|
||
// 目前無 Auth,但保留此結構供未來擴展
|
||
// 當實作登入時,在此處執行登入流程並儲存狀態
|
||
await context.storageState({ path: STORAGE_STATE_PATH })
|
||
console.log(`[Global Setup] Storage state saved to: ${STORAGE_STATE_PATH}`)
|
||
|
||
// =========================================================================
|
||
// 未來 Auth 擴展點
|
||
// =========================================================================
|
||
//
|
||
// 當實作登入機制後,在此處加入:
|
||
//
|
||
// const E2E_USERNAME = process.env.E2E_USERNAME || 'e2e-test'
|
||
// const E2E_PASSWORD = process.env.E2E_PASSWORD
|
||
//
|
||
// if (E2E_PASSWORD) {
|
||
// await page.goto(`${baseURL}/login`)
|
||
// await page.fill('[data-testid="username"]', E2E_USERNAME)
|
||
// await page.fill('[data-testid="password"]', E2E_PASSWORD)
|
||
// await page.click('[data-testid="login-button"]')
|
||
// await page.waitForURL(`${baseURL}/dashboard`)
|
||
// await context.storageState({ path: STORAGE_STATE_PATH })
|
||
// }
|
||
//
|
||
// =========================================================================
|
||
|
||
} catch (error) {
|
||
console.error('[Global Setup] Failed:', error)
|
||
throw error
|
||
} finally {
|
||
await browser.close()
|
||
}
|
||
|
||
console.log('[Global Setup] Complete')
|
||
}
|
||
|
||
export default globalSetup
|