Playwright常用使用案例代码(Node.js)

一、页面导航

1. 基本导航

1
2
3
4
5
6
7
8
9
10
11
const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
// 等待页面加载完成
await page.waitForLoadState('networkidle');
console.log(await page.title());
await browser.close();
})();

2. 页面跳转与返回

1
2
3
4
5
6
7
8
// 导航到新页面
await page.goto('https://example.com');
// 前进
await page.goForward();
// 后退
await page.goBack();
// 刷新页面
await page.reload();

二、元素交互

1. 点击操作

1
2
3
4
5
6
7
8
9
10
11
// 基本点击
await page.click('button#submit');

// 双击
await page.dblclick('.item');

// 右键点击
await page.click('div.context-menu', { button: 'right' });

// 悬停
await page.hover('#menu');

2. 输入操作

1
2
3
4
5
6
7
8
// 快速填充
await page.fill('input[name="username"]', 'testuser');

// 模拟键盘输入
await page.type('#search', 'Playwright', { delay: 100 });

// 清空输入框
await page.locator('input#email').clear();

3. 拖拽操作

1
2
3
4
5
// 元素拖拽
await page.dragAndDrop('#item', '#dropzone');

// 坐标拖拽
await page.locator('#slider').dragTo({ x: 200, y: 0 });

三、表单填写

1. 文本输入

1
2
3
4
5
6
7
8
// 文本输入
await page.getByRole('textbox').fill('Peter');

// 日期输入
await page.getByLabel('Birth date').fill('2020-02-02');

// 时间输入
await page.getByLabel('Appointment time').fill('13:15');

2. 复选框与单选按钮

1
2
3
4
5
6
7
8
// 勾选复选框
await page.getByLabel('I agree to the terms').check();

// 取消勾选
await page.getByLabel('Subscribe to newsletter').uncheck();

// 选择单选按钮
await page.getByLabel('XL').check();

3. 下拉选择

1
2
3
4
5
6
7
8
// 通过值选择
await page.getByLabel('Choose a color').selectOption('blue');

// 通过标签选择
await page.getByLabel('Choose a color').selectOption({ label: 'Blue' });

// 多选
await page.getByLabel('Choose multiple colors').selectOption(['red', 'green', 'blue']);

四、截图功能

1. 页面截图

1
2
3
4
5
6
7
8
9
10
11
12
// 截取当前视口
await page.screenshot({ path: 'screenshot.png' });

// 截取全屏
await page.screenshot({ path: 'fullpage.png', fullPage: true });

// 截取指定区域
await page.screenshot({
path: 'partial.png',
clip: { x: 50, y: 50, width: 400, height: 300 }
});

2. 元素截图

1
2
3
const element = page.locator('.card');
await element.screenshot({ path: 'element.png' });

五、网络请求处理

1. 请求拦截与模拟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 拦截API请求并返回模拟数据
await page.route('**/api/users', route => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify([{ id: 1, name: 'John Doe' }])
});
});

// 拦截并修改请求
await page.route('**/*.png', route => {
// 中止图片请求
route.abort();
});

2. 监听请求和响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 监听所有请求
page.on('request', request => {
console.log(`Request: ${request.method()} ${request.url()}`);
});

// 监听所有响应
page.on('response', response => {
console.log(`Response: ${response.status()} ${response.url()}`);
});

// 等待特定响应
const [response] = await Promise.all([
page.waitForResponse('**/api/data'),
page.click('button#load-data')
]);
const data = await response.json();

3. 修改请求头

1
2
3
4
5
6
7
8
await page.route('**/*', async route => {
const headers = {
...route.request().headers(),
'X-Custom-Header': 'value'
};
await route.continue({ headers });
});

六、高级操作

1. 处理弹出窗口

1
2
3
4
5
6
7
8
// 等待弹出窗口
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.click('a[target="_blank"]')
]);
await popup.waitForLoadState();
console.log(await popup.title());

2. 模拟设备

1
2
3
4
5
6
7
8
9
10
const { devices } = require('playwright');
const iPhone = devices['iPhone 13'];

const context = await browser.newContext({
...iPhone,
locale: 'en-US'
});
const page = await context.newPage();
await page.goto('https://example.com');

3. 执行JavaScript

1
2
3
4
5
6
7
8
9
10
11
// 执行简单表达式
const title = await page.evaluate(() => document.title);

// 传递参数
const result = await page.evaluate((a, b) => {
return a + b;
}, 1, 2);

// 获取元素属性
const value = await page.evaluate(el => el.value, page.locator('input#username'));

参考资源