)
本篇笔记主要讲解在网页端如何去定位元素1. 前置知识1. CSS Selector 定位原理HTML 中为某些元素指定显示效果时会用 CSS 选择器选择元素。既然 CSS Selector 天生就是浏览器用来选元素的Playwright 自然也可以用它来做自动化定位。只要 CSS Selector 语法正确Playwright 就能选到目标元素。2. 简介 Locator 定位器Locator 是 Playwright 用来在页面上查找元素的抽象对象。与传的document.querySelector()不同Playwright 的 Locator 具有自动等待和自动重试能力。当页面内容动态变化时Locator 会不断重新查找元素直到找到匹配的元素或超时。3. Locator 的工作原理创建 Locator 时Playwright 只记录了一个查找规则。当你调用.click()、.fill()等操作或expect(locator)断言时Locator 才真正开始查找元素。如果找不到元素Locator 会持续重试直到操作超时为止。4. Locator 定位方式优先级总结按照推荐程度从高到低排列优先级方法使用条件1最推荐getByRole()元素具有明确的 ARIA 角色2getByLabel()表单元素有关联的 label3getByPlaceholder()输入框有 placeholder4getByText()元素有明确的文本内容5getByAltText()图片有 alt 属性6getByTitle()元素有 title 属性7兜底getByTestId()无法用以上方式定位时8最后选择locator()CSS 选择器 / XPathgetByRole()是 Playwright 最推荐的定位方式。它通过元素的可访问性角色ARIA Role来查找元素这是最接近用户感知的方式。2. 如何定位元素1. 按角色定位getByRole()# 定位一个按钮——通过角色 button submit_btn page.get_by_role(button, name提交) await submit_btn.click() #定位一个链接——通过角色 link home_link page.get_by_role(link, name首页) await home_link.click() 定位一个标题——通过角色 heading main_title page.get_by_role(heading, name欢迎使用 RUNOOB) 定位一个文本框——通过角色 textbox search_box page.get_by_role(textbox, name搜索) await search_box.fill(Playwright)常见 ARIA RoleRole对应 HTML 元素使用示例buttonbutton、rolebuttongetByRole(button, { name: 登录 })linkagetByRole(link, { name: 了解更多 })headingh1~h6getByRole(heading, { name: RUNOOB 教程 })textboxinput typetext、textareagetByRole(textbox, { name: 用户名 })checkboxinput typecheckboxgetByRole(checkbox, { name: 记住我 })radioinput typeradiogetByRole(radio, { name: 男 })comboboxselectgetByRole(combobox, { name: 城市 })imgimggetByRole(img, { name: Logo })listul、olgetByRole(list)listitemligetByRole(listitem)navigationnavgetByRole(navigation)tabletablegetByRole(table)name 选项name选项是通过元素的可访问名称来缩小范围。可访问名称的来源包括元素文本内容、aria-label属性、关联的label等。// 通过按钮文本匹配 page.getByRole(button, { name: 登录 }); // 通过 aria-label 匹配 page.getByRole(button, { name: 关闭对话框 }); // 正则表达式匹配 page.getByRole(link, { name: /RUNOOB|xizi/ });状态选项除了namegetByRole还支持多种状态选项// 定位已选中的复选框 page.getByRole(checkbox, { checked: true }); // 定位已禁用的按钮 page.getByRole(button, { disabled: true }); // 定位展开的下拉菜单 page.getByRole(button, { expanded: true }); // 定位选中的选项 page.getByRole(option, { selected: true }); // 组合多个状态 page.getByRole(checkbox, { name: 同意协议, checked: false });2. 按文本定位getByText()getByText()通过元素的文本内容来定位。// 精确匹配文本 page.getByText(欢迎访问 RUNOOB); // 部分匹配默认 page.getByText(RUNOOB); // 强制精确匹配 page.getByText(RUNOOB, { exact: true }); // 正则表达式匹配 page.getByText(/RUNOOB|菜鸟教程/);getByText匹配的是元素的完整文本内容所以getByText(RUNOOB, { exact: true })只会匹配文本内容刚好为 RUNOOB 的元素。默认不做精确匹配时子字符串匹配即可如getByText(RUNOOB)会匹配 欢迎访问 RUNOOB。3. 按标签定位getByLabel()getByLabel()用于定位与label关联的表单控件。// HTML 结构 // label forusername用户名/label // input idusername typetext / // 通过 label 文本定位 input await page.getByLabel(用户名).fill(runoob_user); // HTML 结构 // label密码 input typepassword //label // 嵌套的 label 同样有效 await page.getByLabel(密码).fill(password123);它也支持{ exact: true }精确匹配选项。4. 按占位符定位getByPlaceholder()getByPlaceholder()通过placeholder属性定位输入框。// HTML 结构input placeholder请输入搜索关键词 / await page.getByPlaceholder(请输入搜索关键词).fill(Playwright); // HTML 结构textarea placeholder说说你的想法.../textarea await page.getByPlaceholder(说说你的想法...).fill(RUNOOB 教程很棒);4. getByLabel vs getByPlaceholder 的选择方法适用场景优先级getByLabel()有 label 元素时优先使用getByPlaceholder()没有 label但有 placeholder 时次选getByRole 是 Playwright 最推荐的定位方式因为它模拟用户通过角色识别元素的方式。其次是 getByLabel 和 getByPlaceholder。在没有语义化元素的情况下才考虑使用 getByTestId 或 CSS 选择器。5. getByAltText() 图片定位getByAltText()通过图片的alt属性来定位img元素。// HTMLimg srclogo.png altRUNOOB Logo / await expect(page.getByAltText(RUNOOB Logo)).toBeVisible(); // 正则匹配 await expect(page.getByAltText(/logo/i)).toBeVisible();6. getByTitle() 标题属性定位getByTitle()通过元素的title属性来定位。// HTMLbutton title关闭当前页面X/button await page.getByTitle(关闭当前页面).click();getByAltText和getByTitle使用频率较低仅在元素具有明确的 alt 或 title 属性且无法用其他方式定位时才使用。7.page.locator() CSS 与 XPath 定位page.locator()支持 CSS 选择器和 XPath是更灵活的备用方案。CSS 选择器// 通过 CSS 类名 (class) await page.locator(.submit-btn).click(); // 通过 ID await page.locator(#username).fill(runoob_user); // 通过属性 await page.locator([data-typeprimary]).click(); // 通过标签 类名组合 await page.locator(button.primary).click(); // 通过父子关系 await page.locator(nav a).first().click(); // 包含特定文本的 CSS 选择器 await page.locator(button:has-text(提交)).click();选择子元素和后代元素# 直接子元素一层 page.locator(#container .layer) # 后代元素任意层级 page.locator(#container .item) # 多层嵌套 page.locator(#a #b #c .d)兄弟节点选择相邻兄弟节点用分隔# 紧跟在 h3 后面的 span page.locator(h3 span)非相邻的后续兄弟节点用~分隔# h3 之后的所有同级 span page.locator(h3 ~ span)XPath 定位// 使用 XPath 定位 await page.locator(xpath//button[typesubmit]).click(); // 通过文本定位 await page.locator(xpath//h1[contains(text(), RUNOOB)]).click();3. 相关资料如下Playwright 定位器Locators | 菜鸟教程古法编程之 Playwright 学习笔记 - 飞书云文档