cypress-react-selector
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.
Install and configure
Add as a dependency:
npm i --save cypress-react-selector
Include the commands
Update Cypress/support/index.js
file to include the cypress-axe commands by adding:
import "cypress-react-selector";
Alert
- 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
Type Definition
interface Chainable {
react(component: string, props?: {}, state?: {}): Chainable<Element>;
}
How to use React Selector?
Lets take this example REACT APP:
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"));
Wait for application to be ready to run tests
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);
Wait to Load React for different react roots
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 name={"John"} />
</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.
cy.waitForReact(10000, "#mount");
Find Element by React Component
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");
it("it should validate react selection with component name", () => {
cy.react("MyComponent").should("have.length", "1");
});
Element filtration by Props and States
You can filter the REACT components by its props and states like below:
cy.react(componentName, { propName: propValue }, { stateName: stateValue });
cy.react("MyComponent", { name: "John" });
Wildcard selection
You can select your components by partial name use a wildcard selectors:
cy.react("My*", { name: "John" });
cy.react("*", { name: "John" });
Find element by nested props
Let's suppose you have an Form component
<Form>
<Field name="email" type="email" component={MyTextInput} />
<ErrorMessage name="email" component="div" />
<br />
<Field type="password" name="password" component={MyTextInput} />
<ErrorMessage name="password" component="div" />
<br />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
And MyTextInput component is developed as:
const MyTextInput = (props) => {
const { field, type } = props;
return (
<input {...field} type={type} placeholder={"ENTER YOUR " + field.name} />
);
};
then you can use cypress-react-selector to identify the element with nested props
it("enter data into the fields", () => {
cy.react("MyTextInput", { field: { name: "email" } }).type(
"john.doe@cypress.com"
);
cy.react("MyTextInput", { field: { name: "password" } }).type("whyMe?");
});
Sample Tests
Checkout sample tests here
Use React Dev Tools plugin to easily identify the react component, props and state. Have a look in the below demonstration, how I have used the tool to write the sample test cases.
Sample Example Project
Credit goes to gregfenton for presenting a great example that uses Cypress-React-Selector. Checkout the work here
Tool You Need
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.
Tell me your issues
you can raise any issue here
Contribution
Any pull request is welcome.
If this plugin helps you in your automation journey, choose to Sponsor
If it works for you , give a Star! :star:
- Copyright © 2019- Abhinaba Ghosh