Playwright 测试中如何暂停
调试用 page.pause() 打开 Playwright Inspector 逐步执行;固定等待用 page.waitForTimeout(毫秒)(仅限调试,正式测试禁用);等待条件用 locator.waitFor() 或 expect 断言。
一句话回答:看你要哪种"暂停":调试时逐步执行用 await page.pause()(弹出 Playwright Inspector,可逐条步进、检查选择器);硬等待固定时间用 await page.waitForTimeout(3000)——但官方明确反对在正式测试里用它;等待某个条件用 locator.waitFor() 或 expect(locator).toBeVisible() 这类自动等待断言。
三种"暂停"按场景选
1. 调试断点:page.pause()
test('调试', async ({ page }) => {
await page.goto('https://example.com');
await page.pause(); // 打开 Inspector,测试停在这里
await page.getByRole('button').click();
});
运行时加 --headed 看到浏览器;Inspector 里可以单步执行、试选择器、看操作日志。CI 里记得移除(或以 PWDEBUG 环境变量控制)。
2. 固定等待:waitForTimeout(仅调试)
await page.waitForTimeout(3000); // 死等 3 秒
它的问题是不问原因地等:元素 0.1 秒出现也等满 3 秒(慢),环境慢了 3 秒又不够(flaky)。正式测试里出现它,几乎都是该换成条件等待的信号。
3. 条件等待(生产测试的正解)
await page.locator('#result').waitFor(); // 等元素出现
await expect(page.locator('#result')).toBeVisible(); // 断言式等待
await page.waitForURL(/\/dashboard/); // 等导航
const responsePromise = page.waitForResponse(r => r.url().includes('/api/list'));
await page.getByRole('button', { name: '加载' }).click();
await responsePromise; // 监听必须先于触发动作,随后仍应断言页面结果
超时设置配套
在 Playwright Test 中,断言默认 5 秒、测试默认 30 秒;动作与导航默认没有单独上限(0),仍受测试总超时约束。不要与独立 Playwright Library 的默认值混淆。调整在 playwright.config.ts:
export default defineConfig({
timeout: 60_000, // 单测试总时长
expect: { timeout: 10_000 }, // 断言超时
use: { actionTimeout: 15_000 }, // 点击等动作超时
});
常见问题(FAQ)
Q:为什么动画场景下断言总是失败?
A:元素可见但还在动,点击落点会偏。Playwright 动作自带稳定性检查(等元素静止),仍失败时优先查是不是 CSS 动画无限循环;应等待业务结束状态,或在测试配置中稳定/禁用动画,不要依靠固定 sleep 掩盖问题。
Q:page.pause() 在 CI 里会卡住吗?
A:page.pause() 要求 headed 模式,不能在无人值守 CI 中依赖它自动跳过。规范做法:if (process.env.PWDEBUG) await page.pause(); 或只在本地调试分支使用。
Q:networkidle 为什么慎用?
A:现代站点有长连接/心跳请求,networkidle 可能永远不触发或大幅拖慢测试。优先等具体接口(waitForResponse)或具体元素。
参考资料
本文依据官方资料核对,未进行现场运行测试;代码与配置示例需结合实际版本、权限和环境验证。