webapp-playwright-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeb Application Testing
Web应用测试
This skill enables comprehensive browser-based testing and debugging for web applications using Playwright MCP. It provides live browser interaction, UI validation, screenshot capture, console log inspection, and accessibility verification to ensure your web application behaves as expected.
Activation: This skill is triggered when you need to interact with a browser, validate UI elements, capture screenshots, or debug web application issues.
本技能借助Playwright MCP实现Web应用的全流程浏览器测试与调试,提供实时浏览器交互、UI验证、截图捕获、控制台日志查看及可访问性校验功能,确保Web应用符合预期行为。
触发条件: 当你需要与浏览器交互、验证UI元素、捕获截图或调试Web应用问题时,将触发本技能。
When to Use This Skill
适用场景
Use this skill when you need to:
- Create Playwright tests for web applications
- Test frontend functionality in a real browser
- Verify UI behavior and interactions
- Debug web application issues
- Capture screenshots for documentation or debugging
- Inspect browser console logs
- Validate form submissions and user flows
- Check responsive design across viewports
在以下场景中使用本技能:
- 为Web应用创建Playwright测试用例
- 在真实浏览器中测试前端功能
- 验证UI行为与交互逻辑
- 调试Web应用问题
- 捕获截图用于文档或调试
- 查看浏览器控制台日志
- 验证表单提交与用户流程
- 跨视口检查响应式设计
Prerequisites
前置条件
- Node.js installed on the system (v18+)
- A locally running web application (or accessible URL)
- Playwright MCP server configured
- Playwright will be installed automatically if not present
- 系统已安装Node.js(v18+版本)
- 本地运行的Web应用(或可访问的URL)
- 已配置Playwright MCP服务器
- 若未安装Playwright,将自动完成安装
Playwright MCP Tools Reference
Playwright MCP工具参考
Navigation & Interaction
导航与交互
| Tool | Purpose | Example Query |
|---|---|---|
| Go to a URL | "Navigate to http://localhost:3000/login" |
| Click elements | "Click the Submit button" |
| Fill input fields | "Fill the email field with test@example.com" |
| Hover over elements | "Hover over the dropdown menu" |
| Keyboard input | "Press Enter" |
| Select from dropdown | "Select 'Option 1' from the dropdown" |
| 工具 | 用途 | 示例指令 |
|---|---|---|
| 访问指定URL | "Navigate to http://localhost:3000/login" |
| 点击元素 | "Click the Submit button" |
| 填充输入字段 | "Fill the email field with test@example.com" |
| 悬停在元素上 | "Hover over the dropdown menu" |
| 键盘输入 | "Press Enter" |
| 选择下拉选项 | "Select 'Option 1' from the dropdown" |
Validation & Capture
验证与捕获
| Tool | Purpose | Example Query |
|---|---|---|
| Get accessibility tree | "Get the accessibility snapshot" |
| Capture visual state | "Take a screenshot" |
| View browser logs | "Check for console errors" |
| Monitor API calls | "Show network requests" |
| 工具 | 用途 | 示例指令 |
|---|---|---|
| 获取可访问性树 | "Get the accessibility snapshot" |
| 捕获页面视觉状态 | "Take a screenshot" |
| 查看浏览器日志 | "Check for console errors" |
| 监控API调用 | "Show network requests" |
Browser Management
浏览器管理
| Tool | Purpose | Example Query |
|---|---|---|
| Change viewport | "Resize to mobile (375x667)" |
| Manage browser tabs | "List open tabs" |
| Close browser | "Close the browser" |
| 工具 | 用途 | 示例指令 |
|---|---|---|
| 更改视口尺寸 | "Resize to mobile (375x667)" |
| 管理浏览器标签页 | "List open tabs" |
| 关闭浏览器 | "Close the browser" |
Core Capabilities
核心功能
1. Browser Automation
1. 浏览器自动化
- Navigate to URLs
- Click buttons and links
- Fill form fields
- Select dropdowns
- Handle dialogs and alerts
- 导航至指定URL
- 点击按钮与链接
- 填充表单字段
- 选择下拉菜单
- 处理对话框与提示框
2. Verification
2. 验证功能
- Assert element presence
- Verify text content
- Check element visibility
- Validate URLs
- Test responsive behavior
- 断言元素存在性
- 验证文本内容
- 检查元素可见性
- 校验URL正确性
- 测试响应式表现
3. Debugging
3. 调试功能
- Capture screenshots
- View console logs
- Inspect network requests
- Debug failed tests
- 捕获截图
- 查看控制台日志
- 检查网络请求
- 调试失败的测试用例
Usage Examples
使用示例
Example 1: Basic Navigation Test
示例1:基础导航测试
typescript
// Navigate to a page and verify heading
await page.goto('http://localhost:3000');
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();typescript
// Navigate to a page and verify heading
await page.goto('http://localhost:3000');
await expect(page.getByRole('heading', { level: 1 })).toBeVisible();Example 2: Form Interaction (Role-Based Locators)
示例2:表单交互(基于角色的定位器)
typescript
// Fill out and submit a form using accessible locators
await page.getByRole('textbox', { name: 'Username' }).fill('testuser');
await page.getByRole('textbox', { name: 'Password' }).fill('password123');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page).toHaveURL(/.*dashboard/);typescript
// Fill out and submit a form using accessible locators
await page.getByRole('textbox', { name: 'Username' }).fill('testuser');
await page.getByRole('textbox', { name: 'Password' }).fill('password123');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page).toHaveURL(/.*dashboard/);Example 3: Screenshot Capture
示例3:截图捕获
typescript
// Capture a full-page screenshot for debugging
await page.screenshot({ path: 'debug.png', fullPage: true });typescript
// Capture a full-page screenshot for debugging
await page.screenshot({ path: 'debug.png', fullPage: true });Example 4: Accessibility Snapshot Assertion
示例4:可访问性快照断言
typescript
// Verify page structure with aria snapshot
await expect(page.getByRole('main')).toMatchAriaSnapshot(`
- main:
- heading "Welcome" [level=1]
- form:
- textbox "Email"
- textbox "Password"
- button "Login"
`);typescript
// Verify page structure with aria snapshot
await expect(page.getByRole('main')).toMatchAriaSnapshot(`
- main:
- heading "Welcome" [level=1]
- form:
- textbox "Email"
- textbox "Password"
- button "Login"
`);Guidelines
操作指南
- Always verify the app is running - Check that the local server is accessible before running tests
- Use explicit waits - Wait for elements or navigation to complete before interacting
- Capture screenshots on failure - Take screenshots to help debug issues
- Clean up resources - Always close the browser when done
- Handle timeouts gracefully - Set reasonable timeouts for slow operations
- Test incrementally - Start with simple interactions before complex flows
- Use selectors wisely - Prefer data-testid or role-based selectors over CSS classes
- 始终验证应用运行状态 - 运行测试前确认本地服务器可正常访问
- 使用显式等待 - 交互前等待元素加载或导航完成
- 失败时捕获截图 - 借助截图辅助调试问题
- 清理资源 - 测试完成后务必关闭浏览器
- 优雅处理超时 - 为慢速操作设置合理超时时间
- 增量式测试 - 先测试简单交互,再推进到复杂流程
- 合理使用定位器 - 优先选择data-testid或基于角色的定位器,而非CSS类
Common Patterns
常见模式
Pattern: Wait for Element (Role-Based)
模式:等待元素(基于角色)
typescript
await page.getByRole('button', { name: 'Submit' }).waitFor({ state: 'visible' });typescript
await page.getByRole('button', { name: 'Submit' }).waitFor({ state: 'visible' });Pattern: Check if Element Exists
模式:检查元素是否存在
typescript
const exists = await page.getByRole('alert').count() > 0;typescript
const exists = await page.getByRole('alert').count() > 0;Pattern: Capture Console Logs
模式:捕获控制台日志
typescript
page.on('console', msg => console.log(`[${msg.type()}] ${msg.text()}`));typescript
page.on('console', msg => console.log(`[${msg.type()}] ${msg.text()}`));Pattern: Handle Errors with Screenshot
模式:结合截图处理错误
typescript
try {
await page.getByRole('button', { name: 'Submit' }).click();
} catch (error) {
await page.screenshot({ path: 'error.png' });
throw error;
}typescript
try {
await page.getByRole('button', { name: 'Submit' }).click();
} catch (error) {
await page.screenshot({ path: 'error.png' });
throw error;
}Pattern: Test Responsive Viewports
模式:测试响应式视口
typescript
const viewports = [
{ width: 375, height: 667, name: 'mobile' },
{ width: 768, height: 1024, name: 'tablet' },
{ width: 1920, height: 1080, name: 'desktop' },
];
for (const vp of viewports) {
await page.setViewportSize({ width: vp.width, height: vp.height });
await page.screenshot({ path: `${vp.name}.png` });
}typescript
const viewports = [
{ width: 375, height: 667, name: 'mobile' },
{ width: 768, height: 1024, name: 'tablet' },
{ width: 1920, height: 1080, name: 'desktop' },
];
for (const vp of viewports) {
await page.setViewportSize({ width: vp.width, height: vp.height });
await page.screenshot({ path: `${vp.name}.png` });
}Step-by-Step Workflows
分步工作流
Workflow 1: Validate a Page with Playwright MCP
工作流1:使用Playwright MCP验证页面
-
Navigate to the page
"Navigate to http://localhost:3000/login" -
Get accessibility snapshot
"Get the accessibility snapshot" -
Verify expected elements exist
- Check for form fields, buttons, headings in the snapshot
-
Take a screenshot for documentation
"Take a screenshot" -
Check for console errors
"Show console messages"
-
访问目标页面
"Navigate to http://localhost:3000/login" -
获取可访问性快照
"Get the accessibility snapshot" -
验证预期元素是否存在
- 在快照中检查表单字段、按钮、标题等元素
-
捕获截图用于文档
"Take a screenshot" -
检查控制台错误
"Show console messages"
Workflow 2: Debug a Failing Test
工作流2:调试失败的测试用例
-
Navigate to the problematic page
"Navigate to http://localhost:3000/checkout" -
Capture initial state
"Take a screenshot" -
Get accessibility snapshot to understand structure
"Get the accessibility snapshot" -
Identify the correct locator from the snapshot
-
Test the interaction
"Click the 'Add to Cart' button" -
Verify result and capture evidence
"Take a screenshot" "Check for console errors"
-
访问问题页面
"Navigate to http://localhost:3000/checkout" -
捕获初始状态
"Take a screenshot" -
获取可访问性快照以了解页面结构
"Get the accessibility snapshot" -
从快照中确定正确的定位器
-
测试交互逻辑
"Click the 'Add to Cart' button" -
验证结果并捕获证据
"Take a screenshot" "Check for console errors"
Workflow 3: Test Responsive Design
工作流3:测试响应式设计
-
Navigate to the page
"Navigate to http://localhost:3000" -
Test mobile viewport
"Resize browser to 375x667" "Take a screenshot" "Verify hamburger menu is visible" -
Test tablet viewport
"Resize browser to 768x1024" "Take a screenshot" -
Test desktop viewport
"Resize browser to 1920x1080" "Verify navigation links are visible"
-
访问目标页面
"Navigate to http://localhost:3000" -
测试移动端视口
"Resize browser to 375x667" "Take a screenshot" "Verify hamburger menu is visible" -
测试平板端视口
"Resize browser to 768x1024" "Take a screenshot" -
测试桌面端视口
"Resize browser to 1920x1080" "Verify navigation links are visible"
Troubleshooting
故障排除
| Problem | Cause | Solution |
|---|---|---|
| Element not found | Wrong locator or element not rendered | Use |
| Timeout waiting for element | Element hidden or slow to load | Check for overlays, increase timeout |
| Strict mode violation | Multiple elements match locator | Add more specific filters like |
| Click intercepted | Another element covering target | Scroll into view or wait for overlay to close |
| Console errors in app | JavaScript runtime errors | Use |
| Screenshot blank | Page not fully loaded | Wait for network idle or specific element |
| Form submission fails | Validation errors not visible | Check for error messages in snapshot |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 元素未找到 | 定位器错误或元素未渲染 | 使用 |
| 等待元素超时 | 元素隐藏或加载缓慢 | 检查是否有遮罩层,增加超时时间 |
| 严格模式违规 | 多个元素匹配定位器 | 添加更具体的筛选条件,如 |
| 点击被拦截 | 目标元素被其他元素覆盖 | 滚动至可见区域或等待遮罩层关闭 |
| 应用控制台报错 | JavaScript运行时错误 | 使用 |
| 截图空白 | 页面未完全加载 | 等待网络空闲或特定元素加载完成 |
| 表单提交失败 | 验证错误不可见 | 在快照中检查错误提示信息 |
Locator Strategy (Priority Order)
定位器策略(优先级顺序)
typescript
// ✅ BEST: Role-based (accessible, resilient)
page.getByRole('button', { name: 'Submit' })
page.getByRole('textbox', { name: 'Email' })
page.getByRole('link', { name: 'Sign up' })
// ✅ GOOD: User-facing text
page.getByLabel('Email address')
page.getByPlaceholder('Enter your email')
page.getByText('Welcome back')
// ✅ GOOD: Test IDs (stable, explicit)
page.getByTestId('submit-button')
// ⚠️ AVOID: CSS selectors (brittle)
page.locator('.btn-primary')
// ❌ NEVER: XPath (extremely brittle)
page.locator('//div[@class="container"]/button[1]')typescript
// ✅ 最优:基于角色(可访问、稳定)
page.getByRole('button', { name: 'Submit' })
page.getByRole('textbox', { name: 'Email' })
page.getByRole('link', { name: 'Sign up' })
// ✅ 良好:面向用户的文本
page.getByLabel('Email address')
page.getByPlaceholder('Enter your email')
page.getByText('Welcome back')
// ✅ 良好:测试ID(稳定、明确)
page.getByTestId('submit-button')
// ⚠️ 尽量避免:CSS选择器(脆弱)
page.locator('.btn-primary')
// ❌ 绝对避免:XPath(极度脆弱)
page.locator('//div[@class="container"]/button[1]')Limitations
局限性
- Requires Node.js environment (v18+)
- Cannot test native mobile apps (use Appium or Detox instead)
- Complex authentication flows may require session storage or API login
- Some modern frameworks with shadow DOM require specific configuration
- Heavy animations may require disabling for stable tests
- 依赖Node.js环境(v18+)
- 无法测试原生移动应用(建议使用Appium或Detox)
- 复杂认证流程可能需要会话存储或API登录
- 部分包含Shadow DOM的现代框架需要特定配置
- 复杂动画可能需要禁用以保证测试稳定性
References
参考资料
- Locator Strategies Guide - Detailed locator patterns and best practices
- Common Test Patterns - Reusable test patterns and utilities
- Page Object Model Guide - POM implementation and best practices
- API Testing Guide - API testing, mocking, and request interception
- Test Helper Utilities - JavaScript helper functions
- Locator Strategies Guide - 详细的定位器模式与最佳实践
- Common Test Patterns - 可复用的测试模式与工具
- Page Object Model Guide - POM实现与最佳实践
- API Testing Guide - API测试、Mock与请求拦截
- Test Helper Utilities - JavaScript辅助函数
Quick Commands
快速指令
| Task | Playwright MCP Query |
|---|---|
| Open page | "Navigate to {URL}" |
| Check structure | "Get the accessibility snapshot" |
| Capture evidence | "Take a screenshot" |
| Fill form | "Fill the {field} with {value}" |
| Click element | "Click the {name} button" |
| Check errors | "Show console messages" |
| Test mobile | "Resize browser to 375x667" |
| 任务 | Playwright MCP指令 |
|---|---|
| 打开页面 | "Navigate to {URL}" |
| 检查页面结构 | "Get the accessibility snapshot" |
| 捕获证据 | "Take a screenshot" |
| 填充表单 | "Fill the {field} with {value}" |
| 点击元素 | "Click the {name} button" |
| 检查错误 | "Show console messages" |
| 测试移动端 | "Resize browser to 375x667" |