React 選擇器
ReactJS 是網路上最廣泛使用的前端函式庫之一。除了 React 之外,許多開發人員使用樣式工具來縮小或重寫透過 JSX 中的 className
屬性附加到 HTML 元素的類別屬性值。這些縮小和覆寫使得使用 WebDriver 的查詢命令(如 findElement
或 findElements
)選擇產生的 HTML 變得困難,因為無法保證類別名稱保持不變。
今天,我們在 WebdriverIO 的瀏覽器物件中引入了兩個新命令 browser.react$
和 browser.react$$
,讓您可以使用易於使用的 API 在頁面中查詢單個或多個 React 元件實例。這些新命令將傳回查詢的 WebdriverIO 元素,您可以在其中存取完整的元素命令 API。
用法
在內部,WebdriverIO 使用一個名為 resq 的函式庫來查詢 React 的 VirtualDOM,以檢索節點。這個函式庫允許 WebdriverIO 透過元件名稱在 VirtualDOM 中找到任何元件,並透過 state 和/或 props 過濾此選擇。
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
匹配,則會有一個 state 會添加額外的文字。我們可以透過它們的目前 state 來篩選元件來選擇此元件。
// 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
})
正如您所見,對於 state 篩選器,我們傳遞的字串等於元件的目前 state,函式中的最後一個參數可以是以下任何一種:字串、數字、布林值、陣列或物件。這是因為所有這些類型對於 React 來說都是有效的 state 類型。
那 browser.react$$
呢?
到目前為止,您可能想知道為什麼我們在所有範例中都使用 browser.react$
。實際上,這兩個命令具有相同的參數,並且工作方式幾乎相同,**唯一的區別** 在於 browser.react$$
將傳回與選擇器和/或篩選器匹配的所有 WebdriverIO 元素的陣列。
最後的話
我們對此新增功能感到非常高興,並希望您能充分利用它。我們建議您使用 React Dev Tools,使用此工具將有助於您查看應用程式中的元件是如何調用的、它們有哪些 props 以及它們目前處於哪個 state。一旦您了解了這些資訊,使用 WebdriverIO 的 React API 將會容易得多。
注意:這篇部落格文章在 v6 版本發布後進行了更新,以反映命令介面的變更。