2

I've got this simple code from react bootstrap website...

import {Modal}  from 'react-bootstrap';
import React from 'react';

export default class ModalExperiment extends React.Component {


  constructor(props) {
    super(props);
    this.state = {
      open: false
    }
  }

  render(){
    let openModal = () => this.setState({open: true});
    let closeModal = () => this.setState({ open: false });

    return (
      <div>
        <button type='button' onClick={openModal} className='launch'>Launch modal</button>

        <Modal
          show={this.state.open}
          onHide={closeModal}
          aria-labelledby="ModalHeader" className='modalClass'
          >
          <Modal.Header closeButton>
            <Modal.Title id='ModalHeader'>A Title Goes here</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <p>Some Content here</p>
          </Modal.Body>
          <Modal.Footer>
            // If you don't have anything fancy to do you can use
            // the convenient `Dismiss` component, it will
            // trigger `onHide` when clicked
            <Modal.Dismiss className='dismiss btn btn-default'>Cancel</Modal.Dismiss>

            // Or you can create your own dismiss buttons
            <button className='btn btn-primary' onClick={closeModal}>
              Close
            </button>
          </Modal.Footer>
        </Modal>
      </div>
    )
  }
}

And here is my test... simple I want to click the launch button, verify the Modal opens, and then click on the Cancel button to verify the Modal is no longer opened.

'use strict';

import React from 'react';
import ReactAddons from 'react/addons';
import {Modal}  from 'react-bootstrap';
import ModalExperiment  from '../ModalExperiment';

import ReactDOM from 'react-dom';

let TestUtils = React.addons.TestUtils;

fdescribe('ModalExperimentFunctional', function() {

  let page;


  fit("click the ok button should open the modal", () => {

    page = TestUtils.renderIntoDocument(<ModalExperiment/>);

    let launch = TestUtils.findRenderedDOMComponentWithClass(page, 'launch');

    let openButton = React.findDOMNode(launch);
    openButton.click(); // work till here

    //let modal = TestUtils.findRenderedComponentWithType(page, Modal);// this managed to find Modal type
    let modal = TestUtils.findRenderedDOMComponentWithClass(page, 'modalClass'); // this fails to find the modalClass..

  });
});

How can I find the Cancel button please? I tried all sort of things, nothing seems to have worked for me.

Tin Ng
  • 937
  • 2
  • 11
  • 25
  • Have you tried using refs? I think the issue might be that the modal is appended to the body so you won't find it by looking for a class in your page element. Try `ref="modalClose"` on your close `button` then try to access it with `page.refs.modalClose`. Testing can be a bit of a nightmare initially. I remember I had many issues with this kind of stuff at first. –  Oct 30 '15 at 10:52
  • Thanks Mat. I modified the button close as below and then try using page.refs.modalClose and this returns undefined.. react 0.13 is what I am using. I am new to react too.. – Tin Ng Oct 30 '15 at 23:09
  • Yeah, Im trying to figure out how to do this with my setup but I'm also having trouble. My tests work because I pass in a component into the modal, and I test that component outside of the context of being in a modal. You can test that your `openModal` and `closeModal` functions actually change the `state` but I'm not sure how I'd test that actually clicking the button produces the correct result –  Nov 01 '15 at 00:15
  • Also, I'd recommend you move the open/close modal functions outside render. They should be siblings to render. The render method should never change state so I'd avoid defining those functions there. Sorry I couldn't be of more help! –  Nov 01 '15 at 00:16

2 Answers2

1

I finally got it working using jquery selector..

import {Modal}  from 'react-bootstrap';
import React from 'react';

export default class ModalExperiment extends React.Component {


  constructor(props) {
    super(props);
    this.state = {
      open: false
    }
  }
  openModal() {
    this.setState({open: true});
  }

  closeModal() {
    this.setState({open: false });
  }

  render(){

    return (

      <div>
        <button type='button' onClick={this.openModal.bind(this)} className='openButton'>Launch modal</button>
        {this.state.open?
        <Modal
          show={this.state.open}
          onHide={this.closeModal.bind(this)}
          aria-labelledby="ModalHeader" className='modalClass'
          >
          <Modal.Header closeButton>
            <Modal.Title id='ModalHeader'>A Title Goes here</Modal.Title>
          </Modal.Header>
          <Modal.Body>
            <p>Some Content here</p>
          </Modal.Body>
          <Modal.Footer>
            <button className='closeButton btn btn-primary' onClick={this.closeModal.bind(this)}>
              Close
            </button>
          </Modal.Footer>
        </Modal> : ''}
      </div>
    )
  }
}

And here is the test...

'use strict';

import React from 'react';
import ReactAddons from 'react/addons';
import {Modal}  from 'react-bootstrap';
import ModalExperiment  from '../ModalExperiment';
import $ from 'jquery';

let TestUtils = React.addons.TestUtils;

describe('ModalExperimentFunctional', function() {

  let page;

  beforeEach(() => {
    document.body.innerHTML = '';

    page = TestUtils.renderIntoDocument(<ModalExperiment/>);
  });



  fit("click the ok button should open the modal", () => {
    expect($('.closeButton').length).toBe(0);
    let openButton = React.findDOMNode(TestUtils.findRenderedDOMComponentWithClass(page, 'openButton'));

    TestUtils.Simulate.click(openButton);


    expect($('.closeButton').length).toBe(1);
    $('.closeButton').click();
    expect($('.closeButton').length).toBe(0);

  });
});
Tin Ng
  • 937
  • 2
  • 11
  • 25
0

In test use:

const component = ReactTestUtils.renderIntoDocument(<Modal />);
ReactTestUtils.Simulate.click(document.body.getElementsByClassName("close")[0]);