193 lines
4.8 KiB
Markdown
Executable File
193 lines
4.8 KiB
Markdown
Executable File
# Playwright
|
||
|
||
> 相关:[[测试策略金字塔]]、[[Browser_Use]]、[[MCP]]
|
||
|
||
## 定义
|
||
|
||
**Playwright**是最流行的浏览器自动化测试框架,支持Chromium、Firefox、WebKit。
|
||
|
||
**核心思想**:提供稳定、快速的浏览器自动化能力,支持多浏览器、多平台。
|
||
|
||
## 核心特征
|
||
|
||
### 1. 多浏览器支持
|
||
- Chromium(Chrome、Edge)
|
||
- Firefox
|
||
- WebKit(Safari)
|
||
- 一套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的一种实现
|