cypress-react-selector is lightweight plugin to help you to locate web elements in your REACT app using components, props and states.. This extension allow you to select page elements in a way that is native to React. This will help you in functional UI tests and E2E tests.
Internally, cypress-react-selector uses a library called resq to query React's VirtualDOM in order to retrieve the nodes.
npm i --save cypress-react-selector
Update Cypress/support/index.js
file to include the cypress-axe commands by adding:
import 'cypress-react-selector'
- cypress-react-selector supports NodeJS 8 or higher
- Support added for IE, Chrome, Firefox, Safari (IE can break for some complex components)
- It supports React 16
interface Chainable {
react(component: string, props?: {}, state?: {}): Chainable<Element>
}
Lets take this example REACT APP:
// imports
const MyComponent = ({ someBooleanProp }) => (
<div>My Component {someBooleanProp ? 'show this' : ''} </div>
)
const App = () => (
<div id='root'>
<MyComponent />
<MyComponent someBooleanProp={true} />
</div>
)
ReactDOM.render(<App />, document.getElementById('root'))
To wait until the React's component tree is loaded, add the waitForReact
method to fixture's before
hook.
before(() => {
cy.visit('http://localhost:3000/myApp')
cy.waitForReact()
})
this will wait to load react inside your app. By-default it will assume that the react root is set to '#root'. In the example above the id of the root element is set to 'root'. So, you don't need to pass the the root selector
The default timeout for waitForReact
is 10000
ms. You can specify a custom timeout value:
cy.waitForReact(30000)
It is always not true that the root of React app is set to 'root', may be your root element is 'mount', like:
const App = () => (
<div id='mount'>
<MyComponent />
<MyComponent someBooleanProp={true} />
</div>
)
There is some application which displays react components asynchronously. The cypress-react-selector by-default assumes the react root element is set to 'root', if you have different root element, you need to pass that information to the react selector.
// if your react root is set to different selector other than 'root'
// then you don't need to pass root element information
cy.waitForReact(10000, '#mount')
You should have React Develop Tool installed to spy and find out the component name as sometimes components can go though modifications. Once the React gets loaded, you can easily identify an web element by react component name:
cy.react('MyComponent')
// you can have your assertions chained like
it('it should validate react selection with component name', () => {
cy.react('MyComponent').should('have.length', '1')
})
You can filter the REACT components by its props and states like below:
cy.react('MyComponent', { someBooleanProp: true }, { someBooleanState: true })
You can select your components by partial name use a wildcard selectors:
// Partial Match
cy.react('My*', { someBooleanProp: true })
// Entire Match
cy.react('*', { someBooleanProp: true }) // return all components matched with the prop
Checkout sample tests here
React-Dev-Tool — You can inspect the DOM element by simply pressing the f12. But, to inspect REACT components and props, you need to install the chrome plugin.
you can raise any issue here
Any pull request is welcome.
If it works for you , give a Star! ⭐
- Copyright © 2019- Abhinaba Ghosh