关于 playwright-expert
playwright-expert 是面向 Playwright 端到端测试与浏览器自动化的技能,帮助开发者配置测试、处理常见问题并审查测试代码。
主要功能
- 01Playwright 配置指导
- 02端到端测试示例
- 03Page Object Model 指导
- 04网络拦截与模拟
- 05视觉回归检查
- 06处理不稳定测试
适用场景
- 01在项目中启动 Playwright 测试
- 02测试登录等用户流程
- 03在浏览器测试中模拟 API 响应
- 04审查测试可靠性问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ cin12211/ orca-q --skill playwright-expert安装后在 Claude Code 中输入/playwright-expert确认已加载。
详细介绍
Playwright 专家
专精于 Playwright,用于 E2E 测试、浏览器自动化和跨浏览器测试。
调用时
推荐专家
- 单元/集成测试:推荐 jest-expert 或 vitest-expert
- React 组件测试:推荐 testing-expert
- 仅 API 测试:推荐 rest-api-expert
环境检测
npx playwright --version 2>/dev/null
ls playwright.config.* 2>/dev/null
find . -name "*.spec.ts" -path "*e2e*" | head -5
问题处理手册
项目设置
# Initialize Playwright
npm init playwright@latest
# Install browsers
npx playwright install
// 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',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
编写测试
import { test, expect } from '@playwright/test';
test.describe('Authentication', () => {
test('should login successfully', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', '[email protected]');
await page.fill('[data-testid="password"]', 'password123');
await page.click('[data-testid="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid="email"]', '[email protected]');
await page.fill('[data-testid="password"]', 'wrong');
await page.click('[data-testid="submit"]');
await expect(page.locator('.error-message')).toBeVisible();
});
});
页面对象模型
// pages/login.page.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.locator('[data-testid="email"]');
this.passwordInput = page.locator('[data-testid="password"]');
this.submitButton = page.locator('[data-testid="submit"]');
}
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();
}
}
// Usage in test
test('login test', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('[email protected]', 'password');
});
网络拦截
test('mock API response', async ({ page }) => {
await page.route('**/api/users', async (route) => {
await route.fulfill({
status: 200,
body: JSON.stringify([{ id: 1, name: 'Mock User' }]),
});
});
await page.goto('/users');
await expect(page.locator('.user-name')).toContainText('Mock User');
});
视觉回归
test('visual comparison', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.1,
});
});
处理不稳定测试
// Retry flaky tests
test('flaky network test', async ({ page }) => {
test.slow(); // Triple timeout
await page.goto('/');
await page.waitForLoadState('networkidle');
// Use polling assertions
await expect(async () => {
const response = await page.request.get('/api/status');
expect(response.ok()).toBeTruthy();
}).toPass({ timeout: 10000 });
});
运行测试
# Run all tests
npx playwright test
# Run specific file
npx playwright test login.spec.ts
# Run in headed mode
npx playwright test --headed
# Run in UI mode
npx playwright test --ui
# Debug mode
npx playwright test --debug
# Generate report
npx playwright show-report
代码审查清单
- 选择器使用 data-testid 属性
- 复杂流程使用页面对象模型
- 按需模拟网络请求
- 使用恰当的等待策略(不使用任意等待)
- 配置失败时截图
- 启用并行执行
反模式
- 硬编码等待——使用恰当的断言
- 脆弱的选择器——使用 data-testid
- 测试之间共享状态——隔离测试
- CI 中不重试——添加重试以应对不稳定情况
- 测试实现细节——测试用户行为
评论
支持 Markdown