Skip to content
This repository has been archived by the owner on Jul 5, 2019. It is now read-only.

softwareventures/cypress-preact-unit-test

Repository files navigation

cypress-preact-unit-test Build Status renovate-app badge

A little helper to unit test Preact 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 6 or above.

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

If you need help configuring bundler, see preprocessors info

Use

Include this plugin from cypress/support/index.js

import 'cypress-preact-unit-test'

This adds a new command cy.mount that can mount a Preact component. It also overloads cy.get to accept in addition to selectors Preact 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 {h} from 'preact';
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 Preact components

Configuration

If your Preact library is installed in a non-standard path (think monorepo scenario), you can tell this plugin where to find them. In cypress.json specify paths like this:

{
  "env": {
    "cypress-preact-unit-test": {
      "preact": "node_modules/preact/dist/preact.dev.js"
    }
  }
}

Transpilation

How can we use features that require transpilation? Using @cypress/webpack-preprocessor. You can use cypress/plugins/index.js to configure any transpilation plugins you need.

For example, to enable class properties:

// cypress/plugins/index.js
const webpack = require('@cypress/webpack-preprocessor')
const webpackOptions = {
  module: {
    rules: [
      {
        test: /\.(js|jsx|mjs)$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env', '@babel/preset-react'],
          plugins: ['@babel/plugin-proposal-class-properties'],
        },
      }
    ]
  }
}

const options = {
  // send in the options from your webpack.config.js, so it works the same
  // as your app's code
  webpackOptions,
  watchOptions: {}
}

module.exports = on => {
  on('file:preprocessor', webpack(options))
}

Install dev dependencies

npm i -D @cypress/webpack-preprocessor \
  babel-loader @babel/preset-env @babel/preset-react \
  @babel/plugin-proposal-class-properties

And write a component using class properties

import {h, Component} from 'preact';

export class Transpiled extends Component {
  state = {
    count: 0
  }

  // ...
}

Examples

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

Large examples

Development

  • 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

Related tools

Same feature for unit testing components from other frameworks using Cypress