React 选择器
ReactJS 是网络上使用最广泛的前端库之一。除了 React 之外,许多开发人员使用样式工具,这些工具将缩小或重写附加到 HTML 元素的类属性值,方法是通过 JSX 中的 className
属性。这些缩小和重写使得难以使用 WebDriver 的查询命令(如 findElement
或 findElements
)来选择生成的 HTML,因为无法保证类名保持不变。
今天,我们在 WebdriverIO 的浏览器对象中引入了两个新命令,browser.react$
和 browser.react$$
,允许您使用易于使用的 API 查询页面中的单个或多个 React 组件实例。这些新命令将为查询返回 WebdriverIO 元素,您可以在其中访问完整的元素命令 API。
用法
在内部,WebdriverIO 使用一个名为resq 的库来查询 React 的虚拟 DOM 以检索节点。此库允许 WebdriverIO 通过组件的名称查找虚拟 DOM 中的任何组件,并通过状态和/或属性过滤此选择。
WebdriverIO 提供的 API,browser.react$
和 browser.react$$
方法有三个参数。第一个参数是要查询的选择器,此参数是必需的。第二个和第三个参数是可选过滤器,分别为 props
和 state
。
const selector = 'MyComponent'
const propFilter = { someProp: true }
const stateFilter = 'this is my state'
browser.react$(selector, {
props: propFilter,
state: stateFilter
})
在示例中,我们将介绍所有三个参数的基本用法。
示例
在以下示例中,我们将针对此示例 React 应用程序进行查询。
// mycomponent.jsx
import React from 'react'
import ReactDOM from 'react-dom'
const MyComponent = (props) => {
const { name } = props;
const [state] = React.useState(name === 'there' ? ', how are you?' : '')
return (
<div>
Hello {name || 'World'}{state}
</div>
)
}
ReactDOM.render(
<div>
<MyComponent />
<MyComponent name="Barry"/>
<MyComponent name="WebdriverIO"/>
<MyComponent name="there"/>
</div>,
document.getElementById('#root'),
)
在此应用程序中,我们有一个组件,它根据传递给它的属性 name
呈现一些文本。
选择和过滤
现在,假设我们要测试 MyComponent
的第一个实例是否在浏览器中正确显示。那么,使用 browser.react$
命令,我们可以选择此第一个实例,然后对其进行查询。
// spec/mycomponent.test.js
test('it should be displayed', () => {
const myComponent = browser.react$('MyComponent')
expect(myComponent.isDisplayed()).toBe(true) // pass
})
很简单,不是吗?但是如果我们想选择显示 Hello WebdriverIO
的组件并验证文本是否正确呢?我们可以过滤我们的查询!
// spec/mycomponent.test.js
test('it should correctly display "Hello WebdriverIO"', () => {
const myComponent = browser.react$('MyComponent', {
props: { name: 'WebdriverIO' }
})
expect(myComponent.getText()).toBe('Hello WebdriverIO') // pass
})
在 React 中,props 始终是一个对象,因此对于此过滤器参数,我们只能传递一个对象来过滤结果。
您可能已经注意到,在我们的组件中,我们有一个状态,如果名称与 there
匹配,则会添加额外的文本。我们可以通过根据其当前状态过滤组件来选择此组件。
// spec/mycomponent.test.js
test('it should correctly display "Hello WebdriverIO"', () => {
const myComponent = browser.react$('MyComponent', {
state: ', how are you?'
})
expect(myComponent.getText()).toBe('Hello there, how are you?') // pass
})
如您所见,对于状态过滤器,我们传递一个与组件当前状态相等的字符串,函数中的最后一个参数可以是以下任何一个:字符串、数字、布尔值、数组或对象。这是因为所有这些类型都是 React 的有效状态类型。
browser.react$$
怎么样?
到目前为止,您可能想知道为什么我们在所有示例中都使用 browser.react$
。这两个命令具有相同的参数并且工作方式几乎相同,**唯一的区别**是 browser.react$$
将返回一个数组,其中包含与选择器和/或过滤器匹配的所有 WebdriverIO 元素。
总结
我们对这次新增功能感到非常满意,希望您能充分利用它。我们建议您使用React Dev Tools,使用此工具将帮助您了解应用程序中的组件是如何调用的、它们有哪些属性以及它们当前处于什么状态。一旦您了解了这些信息,使用 WebdriverIO 的 React API 将变得容易得多。
注意:此博文在 v6 版本发布后进行了更新,以反映对命令接口的更改。