定位器 Locators 总览与自动等待
本教程共 59 篇 · 第 9 篇 · 更新于 2026-08-04 · 约 10 分钟阅读
本节目标:弄懂定位器(Locator)到底是什么、它为什么天生支持自动等待,以及严格模式(strict mode)在帮你挡什么坑。
定位器是什么
定位器(Locator)是 Playwright 用来在页面上找元素的对象。它不代表「此刻的某个元素」,而是「一种找法」。
关键在这:每次你拿定位器去点、去填,Playwright 都会重新按这个找法去页面上找一遍最新的元素。如果页面重渲染了,它找的就是重渲染后的那个。
const locator = page.getByRole('button', { name: 'Sign in' });
await locator.hover(); // 第一次找
await locator.click(); // 第二次找(拿最新结果)
这就是为什么 Playwright 用例不容易因为「时机不对」而挂。定位器不绑定死节点,永远找活的。
内置定位器一览
下面是官方推荐、按优先级排的定位器:
page.getByRole():按无障碍角色(按钮、标题、链接等)找page.getByText():按文字内容找page.getByLabel():按表单控件的关联标签找page.getByPlaceholder():按输入框占位符找page.getByAltText():按图片的 alt 文本找page.getByTitle():按 title 属性找page.getByTestId():按测试专用标记data-testid找
一个登录场景串起来看:
await page.getByLabel('User Name').fill('John');
await page.getByLabel('Password').fill('secret-password');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByText('Welcome, John!')).toBeVisible();
Note这些创建定位器的方法,在
page、Locator、FrameLocator上都有。所以你可以链式往下缩窄范围,这是后面几章的重点。
自动等待:定位器的隐形护盾
第 1 章提过「自动等待」(Auto-Waiting)。它正是绑在定位器上的。
当你调用 locator.click(),Playwright 会先等一连串可操作性检查(Actionability Checks)通过,才真去点:
- 可见(Visible):元素有尺寸、没被
display:none藏起 - 稳定(Stable):连续两帧位置没动,没在动画中
- 接收事件(Receives Events):没被弹层遮住,点得到
- 可用(Enabled):不是 disabled 状态
不同动作检查项不同。比如 fill 还要额外检查可编辑(Editable,没 readonly)。
// 元素晚 1 秒才出现?click 会自己等到它可见、稳定、可点
await page.getByRole('button', { name: '提交' }).click();
检查一直不通过,动作就一直等,直到超时抛 TimeoutError。
这个「超时」默认不是动作自己的。动作超时 actionTimeout 默认是 0,意思是不单独限制,实际卡在整条用例的 30 秒上限里。
想给单个动作设死线,在配置的 use 里加 actionTimeout,或者调用时传 { timeout: 5000 }。
Tip极少数情况你要绕开检查(比如点一个被遮的透明层),可传
{ force: true }。但这是例外,默认别用。
严格模式:多匹配直接报错
定位器是严格(strict)的。一个操作本该只落到一个元素,却匹配到多个,它会直接抛异常。
// 页面有多个按钮时会报错:strict mode violation
await page.getByRole('button').click();
这反而是好事。它逼你在写代码时就想清楚「我要的是哪一个」,而不是闷头点第一个、留下隐患。
Warning如果你图省事用
locator.first()去「消除报错」,往往点错了元素还不报错。优先写能唯一定位的表达式,而不是用 first/last/nth 硬压。
像 count() 这种「统计类」操作不受严格模式限制,多个元素也能正常数:
const buttonCount = await page.getByRole('button').count(); // 多个也 OK
和断言的自动重试是一回事
自动等待管「动作前」,Web 优先断言管「结果后」。两者思路一致:都先等条件满足。
// 等文字出现,最多等 5 秒(expect 默认超时)
await expect(page.getByText('提交成功')).toBeVisible();
常见的断言有 toBeVisible、toHaveText、toHaveValue、toHaveCount、toHaveAttribute 等。
小结
定位器是「一种找法」,不是「某个元素」。每次操作都重新找一遍,所以天然耐重渲染。
自动等待和可操作性检查,是用例不发脆的根;严格模式则逼你一开始就写出唯一确定的定位。
下一章从最基础的 CSS 选择器讲起,顺带看看 Playwright 给 CSS 加了哪些好用的伪类。