Files
chill_notes/AI工程/概念/Playwright.md
2026-06-22 11:30:51 +08:00

193 lines
4.8 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Playwright
> 相关:[[测试策略金字塔]]、[[Browser_Use]]、[[MCP]]
## 定义
**Playwright**是最流行的浏览器自动化测试框架支持Chromium、Firefox、WebKit。
**核心思想**:提供稳定、快速的浏览器自动化能力,支持多浏览器、多平台。
## 核心特征
### 1. 多浏览器支持
- ChromiumChrome、Edge
- Firefox
- WebKitSafari
- 一套API多浏览器运行
### 2. 自动化能力
- 自动等待元素可操作
- 自动重试断言
- 网络拦截
- 截图和视频录制
### 3. 稳定性
- 使用稳定的选择器
- 自动处理动态内容
- 支持并行测试
## 基本使用
### 安装
```bash
npm init playwright@latest
```
### 基本测试
```typescript
import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev/');
await page.getByText('Get Started').click();
await expect(page).toHaveTitle(/Getting started/);
});
```
### 登录测试
```typescript
test('login success', async ({ page }) => {
await page.goto('https://example.com/login');
await page.getByPlaceholder('Email').fill('test@example.com');
await page.getByPlaceholder('Password').fill('123456');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByText('Welcome')).toBeVisible();
});
```
### API登录更稳定
```typescript
test('login via API + set session', async ({ page, request }) => {
const response = await request.post('https://example.com/api/login', {
data: {
email: 'test@example.com',
password: '123456'
}
});
expect(response.ok()).toBeTruthy();
const cookies = await response.headers()['set-cookie'];
await page.context().addCookies([{
name: 'session',
value: cookies,
domain: 'example.com',
path: '/'
}]);
await page.goto('https://example.com/dashboard');
await expect(page.getByText('Welcome')).toBeVisible();
});
```
## 选择器最佳实践
### 推荐的选择器(从优到差)
```typescript
// 1. 使用data-testid最稳定
await page.getByTestId('submit-button').click();
// 2. 使用角色和名称(推荐)
await page.getByRole('button', { name: 'Login' }).click();
// 3. 使用标签文本(推荐)
await page.getByLabel('Email').fill('test@example.com');
// 4. 使用占位符(可用)
await page.getByPlaceholder('Enter your email').fill('test@example.com');
// 5. 使用文本(可用)
await page.getByText('Welcome').toBeVisible();
// 6. 使用CSS选择器不推荐容易变
await page.locator('.btn-primary').click();
// 7. 使用XPath不推荐容易变
await page.locator('//button[@type="submit"]').click();
```
## 等待策略
### 自动等待
```typescript
// Playwright自动等待元素可见、可操作
await page.getByRole('button', { name: 'Login' }).click();
```
### 显式等待
```typescript
// 等待URL变化
await expect(page).toHaveURL(/dashboard/);
// 等待元素可见
await expect(page.getByText('Welcome')).toBeVisible();
// 等待元素隐藏
await expect(page.getByText('Loading')).toBeHidden();
// 等待网络请求完成
await page.waitForLoadState('networkidle');
```
## 配置
### playwright.config.ts
```typescript
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
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',
},
projects: [
{ name: 'chromium', use: { browserName: 'chromium' } },
{ name: 'firefox', use: { browserName: 'firefox' } },
{ name: 'webkit', use: { browserName: 'webkit' } },
],
});
```
## 适用场景
- **E2E测试**最流行的E2E测试框架
- **浏览器自动化**:自动化浏览器操作
- **视觉回归测试**:截图对比
- **性能测试**:页面加载性能
## 优势
- **多浏览器支持**一套API多浏览器运行
- **稳定性**:自动等待、自动重试
- **速度快**比Selenium快
- **生态成熟**:社区活跃,文档完善
## 挑战
- **学习成本**需要了解框架API
- **维护成本**:需要维护测试脚本
- **运行时间**完整的E2E测试运行时间长
## 最佳实践
1. **优先使用稳定的选择器**data-testid、角色、标签
2. **使用API登录**:提高测试速度
3. **测试数据管理**使用Fixture或API准备数据
4. **并行测试**:提高测试效率
5. **CI/CD集成**:每次提交自动运行测试
## 相关概念
- [[测试策略金字塔]]Playwright是E2E测试的工具
- [[Browser_Use]]Playwright和Browser Use的对比
- [[MCP]]Playwright MCP是MCP的一种实现