2026-03-13
Playwright
00
请注意,本文编写于 31 天前,最后修改于 31 天前,其中某些信息可能已经过时。

目录

前言
一. 内置定位器
1. page.getbyrole(role, **options)通过显式和隐式辅助功能属性定位,返回的是一个Locator 对象
(1).参数role:元素在 Accessibility Tree 中的角色
(2).参数name:可访问的元素的名称
(3).参数exact:控制 name 是否完全匹配
(4).其他参数
2. page.getbytext()通过文本内容定位。
(1).参数text:
(2).参数exact:控制 text 是否完全匹配
3. page.getbylabel()通过关联标签的文本定位表单控件。
(1).参数text:表示label 的文本,表单控件的文本。
(2).参数exact:控制 text 是否完全匹配。
4. page.getbyplaceholder()通过占位符定位输入框。
(1).参数text:表示Placeholder的属性值。
(2).参数exact:控制 text 是否完全匹配。
5. page.getbyalt_text()通过文本替代信息定位元素(通常是图像)。。
6. page.getbytitle()通过 title 属性定位元素。
7. page.getbytest_id()根据data-testid元素的属性定位元素。
二. 其他定位方式
1. CSS定位
2. Xpath表达式定位
3. 定位方式推荐顺序
4. 真伪控件的判断
1. 常见的真控件特点
2. 常见UI组件伪控件的特点

前言

 playwright有自己强大的内置定位器,也支持传统的Xpath与CSS定位,本次以课堂派登录页为例子进行详细的定位方法测试。

一. 内置定位器

1. page.get_by_role(role, **options)通过显式和隐式辅助功能属性定位,返回的是一个Locator 对象

(1).参数role:元素在 Accessibility Tree 中的角色

常见的role类型,如下: | role | HTML示例 | 说明 | | -------- | ------------------------- | ----- | | button | `<button>` | 按钮 | | link | `<a>` | 链接 | | textbox | `<input>` / `<textarea>` | 文本输入框 | | checkbox | `<input type="checkbox">` | 复选框 | | radio | `<input type="radio">` | 单选框 | | combobox | `<select>` | 下拉框 | | heading | `<h1>`~`<h6>` | 标题 | | dialog | `<dialog>` / modal | 弹窗 | | img | `<img>` | 图片 | | table | `<table>` | 表格 |

(2).参数name:可访问的元素的名称

可访问文本的标签优先级: | 优先级 | 来源 | | --- | ------------------------------- | | 1 | `aria-labelledby` | | 2 | `aria-label` | | 3 | `<label>` 标签 | | 4 | 元素文本内容 | | 5 | 其他控件如:placeholder |

则根据上述两点,账号输入框、密码输入框、登录按钮定位表达式如下:

python
page.get_by_role("textbox", name="请输入邮箱/手机号/账号").fill("") page.get_by_role("textbox", name="请输入密码").fill("") page.get_by_role("button", name="登录").click()

(3).参数exact:控制 name 是否完全匹配

| 值 | 描述 | | --- | ------------------------------- | |True | 要求元素名称与name完全一致 | |False| 不要求完全一致,元素名称包含name即可 |

则之前的表达式可做如下修改:

python
page.get_by_role("textbox", name="邮箱/手机号/账号", exact=False).fill("") page.get_by_role("textbox", name="密码", exact=False).fill("") page.get_by_role("button", name="登录").click()

(4).其他参数

参数类型作用
checkedboolcheckbox/radio状态
pressedbool按钮是否处于 pressed 状态
selectedbooloption/tab选中
expandedbool是否展开
levelintheading等级
disabledbool是否禁用

2. page.get_by_text()通过文本内容定位。

(1).参数text:

 注意该函数仅匹配DOM中的“可见文本节点”,而无法匹配placeholder中的内容,因为后者是HTML属性,不是文本节点。

(2).参数exact:控制 text 是否完全匹配

| 值 | 描述 | | --- | ------------------------------- | |True | 要求元素名称与name完全一致 | |False| 不要求完全一致,元素名称包含name即可 |

使用该定位方式后的登录脚本则可修改为:

python
page.get_by_role("textbox", name="邮箱/手机号/账号", exact=False).fill("") page.get_by_role("textbox", name="密码", exact=False).fill("") page.get_by_text("登录", exact=True).click()

相关信息

一个 HTML 元素通常由三部分组成:

开始标签 + 属性 + 文本节点 + 结束标签 例如: <button class="login-btn">登录</button>
部分类型示例
<button>标签(HTML元素)button
class="login-btn"HTML属性class
登录文本节点text node
</button>结束标签button

<input type="text" placeholder="请输入邮箱">

属性包括:

属性
typetext
placeholder请输入邮箱
classel-input__inner

3. page.get_by_label()通过关联标签的文本定位表单控件。

(1).参数text:表示label 的文本,表单控件的文本。

(2).参数exact:控制 text 是否完全匹配。

| 值 | 描述 | | --- | ------------------------------- | |True | 要求元素名称与name完全一致 | |False| 不要求完全一致,元素名称包含name即可 |

 这里以登录页面的“下次自动登录”进行举例,值得注意的是,该元素可以通过该方法定位到,但定位到的元素却无法进行点击操作,对于定位到的元素能否被点击,playwright有自己的一套判断标准,在这里不进行展开:

python
pct = page.get_by_label("下次自动登录").count() print("找到存在label标签的元素{}".format(pct)) >>> 1

4. page.get_by_placeholder()通过占位符定位输入框。

 使用标签中Placeholder的属性值进行定位:

(1).参数text:表示Placeholder的属性值。

(2).参数exact:控制 text 是否完全匹配。

 使用该定位方式后的登录脚本则可修改为:

python
page.get_by_placeholder("邮箱/手机号/账号", exact=False).fill("") page.get_by_placeholder("密码", exact=False).fill("") page.get_by_text("登录", exact=True).click()

5. page.get_by_alt_text()通过文本替代信息定位元素(通常是图像)。。

 使用元素中的alt的属性值来进行定位(该元素通常是图像),由于登录页无该元素,在这里引用playwright官方文档中的例子进行说明:

html
<img alt="playwright logo" src="/img/playwright-logo.svg" width="100" />
python
page.get_by_alt_text("playwright logo").click()

6. page.get_by_title()通过 title 属性定位元素。

 依旧使用playwright官方文档中的例子进行说明:

html
<span title='Issues count'>25 issues</span>
python
page.get_by_title("Issues count").click()

7. page.get_by_test_id()根据data-testid元素的属性定位元素。

 专门用于通过 开发者预先在页面上标记的属性 来快速、稳定地定位元素。该标记旨在提高跨团队协作的效率。

html
<input data-testid="login-username" placeholder="请输入账号">
python
ppage.get_by_test_id("login-username").fill("admin")

二. 其他定位方式

1. CSS定位

 Playwright在原生的CSS的基础上新增了一些伪类选择器,如下:

伪类作用示例
:visible匹配可见元素button:visible
:has-text()匹配包含指定文本button:has-text("Login")
:has()匹配包含指定子元素div:has(button)
nth=第N个元素
:nth-match()第 N 个匹配元素:nth-match(button,3)

 结合上述定位方式后的登录脚本则可修改为:

python
page.locator("input").locator("nth=0").fill("") page.locator("input").locator("nth=1").fill("") page.locator("button:has-text('登录')").click()

相关信息

伪类:一种用于描述元素特定状态或特征的CSS选择器,语法特点是以“:”开头,作用是满足某种条件是匹配元素,关于常见的CSS伪类请移步CSS 伪类

2. Xpath表达式定位

 常见的Xpath表达式:

语法含义示例
//任意层级查找//div
/直接子节点/html/body/div
@属性//input[@id='username']
text()文本//button[text()='Login']
contains()包含//div[contains(@class,'login')]
管道运算符(Union)合并多个 XPath 查询结果//button | //a(匹配 button 或 a)

 结合上述定位方式后的登录脚本则可修改为:

python
page.locator('//input[@placeholder="请输入邮箱/手机号/账号"]').fill("") page.locator('//input[@placeholder="请输入密码"]').fill("") page.locator('//button[./span="登录"]').click()

3. 定位方式推荐顺序

 Playwright的官方文档强调优先使用内置定位,原因是内置定位方式更接近用户行为,定位方便,稳定性高,维护成本低,综合衡量我推荐的元素定位顺序如下:

  1. get_by_role():基本可定位大部分元素,可选参数众多。
  2. get_by_label()/get_by_placeholder()/get_by_text()/get_by_test_id()/get_by_title()/get_by_alt_text():比较挑元素的特有属性,有针对性的定位。
  3. CSS定位:定位速度快,但定位语义较复杂,且依赖DOM结构,稳定性较内置定位较差。
  4. Xpath定位:定位速度较慢,不稳定。

4. 真伪控件的判断

 在元素定位的过程中,我们经常会遇到这种情况:元素可以定位的到,但是无法对其进行点击、输入等操作,然后我们就会往外层找一点/往里层找一点,直到能进行操作为止,较为耗时间,有没有什么方法能够大致的判断出该节点是否可交互,我的经验是尽量定位真控件而不是伪控件

1. 常见的真控件特点

控件类型HTML标签
输入框input
按钮button
下拉框select
复选框input type="checkbox"
单选框input type="radio"

2. 常见UI组件伪控件的特点

class特征组件
el-ElementUI
ant-Ant Design
mui-Material UI
v-Vue组件

本文作者:精卫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!