E2E 測試技能
觸發方式
- 關鍵字:
teste、e2e、playwright、browser test、visual test、smoke test - 呼叫:
/e2e-test [suite] [--flags]
說明
針對預覽與生產環境,模擬人類行為的自動化 E2E 測試。 使用 Chrome MCP 或 Playwright MCP 進行瀏覽器自動化。
測試套件
| 套件 | 時長 | 說明 |
|---|---|---|
smoke | 30s | 登入、上傳、基本 UI(關鍵字「teste」時的預設) |
full | 5min | 所有 P0+P1 情境 |
visual | 2min | 僅螢幕截圖比對 |
upload | 1min | 所有檔案格式 |
download | 2min | 匯出功能 |
login | 30s | 驗證流程 |
api | 1min | API 端點測試 |
旗標
| 旗標 | 說明 |
|---|---|
--preview | 只測試 localhost |
--production | 只測試生產環境 URL |
--quick | 僅執行 P0 情境(最快測試) |
--human | 使用真實瀏覽器的 Chrome MCP |
--headless | 使用無頭模式的 Playwright MCP(CI/CD) |
--update-baselines | 更新螢幕截圖基準線 |
--mobile | 測試行動裝置視口(375px, 768px) |
工作流程
1. 環境檢查
- 檢查 localhost 是否正在運行(curl/fetch)
- 檢查生產環境 URL 是否可達
- 根據旗標選擇測試環境
2. 瀏覽器設定
- 若 --human:使用 Chrome MCP(mcp__claude-in-chrome__)
- 否則:使用 Playwright MCP(mcp__playwright__)
- 視口:1280x720(桌面)或 375x667(行動裝置)
3. 啟用人類行為
- 隨機延遲:動作間隔 200-800ms
- 打字速度:每按鍵 50-150ms
- 懸停後再點擊(暫停 200-500ms)
- 平滑滾動而非即時滾動
4. 執行測試套件
- 每個測試:前後螢幕截圖
- 錯誤時:儲存螢幕截圖與主控台日誌
- 下載驗證:檢查檔案大小
5. 產生報告
- Markdown 報告存放於 .playwright-mcp/reports/
- 視覺差異時產生比對圖
- 含通過/失敗/不穩定狀態的摘要
測試情境(P0 - 業務關鍵)
1. 登陸頁面載入
- 導航至 URL
- 等待主要元素可見
- 檢查標誌/品牌識別可見
- 螢幕截圖:landing-page.png
2. 登入 / 驗證流程
- 點擊登入按鈕
- 等待彈窗/頁面動畫
- 檢查驗證選項可見(OAuth、Email 等)
- 螢幕截圖:login-modal.png
3. 切換語言(若有 i18n)
- 找到語言切換開關
- 加入人類延遲後點擊
- 等待文字變化
- 驗證 UI 文字已變更
- 螢幕截圖:language-toggle.png
4. 檔案上傳(若有)
- 點擊上傳區域
- 選擇測試檔案
- 等待確認
- 檢查檔名是否顯示
- 螢幕截圖:file-uploaded.png
5. 執行主要操作
- 執行主要應用功能
- 等待載入狀態
- 等待結果(最多 60 秒)
- 檢查結果內容是否存在
- 螢幕截圖:result.png
6. 匯出 / 下載(若有)
- 點擊下載按鈕
- 等待下載事件
- 驗證檔案格式正確
- 驗證檔案大小大於最小值
- 螢幕截圖:download-complete.png
測試情境(P1 - 重要)
7. 導航 / 歷史記錄
- 點擊導航元素
- 等待動畫
- 檢查正確的內容已載入
8. 主題切換(若有)
- 找到主題切換開關
- 記錄當前顏色
- 點擊切換開關
- 驗證顏色已變更
- 螢幕截圖:theme-toggle.png
9. 響應式設計
- 設定視口為 375x667
- 檢查行動裝置導航可見
- 檢查主要功能可存取
- 螢幕截圖:mobile-view.png
10. 錯誤處理
- 觸發錯誤(無效輸入)
- 等待錯誤訊息
- 檢查錯誤是否對使用者友善
- 螢幕截圖:error-state.png
人類行為函數
// 隨機延遲(200-800ms)
async function humanDelay() {
const delay = 200 + Math.random() * 600;
await page.waitForTimeout(delay);
}
// 人類打字(每按鍵 50-150ms)
async function humanType(selector: string, text: string) {
await page.click(selector);
await humanDelay();
for (const char of text) {
await page.keyboard.type(char);
await page.waitForTimeout(50 + Math.random() * 100);
}
}
// 懸停 -> 暫停 -> 點擊模式
async function humanClick(selector: string) {
await page.hover(selector);
await page.waitForTimeout(200 + Math.random() * 300);
await page.click(selector);
await humanDelay();
}
// 平滑滾動
async function humanScroll(pixels: number) {
await page.evaluate((px) => {
window.scrollTo({ top: px, behavior: "smooth" });
}, pixels);
await page.waitForTimeout(500);
}
報告格式
## E2E 測試報告 - [日期] [時間]
### 環境
- **URL**:[受測 URL]
- **瀏覽器**:Chromium [版本]
- **視口**:1280x720
- **套件**:smoke
### 結果
| # | 測試 | 狀態 | 時長 | 螢幕截圖 |
| --- | ---------------- | ------ | ------ | --------------------------- |
| 1 | 登陸頁面載入 | PASS | 0.8s | [檢視](landing-page.png) |
| 2 | 登入彈窗 | PASS | 1.2s | [檢視](login-modal.png) |
| 3 | 檔案上傳 | PASS | 2.1s | [檢視](file-uploaded.png) |
| 4 | 主要操作 | SLOW | 45.2s | [檢視](result.png) |
| 5 | 下載 | FAIL | 3.4s | [檢視](error.png) |
### 摘要
- **總數**:N 個測試
- **通過**:X(Y%)
- **失敗**:A(B%)
- **慢/不穩定**:C(D%)
- **時長**:Z 秒
視覺基準線
.playwright-mcp/
├── baselines/ # 黃金參考(Git 追蹤)
│ ├── landing-page-desktop.png
│ ├── landing-page-mobile.png
│ ├── login-modal.png
│ ├── result.png
│ └── error-state.png
├── current/ # 當前螢幕截圖(Git 忽略)
├── diffs/ # 像素差異(Git 忽略)
└── reports/ # 測試報告(Git 忽略)
執行方式
最簡單的呼叫
User: "teste"
-> 於可用的環境執行 smoke 套件
特定測試
User: "teste upload"
-> 只執行上傳套件
User: "teste production visual"
-> 於生產環境執行視覺套件
User: "teste --quick --human"
-> 使用真實 Chrome 瀏覽器快速測試
CI/CD 整合
User: "teste --headless --full"
-> 所有測試以無頭模式執行,適用於 CI/CD 流程
錯誤處理
-
localhost 無法連線:
- 顯示警告
- 詢問是否應啟動開發伺服器
-
生產環境無法連線:
- 顯示警告
- 檢查部署狀態
-
測試超時(>60 秒):
- 擷取當前狀態的螢幕截圖
- 儲存主控台日誌
- 標記為 FAIL
-
偵測到視覺差異:
- 產生差異圖
- 標記為 FLAKY(不自動標記 FAIL)
- 由使用者決定是否需要更新基準線
設定
專案根目錄下的選擇性 .e2e-config.json:
{
"previewUrl": "http://localhost:5173",
"productionUrl": "https://your-app.com",
"defaultSuite": "smoke",
"timeouts": {
"navigation": 10000,
"action": 60000,
"download": 30000
},
"viewports": {
"desktop": { "width": 1280, "height": 720 },
"tablet": { "width": 768, "height": 1024 },
"mobile": { "width": 375, "height": 667 }
},
"humanBehavior": {
"enabled": true,
"minDelay": 200,
"maxDelay": 800,
"typingSpeed": { "min": 50, "max": 150 }
},
"screenshots": {
"onEveryStep": false,
"onFailure": true,
"fullPage": false
}
}
前置需求
- 已安裝 Chrome MCP 或 Playwright MCP
- 含有
package.json的 Node.js 專案 - 可選:專案根目錄下的
.e2e-config.json用於專案設定
作者
Dresden AI Insights - https://dresdenaiinsights.com