GithubHelp home page GithubHelp logo

Comments (29)

oliversong avatar oliversong commented on May 1, 2024 3

Bump. We're currently struggling this as well. Has anyone figured out a reasonable pattern for testing with enzyme?

from react-modal.

ArthurCideron avatar ArthurCideron commented on May 1, 2024 2

@jkimbo I figured out my issue. You example worked fine so it was indeed an issue on my side.
I was rendering from an external module like

var  renderedModal = TestUtils.renderIntoDocument(
      <MyModule
           props1:{stubblabla}
      />
    );

and calling MyModule.portal, which was obviously wrong, I needed the Modal.portal
So for whoever is in trouble like I was: remember to get the Modal component !

TestUtils.findRenderedComponentWithType(component, Modal);

from react-modal.

begincalendar avatar begincalendar commented on May 1, 2024 2

I know this issue is about React test utils, but is it possible to make testing work with Enzyme.js?

Enzyme.js provides a simpler/cleaner API over React test utils (in my opinion) and it would be handy to be able to utilise that when testing code regarding react-modal.

from react-modal.

dy-dx avatar dy-dx commented on May 1, 2024 2

This blog post has some examples for testing react-modal with enzyme: http://remarkablemark.org/blog/2017/05/17/testing-react-modal/

from react-modal.

bethcodes avatar bethcodes commented on May 1, 2024 1

With enzyme, shallow supports portal components while mount does not. If you absolutely must use mount, you can use ref={(ref) => { this.namedRef = ref; } in order to access the element and then wrap it in an enzyme ReactWrapper.

from react-modal.

techrah avatar techrah commented on May 1, 2024 1

@ramusus I too am unable to get this to work with enzyme 3 and enzyme-adapter-react-15. If you've come up with a workaround, please share.

I've tried react-dom/test-utils renderIntoDocument then ReactDOM.findDOMNode and scryRenderedDOMComponentsWithClass as recommended here with little to no success.

I've also tried the examples from the blog post recommended by @dy-dx with limited success. I've been able to get a reference to the portal component but it doesn't seem to contain any HTML. (Yes, I've set isOpen to true.)

I've tried using both shallow and mount from enzyme and despite @bethcodes' experience with shallow, I actually got further with mount. With shallow I had no luck finding any portal.

from react-modal.

dviramontes avatar dviramontes commented on May 1, 2024

Having trouble testing this as well.
👍 thanks for the pointer @baer !

from react-modal.

jkimbo avatar jkimbo commented on May 1, 2024

@baer I guess this is because the modal creates a "portal" by mounting the actual modal in a new div at the bottom of the page. You can see in the Modal.js component the render method is not actually returning anything: https://github.com/rackt/react-modal/blob/1ff6a02c689e9fdc03616c4ab82ec53317f14c69/lib/components/Modal.js#L74

To get around this you need to access the .portal property (https://github.com/rackt/react-modal/blob/1ff6a02c689e9fdc03616c4ab82ec53317f14c69/lib/components/Modal.js#L70) on the renderedModal to access the correct React tree to run the TestUtils on. So React.scryRenderedDOMComponentsWithClass(renderedModal.portal, "my-modal-class"); should work.

Hope that makes sense!

from react-modal.

ArthurCideron avatar ArthurCideron commented on May 1, 2024

@jkimbo that sounded promising, unfortunately that didn't do the trick for me. I get an undefined on renderedModal.portal. Do you get the React tree on that ?

from react-modal.

jkimbo avatar jkimbo commented on May 1, 2024

@ArthurCid I've written up a passing test for you using mocha and jsdom: https://gist.github.com/jkimbo/872f42732e6c772bf8e1

from react-modal.

gbrassey avatar gbrassey commented on May 1, 2024

I'm still having trouble with this. I've tried [email protected] w/ [email protected] and [email protected] w/ [email protected]. Testing with karma, karma-chrome and mocha.

the .portal property exists and renders but it appears to have no children

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import { expect } from 'chai';

import Modal from 'react-modal';

describe('component - common - Modal', () => {
  it('renders without problems', () => {
    const renderedModal = TestUtils.renderIntoDocument(
      <Modal>
        <div className="my-modal-class">
          <h1>Hi!</h1>
        </div>
      </Modal>
    );

    // passing
    expect(ReactDOM.findDOMNode(renderedModal.portal).tagName).to.equal('DIV');
    expect(ReactDOM.findDOMNode(renderedModal.portal).children).to.be.empty;

    const divs = TestUtils.scryRenderedDOMComponentsWithClass(renderedModal.portal, 'my-modal-class');
    // fails
    expect(divs.length).to.equal(1);
  });
});

from react-modal.

jkimbo avatar jkimbo commented on May 1, 2024

@gbrassey you need to set isOpen={true} on the modal component for it to render it's children.

from react-modal.

gbrassey avatar gbrassey commented on May 1, 2024

wow thanks @jkimbo 😵 🔫

from react-modal.

jkimbo avatar jkimbo commented on May 1, 2024

@ArthurCid glad you figured it out!

from react-modal.

claydiffrient avatar claydiffrient commented on May 1, 2024

There hasn't been much traction on this issue in over a year. I'm assuming that this is no longer an issue, especially given that #136 was merged. If it is, please feel free to re-open.

from react-modal.

claydiffrient avatar claydiffrient commented on May 1, 2024

@begincalendar Is there a specific issue with using Enzyme? In theory it should "just work" assuming the notes about testing from the read me are followed. If there's a specific issue where it fails, please file an issue for it

from react-modal.

begincalendar avatar begincalendar commented on May 1, 2024

There is no issue per se, it's more of that the React test utils give you DOM elements, whereas Enzyme gives you wrappers and pseudo elements.

I.e. The whole library is designed to work with these wrappers/pseudoelements, e.g. for making simulate() calls.
So getting back DOM elements from React test utils, means that Enzyme can't really be utilised completely.

from react-modal.

claydiffrient avatar claydiffrient commented on May 1, 2024

Right. I actually really like Enzyme and have used it frequently in other projects. I don't see any reason that you couldn't use Enzyme when testing a component that uses react-modal.

from react-modal.

begincalendar avatar begincalendar commented on May 1, 2024

But you need to extract the portal property to get access to child elements, right?

As far as I'm aware, with Enzyme, once you take out the reference to the portal property, you can't then go do things such as: render the child elements, render the text of the child elements, find sub-child elements, etc.

Am I missing something?

from react-modal.

claydiffrient avatar claydiffrient commented on May 1, 2024

Hmmm... I'd have to put together an example of this to be sure. I don't have time at the moment, but I'll see if I can't put something together soon.

from react-modal.

cool-acid avatar cool-acid commented on May 1, 2024

I'm also interested on how to test with Enzyme. I've been struggling with this for a while.

from react-modal.

pzmudzinski avatar pzmudzinski commented on May 1, 2024

Anyone.. ?

from react-modal.

asborisov avatar asborisov commented on May 1, 2024

#291

from react-modal.

Cory-Christensen avatar Cory-Christensen commented on May 1, 2024

Here's an example where I used enzyme to test a component with react-modal. The modal is used to confirm a user wants to go forward, and tests to see if confirmed() was called.

confirm_modal.jsx

import React from 'react';
import ReactModal from 'react-modal';
import PropTypes from 'prop-types';

export default class ConfirmModal extends React.Component {

  static propTypes = {
    closeModal: PropTypes.func.isRequired,
    isOpen: PropTypes.bool.isRequired,
  }

  confirmed() {
    console.log('PASSED');
  }

  modalContent() {
    return (
      <div>
        <div className="c-modal__main">
          Do you wish to proceed?
        </div>
        <div className="c-modal__bottom">
          <button
            type="button"
            className="c-btn c-btn--gray"
            onClick={this.props.closeModal}
          >
            No
          </button>
          <button
            type="button"
            className="c-btn c-btn--blue"
            onClick={() => this.confirmed()}
          >
            Yes
          </button>
        </div>
      </div>
    );
  }

  render() {

    return (
      <ReactModal
        isOpen={this.props.isOpen}
        onRequestClose={this.props.closeModal}
        contentLabel="Modal"
        overlayClassName="c-modal__background"
        className="c-modal is-open"
      >
        {this.modalContent()}
      </ReactModal>
    );
  }
}

confirm_modal.spec.jsx

import React from 'react';
import { shallow } from 'enzyme';
import ConfirmModal from './confirm_modal';

describe('confirm modal', () => {
  let props;
  beforeEach(() => {
    props = {
      closeModal: () => {},
      isOpen: true,
    };
  });

  it('confirms user wants to proceed', () => {
    spyOn(ConfirmModal.prototype, 'confirmed');
    const wrapper = shallow(<ConfirmModal {...props} />);
    const content = wrapper.instance().modalContent();
    const modalContent = shallow(content);
    modalContent.find('.c-btn--blue').simulate('click');
    expect(wrapper.instance().confirmed).toHaveBeenCalled();
  });

  it('renders modalContent', () => {
    spyOn(ConfirmModal.prototype, 'modalContent');
    const wrapper = shallow(<ConfirmModal {...props} />);
    expect(wrapper.instance().modalContent).toHaveBeenCalled();
  });
});

Hopefully that helps you guys out 👍

from react-modal.

ramusus avatar ramusus commented on May 1, 2024

@dy-dx thanks for great solution, but it doesn't work with the last enzyme

    "enzyme": "3.1.1",
    "enzyme-adapter-react-15": "1.0.5",

Do you have any workaround?

from react-modal.

ramusus avatar ramusus commented on May 1, 2024

@ryanhomer, found solution - do not use ReactWrapper or any other hacks - content of modals get rendered into the main wrapper, properly in place where it should be logically (but not in the real DOM).

So everything becomes more simple and easy to test, just not forget to do wrapper.update() ...

from react-modal.

aaronvanston avatar aaronvanston commented on May 1, 2024

@ramusus Are you able to post an example? I'm still have issues rendering modal content without ReactWrapper.

from react-modal.

ramusus avatar ramusus commented on May 1, 2024
// ModalContainer.js
import React, { Component } from 'react';
import ReactModal from 'react-modal';

export default class ModalContainer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isModalOpen: false
    };
    this.toggleModal = this.toggleModal.bind(this);
  }

  toggleModal() {
    this.setState({
      isModalOpen: !this.state.isModalOpen
    });
  }

  render() {
    return (
      <div>
        <button onClick={this.toggleModal}>
          Open Modal
        </button>
        <ReactModal
          {...this.props}
          isOpen={this.state.isModalOpen}
          onRequestClose={this.toggleModal}
        >
          <div>Content</div>
        </ReactModal>
      </div>
    );
  }
}

// ModalContainer.spec.js
import React from 'react';
import ReactModal from 'react-modal';
import ModalContainer from './ModalContainer';
import { mount } from 'enzyme';

describe('<ModalContainer>', () => {
  it('opens modal and render it\'s content when button is clicked', () => {
    const wrapper = mount(<ModalContainer />);
    wrapper.find('button').simulate('click');
    expect(wrapper.find(ReactModal).text()).toBe('Content');
  });
});

from react-modal.

hng0 avatar hng0 commented on May 1, 2024

@ramusus The example above no longer works for me. I got this error

  1. opens modal and render it's content when button is clicked:
    TypeError: Cannot read property 'textContent' of null
    at ReactWrapper. (node_modules/enzyme/build/ReactWrapper.js:799:43)
    at ReactWrapper.single (node_modules/enzyme/build/ReactWrapper.js:1534:25)
    at ReactWrapper.text (node_modules/enzyme/build/ReactWrapper.js:798:21)
    at Context. (src/a/test.spec.js:14:37)

I'm using react-modal 3.4.4 and enzyme 3.3.0. Is there anything that I miss?
Update: If I shallow render the modal, then its children is rendered.

from react-modal.

Related Issues (20)

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.