Giter Site home page Giter Site logo

cypress-io / cypress-react-unit-test Goto Github PK

View Code? Open in Web Editor NEW
678.0 17.0 78.0 30.94 MB

Unit test React components using Cypress

Home Page: https://glebbahmutov.com/blog/my-vision-for-component-tests/

react cypress cypress-io test testing cypress-component-testing

cypress-react-unit-test's Introduction

Cypress React Unit Test

Testing React Components with Cypress

๐Ÿšš This repo has been moved. Cypress is now officially maintaining this package!

cypress-react-unit-test has been renamed to @cypress/react and now lives in the main Cypress monorepo

Migration Guide

To keep up to date with the latest versions, change edit your package.json to use @cypress/react instead of cypress-react-unit-test.

# npm
npm install @cypress/react

# yarn
yarn add @cypress/react

cypress-react-unit-test's People

Contributors

abhinaba-ghosh avatar amirrustam avatar atomicpages avatar bahmutov avatar dmtrkovalenko avatar greenkeeper[bot] avatar jennifer-shehane avatar jessicasachs avatar larrifax avatar onehatrepo avatar renovate-bot avatar renovate[bot] avatar revilotom avatar schalkventer avatar ttacon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cypress-react-unit-test's Issues

Cypress.component is not a function

Tried to recreate the describe('HelloState component') example in the readme and I get Cypress.component is not a function. Any ideas why this might be? "cypress-react-unit-test": "^1.2.1" and "cypress": "^2.1.0"

Typescript Support

Hello,

I have been trying to setup this up with typescript but unfortunately I haven't been able to figure it out. Every time I get this error. Any help would be greatly appreciated. I have spent two full days on this.

You can answer on stack-overflow and get the bounty :)

https://stackoverflow.com/questions/55734312/configuring-cypress-cypress-react-unit-test-and-react

./node_modules/cypress-react-unit-test/lib/getDisplayName.ts 3:24
Module parse failed: Unexpected token (3:24)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| /// <reference path="./index.d.ts" />
| 
> const cachedDisplayNames: WeakMap<JSX, string> = new WeakMap();
| 
| /**
 @ ./node_modules/cypress-react-unit-test/lib/index.ts 3:0-46 111:22-36 171:26-40
 @ ./cypress/support/index.ts

tsconfig

{
    "compilerOptions": {
        "outDir": "./dist/",
        "noImplicitAny": false,
        "module": "es6",
        "target": "es5",
        "jsx": "react",
        "allowJs": true,
        "types": ["cypress"]
    }
}

webpack

const path = require('path')

module.exports = {
  entry: './src/index.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

CSS-in-JS libraries not working

Hi,

this is probably due to how cypress is taking control over the about:blank page. However, if a component is using styled-components or emotionJS, the class names are generated. However the generated styles are not applied to the page.

Weekly Digest (9 February, 2020 - 16 February, 2020)

Here's the Weekly Digest for bahmutov/cypress-react-unit-test:


ISSUES

Last week, no issues were created.


PULL REQUESTS

Last week, 1 pull request was created, updated or merged.

UPDATED PULL REQUEST

Last week, 1 pull request was updated.
๐Ÿ’› #108 Adopt cypress mount mode, by dmtrKovalenko


COMMITS

Last week there were no commits.


CONTRIBUTORS

Last week there were no contributors.


STARGAZERS

Last week there were 5 stagazers.
โญ frederickfogerty
โญ SpencerDuball
โญ TchernyavskyDaniil
โญ FjVillar
โญ adaniliuk
You all are the stars! ๐ŸŒŸ


RELEASES

Last week there were no releases.


That's all for last week, please ๐Ÿ‘€ Watch and โญ Star the repository bahmutov/cypress-react-unit-test to receive next weekly updates. ๐Ÿ˜ƒ

You can also view all Weekly Digests by clicking here.

Your Weekly Digest bot. ๐Ÿ“†

Cypress "headed" browser does not render react-bootstrap modal in the DOM

Other react-bootstrap components render in the DOM and display in the Cypress headed Chrome instance. react-bootstrap modals do not.

Test

/// <reference types="Cypress" />
import React from 'react';
// import {ComposeMessage} from "../../../src/Terra/components/ComposeMessage";
import {Example} from "../../../src/Terra/components/TestComponent";
import { mount } from 'cypress-react-unit-test';

// const mount = require( 'cypress-react-unit-test' ).mount;

describe( "Mounting", () => {
    it( 'works', () => {
        mount( <Example/>)
    } );
} );

Component

import React from 'react';
import ReactDom from 'react-dom';
import {Button, Modal, FormGroup, ControlLabel, FormControl} from 'react-bootstrap';

export class Example extends React.Component <any, any> {
    constructor(props, context) {
        super(props, context);

        this.handleShow = this.handleShow.bind(this);
        this.handleClose = this.handleClose.bind(this);

        this.state = {
            show: true
        };
    }

    handleClose() {
        this.setState({ show: false });
    }

    handleShow() {
        this.setState({ show: true });
    }

render() {
        return(
            <div>
                This text is all that renders. And the modal is not rendered, regardless of whether it is contained within this div.
            <Modal show={this.state.show} onHide={this.handleClose}>
                <Modal.Header closeButton>
                    <Modal.Title>Modal heading</Modal.Title>
                </Modal.Header>
                <Modal.Body>
                    <h4>Text in a modal</h4>
                    <p>
                    Cras mattis consectetur purus sit amet fermentum. Cras justo odio,
                    dapibus ac facilisis in, egestas eget quam. Morbi leo risus, porta
                    ac consectetur ac, vestibulum at eros.
                    </p>
                </Modal.Body>
                <Modal.Footer>
                    <Button onClick={this.handleClose}>Close</Button>
                </Modal.Footer>
            </Modal>
            </div>
        )
    }
}

Copy styles

Just like for Vue - need to copy injected styles from test spec frame to app frame. Cache by component

Uncaught Error: Expected ref to be a function or a string.

I get this error when attempting to unit test a component that uses React.createRef to make a reference to the component. The error is thrown from render():

image

Value of this.textareaRef at render():
image

Source code of the relevant parts of MarkdownEditor:

import React from 'react';

export default class MarkdownEditor extends React.Component {
    constructor(props) {
        super(props);
        this.textareaRef = React.createRef();
    }

    render() {
        console.log(this.textareaRef)
        return (
            <div>
                <textarea ref={this.textareaRef} />
            </div>
        )
    }
}

Test code:

const MarkdownEditor = require('../../src/components/markdown/MarkdownEditor');
const { mount } = require('cypress-react-unit-test');
import React from 'react';

describe('Markdown Editor', () => {
    it('works', () => {
        mount(<MarkdownEditor/>)
        
    })
})

It works once I remove the ref= from the app code, but then again this component depends on having a working ref to itself.

Found a relevant SO that suggested this could be because of an out-of-date React: https://stackoverflow.com/questions/50299218/react-createref-causing-error-expected-ref-to-be-function-or-string

Run cypress-react-unit in terminal

Hello!
I Would Like to know how can I configure cypress with the cypress-react-test-unit to run in the terminal like the "cypress run" command? So I can use in my C.I server(GitLab)

this is my cypress.json config file

{
  "baseUrl": "http://127.0.0.1:3000",
  "integrationFolder": "cypress/e2e",
  "reporter": "junit",
  "video": true,
  "reporterOptions": {
    "mochaFile": "cypress/results/test-development-output.xml",
    "toConsole": true
  }
}

When trying to import an App component in order to set state, Cypress tries to import CSS which breaks the test

/// <reference types="Cypress" />
import 'cypress-react-unit-test'

import { App } from '../../../../src/app';

describe('Additional Vehicles Page', () => {
    beforeEach(() => {
        // cy.mount(<App />)
        cy.get(App)
            .invoke('setState', { cypress: true })
        cy.getToVehiclesPage();
    })

^ Here above all I want cypress-react-unit-test to do is to set the internal state of a component before the tests run. However it throws this error immediately:

This occurred while Cypress was compiling and bundling your test code. This is usually caused by:

A missing file or dependency
A syntax error in the file or one of its dependencies

@import 'buttons';
^
ParseError: Unexpected character '@'

=====

Looks like it imports the App.jsx file, but when it gets to this line import './styles/app.scss'; it tries to process the CSS as javascript and breaks.

How have you guys overcome this problem?

All CSS loads into head of first spec with mounted component

Hi Gleb!
While running all specs I've noticed that the first spec with mounted component get all (and duplicated) CSS styles.
You can see that in your "calculator" example. Lets say it's unable to see orange button when you run tests in the row. To reproduce this clearly you can just rename button.spec.js to _button.spec.js so it will run first. As a result calculator.spec.js will lose all CSS and button really will be orange.

I've faced this issue at my work. Any advice?

Styles are not loaded from components

I'm trying to load the styles from my scss file.

The button is rendered perfectly as component, however the styles are not added.

I am using co-location structure that loads the scss file directly into react components.

Structure:

button/
    button.jsx
    button.scss
    button.test.js

React component:

    import './_button.scss';

    class Button extends React.Component ...

Test:

    it('dark', () => {
      cy.mount(<Button dark={true}/>);
      cy.get('#button').should('have.class', `button--dark`);
    });

Although the button isn't dark :(

Packages:

  • babel 7
  • node-sass
  • Webpack 4 (as plugin preprocesor)

Webpack config:

const webpackOptions = {
  entry: './index.js',
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader']
      },
      {
        test: /\.(scss)$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: ['css-loader', 'sass-loader']
        })
      },
      {
        test: /\.(eot|woff|woff2|svg|ttf)([?]?.*)$/,
        use: ['file-loader']
      },
      {
        test: /\.(png|woff|woff2|eot|ttf|svg)$/,
        use: ['url-loader?limit=100000']
      }
    ]
  },
  resolve: {
    extensions: ['*', '.js', '.jsx'],
      modules: [
      path.resolve(__dirname, '..', 'src/'),
      'node_modules',
    ],
  },
  plugins: [
    new ExtractTextPlugin('main.css')
  ]
};

const webpack = require('@cypress/webpack-preprocessor');

module.exports = (on) => {
  const options = {
    webpackOptions: webpackOptions,
    watchOptions: {},
  };

  on('file:preprocessor', webpack(options))
};

Thanks!

Weekly Digest (16 February, 2020 - 23 February, 2020)

Here's the Weekly Digest for bahmutov/cypress-react-unit-test:


ISSUES

Last week, no issues were created.


PULL REQUESTS

Last week, 1 pull request was created, updated or merged.

UPDATED PULL REQUEST

Last week, 1 pull request was updated.
๐Ÿ’› #44 chore(deps): update dependency @cypress/webpack-preprocessor to v4, by renovate[bot]


COMMITS

Last week there were no commits.


CONTRIBUTORS

Last week there were no contributors.


STARGAZERS

Last week there were no stargazers.


RELEASES

Last week there were no releases.


That's all for last week, please ๐Ÿ‘€ Watch and โญ Star the repository bahmutov/cypress-react-unit-test to receive next weekly updates. ๐Ÿ˜ƒ

You can also view all Weekly Digests by clicking here.

Your Weekly Digest bot. ๐Ÿ“†

Weekly Digest (5 April, 2020 - 12 April, 2020)

Here's the Weekly Digest for bahmutov/cypress-react-unit-test:

ISSUES

This week, 5 issues were created. Of these, 0 issues have been closed and 5 issues are still open.

OPEN ISSUES

๐Ÿ’š #137 Inject remote stylesheets, by bahmutov
๐Ÿ’š #136 Dynamic import keyword is not working (in this repo), by bahmutov
๐Ÿ’š #135 When adding globals to webpack config add test hook names, by bahmutov
๐Ÿ’š #134 Make work with ejected react scripts app, by bahmutov
๐Ÿ’š #108 Adopt cypress mount mode, by dmtrKovalenko

NOISY ISSUE

The issue most discussed this week has been:
๐Ÿ”ˆ #108 Adopt cypress mount mode, by dmtrKovalenko
It received 27 comments.

PULL REQUESTS

This week, no pull requests has been proposed by the users.

CONTRIBUTORS

This week, 2 users have contributed to this repository.
They are bahmutov, and dmtrKovalenko.

STARGAZERS

This week, no user has starred this repository.

COMMITS

This week, there have been 2 commits in the repository.
These are:
๐Ÿ› ๏ธ fix: the require format for react scripts task by bahmutov
๐Ÿ› ๏ธ feat: use latest code coverage plugin by bahmutov

RELEASES

This week, 8 releases were published. These are:
๐Ÿš€ v3.0.0-cypress-mount-mode.14 v3.0.0-cypress-mount-mode.14

3.0.0-cypress-mount-mode.14 (2020-04-09)

Features

  • update style options and document them well (d1aece8)

๐Ÿš€ v3.0.0-cypress-mount-mode.13 v3.0.0-cypress-mount-mode.13

3.0.0-cypress-mount-mode.13 (2020-04-08)

Features

  • correctly clean up webpack for react-scripts for lazy dynamic imports (f72b7d3)
  • support lazy-loaded components by forcing all into 1 chunk (3bee1e2)

๐Ÿš€ v3.0.0-cypress-mount-mode.12 v3.0.0-cypress-mount-mode.12

3.0.0-cypress-mount-mode.12 (2020-04-07)

Features

  • allow loading webpack config by filename (5bbcc69)

๐Ÿš€ v3.0.0-cypress-mount-mode.11 v3.0.0-cypress-mount-mode.11

3.0.0-cypress-mount-mode.11 (2020-04-06)

Features

  • use new code coverage version (60fa438)

๐Ÿš€ v3.3.1 v3.3.1

3.3.1 (2020-04-06)

Bug Fixes

  • the require format for react scripts task (1b49d25)

๐Ÿš€ v3.3.0 v3.3.0

3.3.0 (2020-04-06)

Features

  • use latest code coverage plugin (6ef8223)

๐Ÿš€ v3.0.0-cypress-mount-mode.10 v3.0.0-cypress-mount-mode.10

3.0.0-cypress-mount-mode.10 (2020-04-06)

Features

  • use find-webpack to handle ejected react-scripts too (ddbdbe2)

๐Ÿš€ v3.0.0-cypress-mount-mode.9 v3.0.0-cypress-mount-mode.9

3.0.0-cypress-mount-mode.9 (2020-04-05)

Bug Fixes

  • update code coverage with better filtering (f7678b8)

That's all for this week, please watch ๐Ÿ‘€ and star โญ bahmutov/cypress-react-unit-test to receive next weekly updates. ๐Ÿ˜ƒ

cy.location('pathname') incorrect

Hi All,

I am trying to assert on a connected react router component, and the assertion from cy.location('pathname') is failing. The same test passes if I use just plain cypress without mounting. Is this related to the proposed solution to #51, or is it something different entirely?

import React from "react";
import { ConnectedRouter, connectRouter, push, routerMiddleware } from 'connected-react-router'
import { createBrowserHistory } from "history";
import { connect, Provider } from "react-redux";
import { Redirect, Route, Switch } from 'react-router'
import { combineReducers, createStore, applyMiddleware } from "redux";

import fixScope from '../support/fixScope';

const history = createBrowserHistory()

const root = combineReducers({
  router: connectRouter(history)
})

const store = createStore(root, applyMiddleware(
  routerMiddleware(history)
))

const Redirecter = () => <Redirect to="/home" />

const Away = connect(
  state => ({
  path: state.router.location.pathname
}))(({ path }) => <h1>Away~ {path}</h1>)

const RoutedComponent = ({ match, path, onClick}) =>
  <div>
    <h1>Hello from {match.url} and {path}!</h1>
    <button onClick={onClick}>Change Url</button>
  </div>

const ConnectedRoutedComponent = connect(
  state => ({
    path: state.router.location.pathname
  }),
  dispatch => ({
    onClick: () => dispatch(push('/away'))
}))(RoutedComponent)

describe('a routed component', () => {
  beforeEach(() => {
    fixScope(window)
  })

  it('should render', function() {
    cy.server()

    store.dispatch(push('/home'))

    cy.mount(
      <Provider store={store}>
        <ConnectedRouter history={history}>
          <Switch>
            <Route path="/away" component={Away} />
            <Route path="/home" component={ConnectedRoutedComponent} />
            <Route path="/"  component={Redirecter}/>
          </Switch>
        </ConnectedRouter>
      </Provider>
    )

    cy.get('button').click()
    .then($ => {
      // Passes
      expect(store.getState().router.location.pathname).to.equal('/away')

      // CypressError: Timed out retrying: expected '/__/' to equal '/away'
      cy.location('pathname').should('eq', '/away')
    })
  })
})

TypeScript compile error: Variable 'displayName' is used before being assigned.

Problem
I get the following TypeScript error when i try to use the package in my code.

TypeScript error in /(hidden)/node_modules/cypress-react-unit-test/lib/getDisplayName.ts(27,8):
Variable 'displayName' is used before being assigned.  TS2454

    25 |   }
    26 | 
  > 27 |   if (!displayName) {
       |        ^
    28 |     displayName = type.name || fallbackName
    29 |   }
    30 | 

It's coming from function getDisplayName()

let displayName: string

  // The displayName property is not guaranteed to be a string.
  // It's only safe to use for our purposes if it's a string.
  // github.com/facebook/react-devtools/issues/803

  if (typeof type.displayName === 'string') {
    displayName = type.displayName
  }

  if (!displayName) {
    displayName = type.name || fallbackName
  }

Solution
I suggest displayName is initialised to fallbackName before the rest of the code happens.

let displayName: string = fallbackName

  // The displayName property is not guaranteed to be a string.
  // It's only safe to use for our purposes if it's a string.
  // github.com/facebook/react-devtools/issues/803

  if (typeof type.displayName === 'string') {
    displayName = type.displayName
  }

  if (!displayName && type.name) {
    displayName = type.name
  }

@bahmutov Do you mind if submit a PR on this?

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! ๐ŸŽŠ

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml

If youโ€™re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didnโ€™t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didnโ€™t touch job or matrix configurations because these tend to be quite specific and complex, and itโ€™s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what youโ€™re doing it may require additional work or may not be applicable at all. Weโ€™re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, Iโ€™m a humble robot and wonโ€™t feel rejected ๐Ÿค–


FAQ and help

There is a collection of frequently asked questions. If those donโ€™t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot ๐ŸŒด

An in-range update of react-dom is breaking the build ๐Ÿšจ

โ˜๏ธ Greenkeeperโ€™s updated Terms of Service will come into effect on April 6th, 2018.

Version 16.3.0 of react-dom was just published.

Branch Build failing ๐Ÿšจ
Dependency react-dom
Current Version 16.2.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

react-dom is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • โŒ continuous-integration/travis-ci/push The Travis CI build failed Details

Release Notes v16.3.0

16.3.0 (March 29, 2018)

React

  • Add a new officially supported context API. (@acdlite in #11818)
  • Add a new React.createRef() API as an ergonomic alternative to callback refs. (@trueadm in #12162)
  • Add a new React.forwardRef() API to let components forward their refs to a child. (@bvaughn in #12346)
  • Fix a false positive warning in IE11 when using React.Fragment. (@XaveScor in #11823)
  • Replace React.unstable_AsyncComponent with React.unstable_AsyncMode. (@acdlite in #12117)
  • Improve the error message when calling setState() on an unmounted component. (@sophiebits in #12347)

React DOM

  • Add a new getDerivedStateFromProps() lifecycle and UNSAFE_ aliases for the legacy lifecycles. (@bvaughn in #12028)
  • Add a new getSnapshotBeforeUpdate() lifecycle. (@bvaughn in #12404)
  • Add a new <React.StrictMode> wrapper to help prepare apps for async rendering. (@bvaughn in #12083)
  • Add support for onLoad and onError events on the <link> tag. (@roderickhsiao in #11825)
  • Add support for noModule boolean attribute on the <script> tag. (@aweary in #11900)
  • Fix minor DOM input bugs in IE and Safari. (@nhunzaker in #11534)
  • Correctly detect Ctrl + Enter in onKeyPress in more browsers. (@nstraub in #10514)
  • Fix containing elements getting focused on SSR markup mismatch. (@koba04 in #11737)
  • Fix value and defaultValue to ignore Symbol values. (@nhunzaker in #11741)
  • Fix refs to class components not getting cleaned up when the attribute is removed. (@bvaughn in #12178)
  • Throw with a meaningful message if the component runs after jsdom has been destroyed. (@gaearon in #11677)
  • Don't crash if there is a global variable called opera with a null value. @alisherdavronov in #11854)
  • Don't check for old versions of Opera. (@skiritsis in #11921)
  • Deduplicate warning messages about <option selected>. (@watadarkstar in #11821)
  • Deduplicate warning messages about invalid callback. (@yenshih in #11833)
  • Deprecate ReactDOM.unstable_createPortal() in favor of ReactDOM.createPortal(). (@prometheansacrifice in #11747)
  • Don't emit User Timing entries for context types. (@abhaynikam in #12250)
  • Improve the error message when context consumer child isn't a function. (@raunofreiberg in #12267)
  • Improve the error message when adding a ref to a functional component. (@skiritsis in #11782)

React DOM Server

  • Prevent an infinite loop when attempting to render portals with SSR. (@gaearon in #11709)
  • Warn if a class doesn't extend React.Component. (@wyze in #11993)
  • Fix an issue with this.state of different components getting mixed up. (@sophiebits in #12323)
  • Provide a better message when component type is undefined. (@HeroProtagonist in #11966)

React Test Renderer

  • Fix handling of fragments in toTree(). (@maciej-ka in #12107 and @gaearon in #12154)
  • Shallow renderer should assign state to null for components that don't set it. (@jwbay in #11965)
  • Shallow renderer should filter legacy context according to contextTypes. (@koba04 in #11922)
  • Add an unstable API for testing asynchronous rendering. (@acdlite in #12478)

React Is (New)

  • First release of the new package that libraries can use to detect different React node types. (@bvaughn in #12199)
  • Add ReactIs.isValidElementType() to help higher-order components validate their inputs. (@jamesreggio in #12483)

React Lifecycles Compat (New)

Create Subscription (New)

React Reconciler (Experimental)

  • Expose react-reconciler/persistent for building renderers that use persistent data structures. (@gaearon in #12156)
  • Pass host context to finalizeInitialChildren(). (@jquense in #11970)
  • Remove useSyncScheduling from the host config. (@acdlite in #11771)

React Call Return (Experimental)

FAQ and help

There is a collection of frequently asked questions. If those donโ€™t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot ๐ŸŒด

Cannot read property 'render' of undefined

I am attempting to work my way through the sample scripts offered to understand this extension for my own unit testing project.

My problem is that I have encountered issues with cy.mount(). Encountered when copying hello-x to confirm my issues with cy.mount() stem from my own code rather than the extension.

When running the Hello-x-spec.js test I get the following errors.

2019-09-17 17_37_34-ocarina party

I have read elsewhere that some had encountered errors with exporting when the class was not default, so I changed export class HelloX extends React.Component to export default class HelloX extends React.Component and get the following errors.

2019-09-17 17_39_53-ocarina party

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

File: renovate.json
Error type: The renovate configuration file contains some invalid settings
Message: Invalid schedule: Invalid schedule: Failed to parse "every night"``

Styled Components - Fails to mount

Hey, first of all: great module! It's very elevating to combine unit tests into the E2E workflow.

Anyway; we use styled-components heavily and I would like to unit test them in cypress. Unfortunately, mount throws a fit when hit with a styled component.

After

  • yarn add -D styled-components
  • (yarn add -D cypress-react-unit-test)

If you throw this test into cypress...

// type definitions for Cypress object "cy"
/// <reference types="cypress" />

// check this file using TypeScript if available
// @ts-check

// =============================================================================
// Debugging Styled Component in Cypress for Unit Testing
// yarn add -D cypress-react-unit-test
// yarn add -D styled-components
// =============================================================================
import React from "react";
import { mount } from "cypress-react-unit-test";
import styled from "styled-components";

/** 
 * Create normal react component
 * */
const TestComponent = props => {
  return <div data-test="TestComponent">This is a test!</div>;
};

/** 
 * ๐Ÿ’„ Now we style with styled-components
 * */
const StyledComponent = styled(TestComponent)`
  background-color: green;
`;

/** 
 * Running Test
*/
describe("Can Render Component", () => {
  it("Plain Component", () => {

    // โœ… Works
    mount(<TestComponent />);

    cy.get('[data-test="TestComponent"]').should("contain", "test");
  });

  it("Styled Component as JSX", () => {

    // ๐Ÿ”ฅ Fails
    // Error: Element type is invalid: expected a string
    // (for built-in components) or a class/function (for composite components)
    // but got: object.
    mount(<StyledComponent />);

    cy.get('[data-test="TestComponent"]').should("contain", "test");
  });

  it("Styled Component as object reference", () => {

    // ๐Ÿ”ฅ Fails
    // Error: TypeError: Cannot read property 'name' of undefined
    mount(StyledComponent);

    cy.get('[data-test="TestComponent"]').should("contain", "test");
  });
});

// =============================================================================
// END Debugging Component
// =============================================================================

...you'll see the tests fail.
image

I was trying to solve this with some style extraction etc. to see what's going on but the last error TypeError: Cannot read property 'name' of undefined is really odd to me.

Someone have an idea?

Thanks in advance

Cannot access document from within component

TL;DR document seems to refer to the 'spec' iframes document not the 'app' iframe document

Issue has come up when trying to access document.documentElement.clientHeight for D3 graphing

Eg using hello-world.jsx

import React from 'react'

export class HelloWorld extends React.Component {
  render () {
    console.log(document.documentElement.clientHeight, document.body.clientHeight); //0 0
    return <p>Hello World!</p>
  }
}

Any ideas of a workaround?

Click does not click in the center

Trying the test runner, the click does not click in the center of the found link

import React from 'react'
import ProjectId from './project-id'
import { mount } from 'cypress-react-unit-test'

import ipc from '../lib/ipc'

/* global cy */
describe('ProjectId', () => {
  it('loads', () => {
    const project = {
      id: 'fake-project-id',
      configFile: false,
    }

    cy.stub(ipc, 'externalOpen').as('externalOpen')
    mount(<ProjectId project={project} />)
    cy.contains('a', 'Learn more').click()
    cy.get('@externalOpen').should('have.been.called')
  })
})

The failed screenshot showing where the click happens

Screen Shot 2020-04-14 at 10 29 17 AM

Manually clicking shows the stub is working

Screen Shot 2020-04-14 at 10 29 27 AM

Invariant Violation with DropDown components

I get an error while mounting my component

image

The component is correctly render in Cypress regular tests, and it only contains a DropDown from the react-bootstrap lib (same error with the react-simple-dropdown)

import {Dropdown} from 'react-bootstrap';


class UserControls extends React.Component {
    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (
                <Dropdown>
                    <Dropdown.Toggle>
                        Toggle
                    </Dropdown.Toggle>
                    <Dropdown.Menu>
                        <li>
                            menu
                        </li>
                    </Dropdown.Menu>
                </Dropdown>
        );
    }
}

UserControls.displayName = 'UserControls';

UserControls.propTypes = {
};

export default UserControls;

Components with forwardRef fail when trying to get displayName

Repro the issue using the following component:

import React from 'react';

const Button = React.forwardRef(({ children, ...rest }, ref) => <button {...rest} ref={ref}>{children}</button>);

export default Button;

The correct way to get the display name is not through JSX magic, but rather from the static member on the object. With function components jsx.type.prototype is undefined.

Inject remote stylesheets

Take from https://github.com/bahmutov/cypress-react-unit-test/tree/feature/cypress-mount-mode

interface MountOptions {
  alias?: string
  ReactDom?: typeof ReactDOM
  stylesheets?: string | string[]
  style?: string
  cssFile?: string
}

https://github.com/bahmutov/cypress-react-unit-test/blob/feature/cypress-mount-mode/lib/index.ts#L25

Use case from https://github.com/bahmutov/react-todo-with-hooks/blob/added-tests/src/Todo.spec.js#L11

    mount(
      <Todo todo={todo} />,
      {
        stylesheets: [
          'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css'
        ]
      }
    )

function "mount" does not work

Hi,

I'm trying to configure unit test environment in my app using Cypress and cypress-react-unit-test. The problem is I have code that needs plugins like "@babel/plugin-proposal-decorators", "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-optional-chaining", "@babel/plugin-transform-classes" to compile.

My problem is, when I'm pretty sure that code compiles in right way (with big help of webpack-preprocessor) I see that Cypress don't understand cy.mount().

This is my config files of Cypress, am I doing something wrong?

//cypress/support/index.js:

import './commands';
import 'cypress-react-unit-test';

//cypress/plugins/index.js:

const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const webpackOptions = require('./webpack.config');

module.exports = on => {
  on('file:preprocessor', webpackPreprocessor(webpackOptions));
};

//cypress/plugins/webpack.config.js

module.exports = {
  node: {
    fs: 'empty'
  },
  module: {
    strictExportPresence: true,
    rules: [
      {
        test: /\.jsx?$/,
        exclude: [/node_modules/],
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                'ms',
                '@babel/preset-env',
                '@babel/preset-react'
              ],
              plugins: [
                ['@babel/plugin-proposal-decorators', { legacy: true }],
                ['@babel/plugin-proposal-class-properties', { loose: true }],
                ['@babel/plugin-proposal-optional-chaining', { loose: true }],
                ['@babel/plugin-transform-classes', { loose: true }]
              ]
            },
          },
        ],
      },
      {
        test: /\.css$/,
        exclude: [/node_modules/],
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
};

I would be really grateful for any help. It's hard to find some info about that library.

with regards :)

React portal not rendering in cypress headed chrome instance

React portal is not rendering in cypress headed chrome instance.

React Component (Having portal)

import React from "react";
import ReactDOM from 'react-dom';


export class PortalExample extends React.Component {

    DOM_OBJECT = null;

    constructor(...args) {
        super(...args);
        const domElement = document.getElementById("portalId");
        if (!domElement) {
            this.DOM_OBJECT = document.createElement("div");
            this.DOM_OBJECT.id = "portalId";
            document.body.appendChild(this.DOM_OBJECT);
        } else {
            this.DOM_OBJECT = document.getElementById("portalId");
        }
    }

    renderApprovalBar = () => {
        const portalCOntainer = () => (
            <div>
                <h2>PORTAL HEADER</h2>
            </div>
        );
        return ReactDOM.createPortal(
            portalCOntainer(),
            this.DOM_OBJECT
        );
    }

    render() {
        return (
            <div>
                <h1>APP </h1>
                {this.renderApprovalBar()}
            </div>

        );
    }
}

Test file

import React from "react";
import 'cypress-react-unit-test'
import { PortalExample } from "./portalExample";

describe('React.portal', () => {

    it('Test portal is renddering', () => {
        cy.mount(<PortalExample />)
        cy.get('#portalId')
    })
});

Screenshot 2019-11-25 at 11 42 17 AM

Screenshot 2019-11-25 at 11 42 09 AM

cy.mount cannot mount multiple components

Using cy.mount to mount one component can be finished successfully but failed to mount multiple components.

Please find the files in attached zip file (component.and.test.files.zip).
Button.js is the file of component. button.spec.js is the test file.
component and test files.zip
snapshot of error info
image
error log


cypress_runner.js:172385 Error:    TypeError: Invalid value used as weak map key
    at WeakMap.set (<anonymous>)
    at Object.getDisplayName [as default] (http://localhost:51524/__cypress/tests?p=cypress/integration/button.spec.js-500:254:24)
    at Context.exports.mount (http://localhost:51524/__cypress/tests?p=cypress/integration/button.spec.js-500:356:47)
From previous event:
    at runCommand (http://localhost:51524/__cypress/runner/cypress_runner.js:78709:14)
    at next (http://localhost:51524/__cypress/runner/cypress_runner.js:78793:14)
From previous event:
    at http://localhost:51524/__cypress/runner/cypress_runner.js:78812:37
From previous event:
    at run (http://localhost:51524/__cypress/runner/cypress_runner.js:78810:15)
    at Object.cy.<computed> [as mount] (http://localhost:51524/__cypress/runner/cypress_runner.js:79038:11)
    at Context.runnable.fn (http://localhost:51524/__cypress/runner/cypress_runner.js:79168:20)
    at callFn (http://localhost:51524/__cypress/runner/cypress_runner.js:51457:21)
    at Test.Runnable.run (http://localhost:51524/__cypress/runner/cypress_runner.js:51450:7)
    at http://localhost:51524/__cypress/runner/cypress_runner.js:82159:28
From previous event:
    at Object.onRunnableRun (http://localhost:51524/__cypress/runner/cypress_runner.js:82154:20)
    at $Cypress.action (http://localhost:51524/__cypress/runner/cypress_runner.js:77456:51)
    at Test.Runnable.run (http://localhost:51524/__cypress/runner/cypress_runner.js:81220:20)
    at Runner.runTest (http://localhost:51524/__cypress/runner/cypress_runner.js:51920:10)
    at http://localhost:51524/__cypress/runner/cypress_runner.js:52026:12
    at next (http://localhost:51524/__cypress/runner/cypress_runner.js:51840:14)
    at http://localhost:51524/__cypress/runner/cypress_runner.js:51850:7
    at next (http://localhost:51524/__cypress/runner/cypress_runner.js:51782:14)
    at http://localhost:51524/__cypress/runner/cypress_runner.js:51818:5
    at timeslice (http://localhost:51524/__cypress/runner/cypress_runner.js:47059:27)

Need a render method

In this example

import counter from './reducers'
const store = createStore(counter)

const rootEl = document.getElementById('root')

const render = () => ReactDOM.render(
  <App store={store} />,
  rootEl
)

render()
store.subscribe(render)

We need to re-render the current JSX App element whenever the store is updated. This test does not update the UI, even when it passes

import React from 'react'
import App from './App'

import {createStore} from 'redux'
import counter from './reducers'
const store = createStore(counter)

describe('App', () => {
  it.only('works but never prints new counter', () => {
    cy.mount(<App store={store} />)

    cy.wrap(store).invoke('getState').should('equal', 0)
    cy.contains('button', 'Increment async').click().click().click()
    cy.wrap(store).invoke('getState').should('equal', 3)
    cy.contains('Clicked: 0 times').should('be.visible')
  })
})

Screen Shot 2020-04-02 at 10 56 10 PM

We need to somehow simulate from the test itself store.subscribe(render) call

Something like

it.only('works and prints new counter', () => {
  cy.mount(<App store={store} />)
  store.subscribe(() => {
    cy.render(<App store={store} />)
  })

  cy.wrap(store).invoke('getState').should('equal', 0)
  cy.contains('button', 'Increment async').click().click().click()
  cy.wrap(store).invoke('getState').should('equal', 3)
  cy.contains('Clicked: 3 times').should('be.visible')
})

Screen Shot 2020-04-02 at 10 57 41 PM

Block fetch to stub Graphql

Hi there,

I'm using this library which greatly helps testing of components, thank you so much for that :)
There is one thing that I cannot seem to figure out, and that is removing the window.fetch() function to force Apollo-Client to use XHR to get the Graphql requests. This way one would be able to stub those requests as per usual. I thought adding an extra chain in cy.window({log: false}).then(removeFetch) which would simply be function removeFetch(w){w.fetch=null;return w) would do the trick, but even though function is actually nullified, the network inspector still shows that fetch is being used for the Graphql query. Would you have any idea or pointer on how to get this working ?

Thanks a bunch!
Gerard.

Unable to configure

Hi all.
I am developing react component library with typescript and I would like to test it with cypress-react-unit-test. I tried everything i found on internet, but without success. I would be very thankfull if someone could check it up and point me in some direction.

I am unable to run simple example.test.ts

Here is the link : https://github.com/BogMil/react-crud-master

Thank you in advance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.