Playwright 页面操作基础(2025 年最新版)
Playwright 的页面操作非常强大且直观,核心优势在于自动等待(Auto-waiting):大多数操作会在元素真正可交互时才执行,无需手动添加 sleep() 或显式等待。下面以 Node.js/TypeScript(Playwright Test 框架)为主进行讲解,同时附上 Python 对应写法。
1. 基本导航操作
// 导航到页面
await page.goto('https://example.com');
// 刷新页面
await page.reload();
// 前进 / 后退
await page.goBack();
await page.goForward();
2. 元素定位(Locators)——最推荐方式
Playwright 强烈推荐使用 Locator 而不是直接的 page.$(),因为 Locator 是惰性求值的,支持自动等待。
// 推荐的现代定位方式(自动等待 + 链式调用)
const button = page.getByRole('button', { name: '提交' }); // 无障碍角色
const link = page.getByText('点击这里'); // 精确文本
const partialLink = page.getByText('点击', { exact: false }); // 部分匹配
const input = page.getByLabel('用户名'); // 标签关联
const placeholder = page.getByPlaceholder('请输入用户名'); // placeholder
const alt = page.getByAltText('logo'); // 图片 alt
const title = page.getByTitle('关闭'); // title 属性
const testId = page.getByTestId('submit-btn'); // data-testid(推荐!)
const css = page.locator('#login-form input[type="password"]'); // 传统 CSS
3. 常用交互操作
// 点击
await page.getByRole('button', { name: '登录' }).click();
// 双击 / 右键
await button.dblclick();
await button.click({ button: 'right' });
// 输入文本
await page.getByLabel('用户名').fill('admin'); // 清空后输入(推荐)
await page.getByLabel('密码').type('123456'); // 逐字符输入(模拟真人)
// 清除输入框
await input.clear();
// 勾选 / 取消勾选 Checkbox 或 Radio
await page.getByRole('checkbox', { name: '记住我' }).check();
await page.getByRole('checkbox').uncheck();
// 下拉选择 Select
await page.getByLabel('国家').selectOption('cn'); // value 值
await page.getByLabel('国家').selectOption({ label: '中国' }); // 可见文本
await page.getByLabel('国家').selectOption({ index: 2 }); // 索引
// 上传文件
await page.getByLabel('上传头像').setInputFiles('path/to/file.jpg');
// 多文件
await input.setInputFiles(['file1.jpg', 'file2.png']);
// 清除上传
await input.setInputFiles([]);
4. 鼠标与键盘操作
// 鼠标悬停
await page.getByText('菜单').hover();
// 拖拽
await page.locator('#source').dragTo(page.locator('#target'));
// 键盘操作
await page.keyboard.press('Enter');
await page.keyboard.press('Control+A'); // 组合键
await page.keyboard.type('Hello World'); // 输入文本
await page.keyboard.down('Shift'); // 按住
await page.keyboard.up('Shift'); // 释放
5. 页面信息获取
// 获取页面标题和 URL
const title = await page.title();
const url = await page.url();
// 获取元素文本
const text = await page.getByRole('heading').textContent();
const allTexts = await page.getByRole('listitem').allTextContents();
// 获取输入框值
const value = await page.getByLabel('用户名').inputValue();
// 获取属性
const href = await page.getByRole('link').getAttribute('href');
6. 截图与录屏
// 全页面截图
await page.screenshot({ path: 'full.png', fullPage: true });
// 元素截图
await page.getByRole('button').screenshot({ path: 'button.png' });
// 录制视频(需在 playwright.config.ts 中启用)
await page.video().saveAs('video.webm');
7. Python 同步版对应示例
# 点击
page.get_by_role("button", name="登录").click()
# 输入
page.get_by_label("用户名").fill("admin")
page.get_by_label("密码").fill("123456")
# 选择下拉
page.get_by_label("国家").select_option("cn")
# 上传文件
page.get_by_label("上传").set_input_files("file.jpg")
# 截图
page.screenshot(path="screenshot.png", full_page=True)
8. 最佳实践建议
- 优先使用 getByRole(无障碍优先,最稳定)。
- 使用 data-testid 属性进行测试专用定位(不依赖文本或结构变化)。
- 所有操作默认自动等待,无需额外 waitFor。
- 复杂操作可链式调用:
await page.getByText('提交').click({ timeout: 5000 });
掌握这些基础操作后,你已经可以处理 90% 的网页交互场景了!下一步建议练习:用 npx playwright codegen 录制一个登录流程,观察生成的代码。
需要更具体的场景示例(如处理弹窗、iframe、Shadow DOM),随时告诉我!