All Projects → abhinaba-ghosh → Cypress React Selector

abhinaba-ghosh / Cypress React Selector

Licence: mit
⚡️ cypress plugin to locate react elements by component, props and state

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Cypress React Selector

React Fontawesome
A React Font Awesome component.
Stars: ✭ 662 (+447.11%)
Mutual labels:  props, component
Doctor
quick and easy documentation of Vue.js components - DEPRECATED
Stars: ✭ 227 (+87.6%)
Mutual labels:  props, component
Aura.ui
A Library with a lot of Controls for AvaloniaUI
Stars: ✭ 114 (-5.79%)
Mutual labels:  component
Vue Datatables Net
Vue jQuery DataTables.net wrapper component
Stars: ✭ 119 (-1.65%)
Mutual labels:  component
Zoid
Cross domain components
Stars: ✭ 1,672 (+1281.82%)
Mutual labels:  component
Sakuli
Sakuli is an end-2-end testing and monitoring tool for web sites and common UIs with multiple monitoring integrations
Stars: ✭ 115 (-4.96%)
Mutual labels:  e2e
Ka Table
Lightweight MIT React Table component for both TS and JS with Sorting, Filtering, Grouping, Virtualization, Editing and many more
Stars: ✭ 117 (-3.31%)
Mutual labels:  component
Mayre
Maybe render a React component, maybe not 😮
Stars: ✭ 114 (-5.79%)
Mutual labels:  component
Verte
🎨 A Color picker component. Built from the bottom to work with Vue.js.
Stars: ✭ 117 (-3.31%)
Mutual labels:  component
Vue Range Slider
Simple slider component of Vue.js
Stars: ✭ 117 (-3.31%)
Mutual labels:  component
Calendar
📆 calendar 日历
Stars: ✭ 119 (-1.65%)
Mutual labels:  component
Dappeteer
🏌🏼‍E2E testing for dApps using Puppeteer + MetaMask
Stars: ✭ 117 (-3.31%)
Mutual labels:  e2e
React Magnifier
🔍 React image zoom component
Stars: ✭ 116 (-4.13%)
Mutual labels:  component
React Timer Hook
React timer hook
Stars: ✭ 118 (-2.48%)
Mutual labels:  component
React Workshop
⚒ 🚧 This is a workshop for learning how to build React Applications
Stars: ✭ 114 (-5.79%)
Mutual labels:  props
Polyfill Iconv
This component provides a native PHP implementation of the php.net/iconv functions.
Stars: ✭ 1,621 (+1239.67%)
Mutual labels:  component
React Relative Portal
React component for place dropdowns outside overflow: hidden; elements
Stars: ✭ 114 (-5.79%)
Mutual labels:  component
Vcomponents
VComponents is a SwiftUI framework that contains 40+ customizable UI components
Stars: ✭ 117 (-3.31%)
Mutual labels:  component
React Spring Slider
A slider component for react
Stars: ✭ 118 (-2.48%)
Mutual labels:  component
Container Query
A PostCSS plugin and Javascript runtime combination, which allows you to write container queries in your CSS the same way you would write media queries.
Stars: ✭ 119 (-1.65%)
Mutual labels:  component

cypress-react-selector

Build Status NPM release code style: prettier NPM Downloads

cypress-react-selector is a 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.

Table of Contents

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-react-selector commands by adding:

import 'cypress-react-selector';

TSConfig Settings for types

{
  "compilerOptions": {
    "sourceType": "module",
    "types": ["node", "cypress", "cypress-react-selector"]
  }
}

Alert

  • V2.0.0 is breaking change. Find more on CHANGELOG
  • cypress-react-selector supports NodeJS 8 or higher
  • It supports React 16 or higher

How to use React Selector?

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'));

Wait for application to be ready to run tests

cypress-react-selector needs the react root css-selector information to identify

  • Whether React has loaded
  • Retry React identification queries if state changes in run time/React loads asynchronously

In order to make sure that the React component tree has loaded, add the waitForReact call immediately after loading a page. Here is an example where it's done in the fixture's before hook.

before(() => {
  cy.visit('http://localhost:3000/myApp');
  cy.waitForReact(1000, '#root'); // 1000 is the timeout in milliseconds, you can provide as per AUT
});

NOTE : The Best Configuration for React root is to declare it as an env variable

We always recommend to declare the react root as a env variable in the cypress.json file. It is a best approach rather than passing react root information to waitForReact method every time.

As an example:

{
  "env": {
    "cypress-react-selector": {
      "root": "#root"
    }
  }
}

If you choose to declare the root selector as a configuration, then you will have the freedom to call waitForReact method without passing the root parameter.

before(() => {
  cy.visit('http://localhost:3000/myApp');
  cy.waitForReact();
});

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');

// you can have your assertions chained like
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, reactOpts);

// ReactOpts:
//{
//  props: { someProp: someValue },
//  state: { someState: someValue },
//  exact: boolean
//}

// for the example APP
cy.react('MyComponent', { props: { name: 'John' } });

Deep Matching with exact flag

If you are in need of matching exactly every property and value in the object (or nested objects), you can pass the exact flag to the cy.react or cy.getReact function:

cy.react('MyComponent', { props: { name: 'John' }, exact: true });

Make sure all the props and/or state are listed while using this flag, if not matched it will return undefined

Wildcard selection

You can select your components by partial name use a wildcard selectors:

// Partial Match
cy.react('My*', { props: { name: 'John' } });

// Entire Match
cy.react('*', { props: { name: 'John' } }); // return all components matched with the prop

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', { props: { field: { name: 'email' } } }).type(
    '[email protected]'
  );
  cy.react('MyTextInput', { props: { field: { name: 'password' } } }).type(
    'whyMe?'
  );
});

Get React Properties from element

Let's take same Form example

Get Props

You can get the React properties from a React element and validate the properties run time.

// set the email in the form
cy.react('MyTextInput', { props: { field: { name: 'email' } } }).type(
  '[email protected]'
);

// validate the property runtime
cy.getReact('MyTextInput', { props: { field: { name: 'email' } } })
  .getProps('fields.value')
  .should('eq', '[email protected]');

// to get all the props, simply do not pass anything in getProps() method
cy.getReact('MyTextInput', { props: { field: { name: 'email' } } }).getProps();

get-props

Get current state

cy.getReact('MyTextInput', {
  props: { field: { name: 'email' } },
}).getCurrentState(); // can return string | boolean | any[] | {}

Timeouts

You can configure the timeouts in the cypress.json configuration file. Alternatively, you can also pass the timeout as a object literal in the react commands like,

cy.react('MyComponent', { options: { timeout: 50000 } });

Fetch indexed node

  1. cy.react returns DOM element, so you can fetch the indexed node by .eq(index), like:
cy.react('MyComponent').eq(0).click();
  1. cy.getReact() return RESQ node, so you can't fetch it through .eq(). You need to use .nthNode(index), like:
cy.getReact('MyComponent')
  .nthNode(0)
  .getProps('name')
  .should('eq', 'First Item');

Use fluent chained queries

⚠️ Fluent commands are not working in some special cases. It is being tracked here

You can chain react-selector queries like:

  • fetch HTMLElements by chained react queries
cy.react('MyComponent', { props: { name: 'Bob' } })
  .react('MyAge')
  .should('have.text', '50');
  • fetch react props and states by chained getReact query
cy.getReact('MyComponent', { props: { name: 'Bob' } })
  .getReact('MyAge')
  .getProps('age')
  .should('eq', '50');

Sample Tests

  • Checkout basic tests here (where React-root is passed from waitForReact method)
  • Checkout Complex tests here (React-root configured as env parameter)

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.

Community Projects

  • Credit goes to Gleb Bahmutov for drafting how cypress-react-selector can be used in react unit testing here

  • Credit goes to gregfenton for presenting a formik form 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.

Before you go

If it works for you , give a Star! ⭐️

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].