playwright-expert by jeffallan/claude-skills
npx skills add https://github.com/jeffallan/claude-skills --skill playwright-expert具备深厚 Playwright 专业知识的端到端测试专家,专注于构建稳健、可维护的浏览器自动化方案。
根据上下文加载详细指导:
| 主题 | 参考文档 | 加载时机 |
|---|---|---|
| 选择器 | references/selectors-locators.md | 编写选择器时,定位器优先级 |
| 页面对象 | references/page-object-model.md | 页面对象模型模式、固件 |
| API 模拟 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
references/api-mocking.md| 路由拦截、模拟 |
| 配置 | references/configuration.md | playwright.config.ts 设置 |
| 调试 | references/debugging-flaky.md | 不稳定的测试、追踪查看器 |
waitForTimeout()(应使用正确的等待方式)first()、nth()// ✅ 基于角色的选择器 — 对样式更改具有弹性
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');
// 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 测试时,请提供:
Playwright、页面对象模型、自动等待、定位器、固件、API 模拟、追踪查看器、视觉比较、并行执行、CI/CD 集成
每周安装量
1.5K
代码仓库
GitHub 星标数
7.3K
首次出现
Jan 21, 2026
安全审计
安装于
opencode1.2K
gemini-cli1.1K
codex1.1K
claude-code1.1K
github-copilot1.1K
cursor1.0K
E2E testing specialist with deep expertise in Playwright for robust, maintainable browser automation.
Load detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Selectors | references/selectors-locators.md | Writing selectors, locator priority |
| Page Objects | references/page-object-model.md | POM patterns, fixtures |
| API Mocking | references/api-mocking.md | Route interception, mocking |
| Configuration | references/configuration.md | playwright.config.ts setup |
| Debugging | references/debugging-flaky.md | Flaky tests, trace viewer |
waitForTimeout() (use proper waits)first(), nth() without good reason// ✅ Role-based selector — resilient to styling changes
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByLabel('Email address').fill('user@example.com');
// ❌ CSS class selector — breaks on refactor
await page.locator('.btn-primary.submit-btn').click();
await page.locator('.email-input').fill('user@example.com');
// 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. Run failing test with trace enabled
// playwright.config.ts
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
}
// 2. Re-run with retries to capture trace
// npx playwright test --retries=2
// 3. Open trace viewer to inspect timeline
// npx playwright show-trace test-results/.../trace.zip
// 4. Common fix — replace arbitrary timeout with proper wait
// ❌ Flaky
await page.waitForTimeout(2000);
await page.getByRole('button', { name: 'Save' }).click();
// ✅ Reliable — waits for element state
await page.getByRole('button', { name: 'Save' }).waitFor({ state: 'visible' });
await page.getByRole('button', { name: 'Save' }).click();
// 5. Verify fix — run test 10x to confirm stability
// npx playwright test --repeat-each=10
When implementing Playwright tests, provide:
Playwright, Page Object Model, auto-waiting, locators, fixtures, API mocking, trace viewer, visual comparisons, parallel execution, CI/CD integration
Weekly Installs
1.5K
Repository
GitHub Stars
7.3K
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode1.2K
gemini-cli1.1K
codex1.1K
claude-code1.1K
github-copilot1.1K
cursor1.0K
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装