ReactJS is one of the most widely use Front-End libraries in the web. Along side React, many developers use styling tools that will minify or re-write the class attribute values attached to the HTML elements via className
props in JSX. These minifications and overwrites make it difficult to select the generated HTML using the WebDriver's query commands like findElement
or findElements
since it's not guaranteed that the class name will remain the same.
Today we introduce two new commands, browser.react$
and browser.react$$
, to WebdriverIO's browser object that allows you to query for a single or multiple React component instances in the page with an easy to use API. These new commands will return the WebdriverIO element(s) for the query in where you will have access to the complete element commands API.
Usage
Internally, WebdriverIO uses a library called resq to query React's VirtualDOM in order to retrieve the nodes. This library allows WebdriverIO to find any component in the VirtualDOM by the component's name and also filter this selection by state and/or props.
WebdriverIO's provided API, browser.react$
and browser.react$$
, methods have three parameters. The first parameter is the selector to query, this parameter is required. The second and third parameters are optional filters, props
and state
respectively.
const selector = 'MyComponent'
const propFilter = { someProp: true }
const stateFilter = 'this is my state'
browser.react$(selector, {
props: propFilter,
state: stateFilter
})
In the examples we will cover basic usages for all three parameters.
Examples
In the following examples, we will base our queries against this example React application.
// 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'),
)