cypress-react-unit-test

Unit test React components using Cypress


Keywords
react, cypress, cypress-io, test, testing, cypress-component-testing
License
MIT
Install
npm install cypress-react-unit-test@4.17.1

Documentation

cypress-react-unit-test CircleCI Cypress.io tests renovate-app badge This project is using Percy.io for visual regression testing.

A little helper to unit test React components in the open source Cypress.io E2E test runner ALPHA

TLDR

Known problems

  • some DOM events are not working when running all tests at once #4
  • cannot mock server XHR for injected components #5
  • cannot spy on window.alert #6

Install

Requires Node version 8 or above.

npm install --save-dev cypress cypress-react-unit-test

If you need help configuring bundler, see preprocessors info

Use

Include this plugin from cypress/support/index.js

import 'cypress-react-unit-test'

This adds a new command cy.mount that can mount a React component. It also overloads cy.get to accept in addition to selectors React component, returning it. See examples below.

Example

// load Cypress TypeScript definitions for IntelliSense
/// <reference types="cypress" />
// import the component you want to test
import { HelloState } from '../../src/hello-x.jsx'
import React from 'react'
describe('HelloState component', () => {
  it('works', () => {
    // mount the component under test
    cy.mount(<HelloState />)
    // start testing!
    cy.contains('Hello Spider-man!')
    // mounted component can be selected via its name, function, or JSX
    // e.g. '@HelloState', HelloState, or <HelloState />
    cy.get(HelloState)
      .invoke('setState', { name: 'React' })
    cy.get(HelloState)
      .its('state')
      .should('deep.equal', { name: 'React' })
    // check if GUI has rerendered
    cy.contains('Hello React!')
  })
})

Unit testing React components

styles

You can add individual style to the mounted component by passing its text as an option

it('can be passed as an option', () => {
  const style = `
    .component-button {
      display: inline-flex;
      width: 25%;
      flex: 1 0 auto;
    }

    .component-button.orange button {
      background-color: #F5923E;
      color: white;
    }
  `
  cy.mount(<Button name='Orange' orange />, null, { style })
  cy.get('.orange button')
    .should('have.css', 'background-color', 'rgb(245, 146, 62)')
})

Often your component rely on global CSS style imported from the root index.js or app.js file

// index.js
import './styles.css'
// bootstrap application

You can read the CSS file and pass it as style option yourself

cy.readFile('cypress/integration/Button.css')
  .then(style => {
    cy.mount(<Button name='Orange' orange />, null, { style })
  })

You can even let Cypress read the file and inject the style

const cssFile = 'cypress/integration/Button.css'
cy.mount(<Button name='Orange' orange />, null, { cssFile })

See cypress/integration/inject-style-spec.js for more examples.

Configuration

If your React and React DOM libraries are installed in non-standard paths (think monorepo scenario), you can tell this plugin where to find them. In cypress.json specify paths like this:

{
  "env": {
    "cypress-react-unit-test": {
      "react": "node_modules/react/umd/react.development.js",
      "react-dom": "node_modules/react-dom/umd/react-dom.development.js"
    }
  }
}

Transpilation

How can we use features that require transpilation? By using @cypress/webpack-preprocessor - see the plugin configuration in cypress/plugins/index.js

Examples

All components are in src folder. All tests are in cypress/integration folder.

Large examples

Development

To get started with this repo, compile the plugin's code and the examples code

npm run transpile
npm run build
npm run cy:open
  • run TypeScript compiler in watch mode with npx tsc -w
  • run Cypress with npx cypress open and select the spec you want to work with
  • edit lib/index.ts where all the magic happens

Visual testing

Uses Percy.io visual diffing service as a GitHub pull request check.

Related tools

Same feature for unit testing components from other frameworks using Cypress