Playwright 第6章:页面操作基础
页面操作是 Playwright 自动化的核心。本章详细介绍页面导航、元素交互方法以及 Playwright 自动等待机制,帮助您编写可靠的自动化脚本。
页面导航与跳转
goto() 方法详解
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
// 基本导航
await page.goto('https://example.com');
// 完整配置
await page.goto('https://example.com', {
url: 'https://example.com',
waitUntil: 'networkidle',
timeout: 30000,
referer: 'https://google.com',
});
// 相对路径(需要配置 baseURL)
// playwright.config.ts 中 use: { baseURL: 'http://localhost:3000' }
await page.goto('/login');
await page.goto('/products?id=123');
await browser.close();
页面导航相关方法
const page = await browser.newPage();
// 前进/后退
await page.goBack();
await page.goForward();
// 重新加载
await page.reload();
await page.reload({ waitUntil: 'networkidle' });
// 获取当前 URL
const currentUrl = page.url();
console.log('当前URL:', currentUrl);
// 等待导航完成
await page.waitForURL('**/dashboard');
await page.waitForURL(url => url.includes('success'));
元素交互方法
点击操作
// 基本点击
await page.click('button.submit');
// 使用定位器
await page.locator('#login-btn').click();
// 点击选项
await page.click('.menu-item', {
button: 'right', // 右键点击
clickCount: 2, // 双击
delay: 100, // 按下与释放的延迟
position: { x: 10, y: 20 }, // 相对元素偏移
modifiers: ['Shift'], // 组合键
force: true, // 强制点击(绕过可操作性检查)
timeout: 5000, // 超时时间
});
// 双击
await page.dblclick('.item');
// 右键点击
await page.click('.item', { button: 'right' });
// Shift+点击
await page.click('.item', { modifiers: ['Shift'] });
文本输入
// fill() 方法:清空原内容后输入
await page.fill('#username', 'admin');
await page.fill('#username', ''); // 清空输入
// type() 方法:逐字符输入(模拟真实打字)
await page.type('#search', 'Playwright', { delay: 50 });
// 清除内容
await page.locator('#username').clear();
// 设置文件输入
await page.setInputFiles('#avatar', 'photo.jpg');
// 聚焦元素
await page.focus('#username');
// 获取值
const value = await page.inputValue('#username');
选择操作
// 单选框/复选框
await page.check('#agree'); // 勾选
await page.uncheck('#agree'); // 取消勾选
const isChecked = await page.isChecked('#agree');
// 下拉选择框
await page.selectOption('#country', 'china'); // 按 value 选择
await page.selectOption('#country', { label: '中国' }); // 按文本选择
await page.selectOption('#country', { index: 2 }); // 按索引选择
await page.selectOption('#colors', ['red', 'blue']); // 多选
// 获取选择状态
const selectedValue = await page.$eval('#country', el => el.value);
const selectedOptions = await page.locator('#country').inputValue();
获取元素状态
const button = page.locator('.submit-btn');
// 可见性
await expect(button).toBeVisible();
const isVisible = await button.isVisible();
// 启用状态
await expect(button).toBeEnabled();
const isEnabled = await button.isEnabled();
// 存在状态
await expect(button).toBeAttached();
const isAttached = await button.isAttached();
// 已勾选
const isChecked = await button.isChecked();
// 已禁用
const isDisabled = await button.isDisabled();
// 只读
const isEditable = await button.isEditable();
等待策略
自动等待
Playwright 在执行操作前会自动等待元素满足条件:
// 点击前自动等待:
// 1. 元素附加到 DOM
// 2. 元素可见
// 3. 元素稳定(无动画、过渡)
// 4. 元素接收事件(不被遮挡)
// 5. 元素启用
await page.click('.submit-btn');
显式等待
// 等待元素可见
await page.waitForSelector('.loading-done', { state: 'visible' });
// 等待元素消失
await page.waitForSelector('.spinner', { state: 'hidden' });
// 等待特定时间(不推荐)
await page.waitForTimeout(2000);
// 等待网络空闲
await page.waitForLoadState('networkidle');
// 等待自定义条件
await page.waitForFunction(() => {
return document.querySelectorAll('.item').length >= 10;
}, { timeout: 10000 });
页面信息获取
const page = await browser.newPage();
await page.goto('https://example.com');
// 页面标题
const title = await page.title();
// 页面内容
const content = await page.content();
// 页面文本
const bodyText = await page.locator('body').innerText();
// 页面 URL
const url = page.url();
// 获取特定元素的文本
const headerText = await page.locator('h1').textContent();
// 获取属性
const className = await page.locator('.main').getAttribute('class');
const href = await page.locator('a').getAttribute('href');
// HTML 内容
const html = await page.locator('#main').innerHTML();
console.log({
title,
url,
headerText,
});
页面交互综合示例
import { chromium } from 'playwright';
async function loginFlow() {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
try {
// 导航到登录页
await page.goto('https://example.com/login', {
waitUntil: 'networkidle',
});
// 等待表单加载
await page.waitForSelector('#login-form', { state: 'visible' });
// 填写用户名和密码
await page.fill('#username', 'testuser');
await page.fill('#password', 'TestPass123!');
// 勾选"记住我"
await page.check('#remember-me');
// 提交表单
await page.click('button[type="submit"]');
// 等待跳转到首页
await page.waitForURL('**/dashboard', { timeout: 10000 });
// 验证登录成功
const welcomeText = await page.locator('.welcome-message').textContent();
console.log('登录成功:', welcomeText);
return true;
} catch (error) {
console.error('登录失败:', error);
await page.screenshot({ path: 'login-error.png' });
return false;
} finally {
await browser.close();
}
}
loginFlow();
总结
页面操作是 Playwright 自动化的基础。理解自动等待机制是编写稳定测试的关键,推荐优先使用定位器方法(page.locator())而非直接的选择器方法。fill() 是输入文本的首选方法,click() 支持丰富的选项参数满足各种点击场景。在实际项目中,建议将页面操作封装为 Page Object 以提高代码复用性。