SKILL.md
唯讀
名稱
playwright-expert
描述
在撰寫 Playwright 的 E2E 測試、設定測試基礎架構或偵錯不穩定的瀏覽器測試時使用。呼叫以編寫測試腳本、建立頁面物件、設定測試固定裝置、配置報告器、加入 CI 整合、實作 API 模擬或執行視覺回歸測試。觸發詞:Playwright、E2E 測試、端到端、瀏覽器測試、自動化、UI 測試、視覺測試、Page Object Model、測試不穩定性。
Playwright 專家
E2E 測試專家,專精於 Playwright,實現穩健且可維護的瀏覽器自動化。
核心工作流程
- 分析需求 - 識別要測試的使用者流程
- 設定 - 使用適當設定配置 Playwright
- 編寫測試 - 使用 POM 模式、適當的選擇器、自動等待
- 偵錯 - 執行測試 → 檢查追蹤 → 識別問題 → 修正 → 驗證修正
- 整合 - 加入 CI/CD 管線
參考指南
根據情境載入詳細指引:
| 主題 | 參考文件 | 載入時機 |
|---|---|---|
| 選擇器 | references/selectors-locators.md |
編寫選擇器、選擇器優先順序 |
| 頁面物件 | references/page-object-model.md |
POM 模式、固定裝置 |
| API 模擬 | references/api-mocking.md |
路由攔截、模擬 |
| 配置 | references/configuration.md |
playwright.config.ts 設定 |
| 偵錯 | references/debugging-flaky.md |
不穩定測試、追蹤檢視器 |
限制
必須做
- 盡可能使用基於角色的選擇器
- 利用自動等待(不要加入任意逾時)
- 保持測試獨立(無共享狀態)
- 使用 Page Object Model 以利維護
- 啟用追蹤/截圖以利偵錯
- 平行執行測試
禁止做
- 使用
waitForTimeout()(應使用適當的等待) - 依賴 CSS 類別選擇器(脆弱)
- 在測試之間共享狀態
- 忽略不穩定的測試
- 無正當理由使用
first()、nth()
程式碼範例
選擇器:基於角色(正確) vs CSS 類別(脆弱)
// ✅ 基於角色的選擇器 — 對樣式變更有彈性
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Email address').fill('user@example.com');
// ❌ CSS 類別選擇器 — 重構時會壞掉
await page.locator('.btn-primary.submit-btn').click();
await page.locator('.email-input').fill('user@example.com');
Page Object Model + 測試檔案
// pages/LoginPage.ts
import { type Page, type Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
readonly errorMessage: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel('Email address');
this.passwordInput = page.getByLabel('Password');
this.submitButton = page.getByRole('button', { name: 'Sign in' });
this.errorMessage = page.getByRole('alert');
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.submitButton.click();
}
}
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
test.describe('Login', () => {
let loginPage: LoginPage;
test.beforeEach(async ({ page }) => {
loginPage = new LoginPage(page);
await loginPage.goto();
});
test('successful login redirects to dashboard', async ({ page }) => {
await loginPage.login('user@example.com', 'correct-password');
await expect(page).toHaveURL('/dashboard');
});
test('invalid credentials shows error', async () => {
await loginPage.login('user@example.com', 'wrong-password');
await expect(loginPage.errorMessage).toBeVisible();
await expect(loginPage.errorMessage).toContainText('Invalid credentials');
});
});
不穩定測試的偵錯工作流程
// 1. 啟用追蹤執行失敗的測試
// playwright.config.ts
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
}
// 2. 使用重試重新執行以擷取追蹤
// npx playwright test --retries=2
// 3. 開啟追蹤檢視器檢查時間軸
// npx playwright show-trace test-results/.../trace.zip
// 4. 常見修正 — 將任意逾時替換為適當的等待
// ❌ 不穩定
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Save' }).click();
// ✅ 可靠 — 等待元素狀態
await page.getByRole('button', { name: 'Save' }).waitFor({ state: 'visible' });
await page.getByRole('button', { name: 'Save' }).click();
// 5. 驗證修正 — 執行測試 10 次以確認穩定性
// npx playwright test --repeat-each=10
輸出模板
實作 Playwright 測試時,提供:
- Page Object 類別
- 包含適當斷言的測試檔案
- 必要時的固定裝置設定
- 配置建議
知識參考
Playwright、Page Object Model、自動等待、定位器、固定裝置、API 模擬、追蹤檢視器、視覺比對、平行執行、CI/CD 整合




