选择器
WebDriver 协议提供了多种选择器策略来查询元素。WebdriverIO 简化了这些策略,使选择元素变得简单。请注意,尽管查询元素的命令被称为 $ 和 $$,但它们与 jQuery 或 Sizzle 选择器引擎没有任何关系。
虽然有很多不同的选择器可用,但只有少数几个提供了一种稳健的方式来找到正确的元素。例如,给定以下按钮:
<button
id="main"
class="btn btn-large"
name="submission"
role="button"
data-testid="submit"
>
Submit
</button>
我们__推荐__和__不推荐__以下选择器:
| 选择器 | 推荐 | 说明 |
|---|---|---|
$('button') | 🚨 永不 | 最差 - 太过通用,没有上下文。 |
$('.btn.btn-large') | 🚨 永不 | 不好。与样式 耦合。极易变更。 |
$('#main') | ⚠️ 谨慎使用 | 更好。但仍与样式或JS事件监听器耦合。 |
$(() => document.queryElement('button')) | ⚠️ 谨慎使用 | 有效查询,但编写复杂。 |
$('button[name="submission"]') | ⚠️ 谨慎使用 | 与具有HTML语义的name属性耦合。 |
$('button[data-testid="submit"]') | ✅ 好 | 需要额外属性,不与无障碍功能相连。 |
$('aria/Submit') | ✅ 好 | 好。类似于用户与页面交互的方式。建议使用翻译文件,这样当翻译更新时测试不会中断。注意:此选择器在大页面上可能比其他选择器慢。 |
$('button=Submit') | ✅ 始终 | 最佳。类似于用户与页面交互的方式且速度快。建议使用翻译文件,这样当翻译更新时测试不会中断。 |
CSS 查询选择器
如果没有特别指明,WebdriverIO 将使用 CSS 选择器 模式查询元素,例如:
loading...
链接文本
要获取具有特定文本的锚点元素,请使用以等号(=)开始的文本进行查询。
例如:
loading...
你可以通过以下方式查询该元素:
loading...
部分链接文本
要查找可见文本部分匹配你的搜索值的锚点元素,
可以在查询字符串前使用 *= 进行查询(例如 *=driver)。
你也可以通过以下方式查询上面示例中的元素:
loading...
注意: 你不能在一个选择器中混合使用多种选择器策略。使用多个链式元素查询来达到相同的目标,例如:
const elem = await $('header h1*=Welcome') // 这不起作用!!!
// 应该使用
const elem = await $('header').$('*=driver')
具有特定文本的元素
同样的技术也可以应用于元素。此外,还可以使用 .= 或 .*= 进行不区分大小写的匹配。
例如,这里查询文本为"Welcome to my Page"的一级标题:
loading...
你可以通过以下方式查询该元素:
loading...
或使用查询部分文本:
loading...
同样适用于 id 和 class 名称:
loading...
你可以通过以下方式查询该元素:
loading...
注意: 你不能在一个选择器中混合使用多种选择器策略。使用多个链式元素查询来达到相同的目标,例如:
const elem = await $('header h1*=Welcome') // 这不起作用!!!
// 应该使用
const elem = await $('header').$('h1*=Welcome')
标签名称
要查询具有特定标签名的元素,使用 <tag> 或 <tag />。
loading...
你可以通过以下方式查询该元素:
loading...
Name 属性
要查询具有特定 name 属性的元素,你可以使用普通的 CSS3 选择器或者通过传递类似 [name="some-name"] 的选择器参数来使用 JSONWireProtocol 提供的 name 策略:
loading...
loading...
注意: 这个选择器策略已被弃用,只在由 JSONWireProtocol 协议运行的旧浏览器或使用 Appium 时有效。
xPath
也可以通过特定的 xPath 查询元素。
xPath 选择器的格式如 //body/div[6]/div[1]/span[1]。
loading...
你可以通过以下方式查询第二个段落:
loading...
你可以使用 xPath 在 DOM 树中上下遍历:
loading...
无障碍名称选择器
通过元素的无障碍名称查询元素。无障碍名称是当元素获得焦点时屏幕阅读器宣读的内容。无障碍名称的值可以是可视内容或隐藏的文本替代项。
你可以在我们的发布博客文章中了解更多关于这个选择器的信息
通过 aria-label 获取
loading...
loading...
通过 aria-labelledby 获取
loading...
loading...
通过内容获取
loading...
loading...
通过标题获取
loading...
loading...
通过 alt 属性获取
loading...
loading...
ARIA - Role 属性
要基于 ARIA 角色查询元素,你可以直接将元素的角色指定为选择器参数,如 [role=button]:
loading...
loading...
ID 属性
WebDriver 协议不支持"id"定位策略,应该使用 CSS 或 xPath 选择器策略来通过 ID 查找元素。
但是,一些驱动程序(如 Appium You.i Engine Driver)可能仍支持这种选择器。
当前支持的 ID 选择器语法有:
//css 定位器
const button = await $('#someid')
//xpath 定位器
const button = await $('//*[@id="someid"]')
//id 策略
// 注意:仅在 Appium 或支持"ID"定位策略的类似框架中有效
const button = await $('id=resource-id/iosname')
JS 函数
你还可以使用 JavaScript 函数通过 Web 原生 API 获取元素。当然,你只能在 Web 上下文中(例如,browser,或移动设备中的 Web 上下文)执行此操作。
给定以下 HTML 结构:
loading...
你可以按如下方式查询 #elem 的兄弟元素:
loading...
深度选择器
从 WebdriverIO 的 v9 开始,不再需要这个特殊选择器,因为 WebdriverIO 会自动穿透 Shadow DOM。建议通过去除选择器前面的 >>> 来停止使用此选择器。
许多前端应用程序严重依赖具有 shadow DOM 的元素。在没有变通方法的情况下,技术上不可能查询 shadow DOM 内的元素。shadow$ 和 shadow$$ 是这样的变通方法,但它们有局限性。使用深度选择器,你现在可以使用常见的查询命令查询任何 shadow DOM 内的所有元素。
假设我们有一个具有以下结构的应用程序:

使用此选择器,你可以查询嵌套在另一个 shadow DOM 中的 <button /> 元素,例如:
loading...
移动选择器
对于混合移动测试,重要的是自动化服务器在执行命令前处于正确的上下文中。对于自动化手势,驱动程序理想情况下应设置为原生上下文。但要从 DOM 中选择元素,驱动程序需要设置为平台的 webview 上下文。只有这样才能使用上面提到的方法。
对于原生移动测试,不需要在上下文之间切换,因为你必须使用移动策略并直接使用底层设备自动化技术。当测试需要对查找元素进行精细控制时,这特别有用。
Android UiAutomator
Android 的 UI Automator 框架提供了多种查找元素的方法。你可以使用 UI Automator API,特别是 UiSelector 类来定位元素。在 Appium 中,你将 Java 代码作为字符串发送到服务器,服务器在应用程序的环境中执行它,返回元素或多个元素。
const selector = 'new UiSelector().text("Cancel").className("android.widget.Button")'
const button = await $(`android=${selector}`)
await button.click()
Android DataMatcher 和 ViewMatcher(仅限 Espresso)
Android 的 DataMatcher 策略提供了一种通过 Data Matcher 查找元素的方法
const menuItem = await $({
"name": "hasEntry",
"args": ["title", "ViewTitle"]
})
await menuItem.click()
类似地,View Matcher
const menuItem = await $({
"name": "hasEntry",
"args": ["title", "ViewTitle"],
"class": "androidx.test.espresso.matcher.ViewMatchers"
})
await menuItem.click()
Android View Tag(仅限 Espresso)
视图标签策略提供了一种通过元素的标签查找元素的便捷方法。
const elem = await $('-android viewtag:tag_identifier')
await elem.click()
iOS UIAutomation
在自动化 iOS 应用程序时,可以使用 Apple 的 UI Automation 框架查找元素。
这个 JavaScript API 有方法访问视图及其上的所有内容。
const selector = 'UIATarget.localTarget().frontMostApp().mainWindow().buttons()[0]'
const button = await $(`ios=${selector}`)
await button.click()
你还可以在 Appium 的 iOS UI Automation 中使用谓词搜索,进一步细化元素选择。详情请参阅此处。