Wrong document DOMException when testing React using Mocha and Sinon

325 Views Asked by At

I am new to React and trying to unit test my page (react component) using MochaTest and sinon. The page is very simple with two mandatory fields first name and last name. If both are filled, it should submit successfully and if only one is filled in, it should not submit and display a validation error message.

Below is the code snippet:

NameTest.js :

var React          = require('react')
var ReactAddons    = require('react/addons')
var TestUtils = React.addons.TestUtils
var sinon = require("sinon");

describe('Name page component', function(){

    it('should submit when all valid values are entered', function() {
        var MochaMix = require('mocha-mix');
        var sandbox = MochaMix.sandbox;
        var stubContexts = MochaMix.stubContexts;
        var stubRouter = stubContexts.createReactRouterStub(sandbox)
        stubRouter.makeHref = sinon.stub.returns('/name')
        var mix = MochaMix.mix({
            require: '/src/page/name/NamePage'
            , context: stubRouter
        });
        var namePage = mix.renderComponent()

        var formElement = TestUtils.findRenderedDOMComponentWithTag(namePage, 'form')
        var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(formElement, 'input')[0].getDOMNode()
        var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(formElement, 'input')[1].getDOMNode()

        React.findDOMNode(firstNameElement).value = 'Lansen';
        TestUtils.Simulate.change(firstNameElement);
        React.findDOMNode(lastNameElement).value = 'Lansen';
        TestUtils.Simulate.change(lastNameElement);

        var buttonElement = TestUtils.findRenderedDOMComponentWithTag(namePage, 'button')
        TestUtils.Simulate.submit(formElement.getDOMNode())
        var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(namePage, 'error-message')

        var transitionToCall = namePage.context.router.transitionTo.getCall(0);

        expect(errorSpans.length).to.equal(0);
        expect(transitionToCall.args[0]).to.equal('name');
    })

    it('should show one error when only one of the fields is filled', function() {
        var MochaMix = require('mocha-mix');
        var sandbox = MochaMix.sandbox;
        var stubContexts = MochaMix.stubContexts;
        var stubRouter = stubContexts.createReactRouterStub(sandbox)
        stubRouter.makeHref = sinon.stub.returns('/name')
        var mix = MochaMix.mix({
            require: '/src/page/name/NamePage'
            , context: stubRouter
        });
        var namePage = mix.renderComponent()

        var formElement = TestUtils.findRenderedDOMComponentWithTag(namePage, 'form')
        var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(formElement, 'input')[0].getDOMNode()
        var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(formElement, 'input')[1].getDOMNode()

        React.findDOMNode(firstNameElement).value = 'Lansen';
        TestUtils.Simulate.change(firstNameElement);

        var buttonElement = TestUtils.findRenderedDOMComponentWithTag(namePage, 'button')
        try{
            TestUtils.Simulate.submit(formElement.getDOMNode())
        }catch(err){
            console.log('NamePage err.message :', err.message)
            console.log('NamePage err.stack :', err.stack)
            throw err
        }

        var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(namePage, 'error-message')

        var transitionToCall = namePage.context.router.transitionTo.getCall(0);

        expect(errorSpans.length).to.equal(0);
        expect(transitionToCall.args[0]).to.equal('name');
    })
});

code snippet from NamePage.jsx:

_onSubmit(e) {
  e.preventDefault()
  this.state.form.validate(this.refs.form, (err, isValid) => {
      if (isValid) {
          this.context.router.transitionTo('name', {}, {}, {
              method: 'POST',
              body: this.state.form.data
          })
      }
  })
  this.forceUpdate()
  },



render() {
  return <div>
      <h1 className="heading-large">Your name</h1>
      <form action={this.context.router.makeHref('name')} method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
          {this.state.form.render()}
        <button type="submit" className="button">Next</button>
      </form>
    </div> 
}

When I try to test the code, I get the below error. This error occurs at the line - TestUtils.Simulate.submit(formElement.getDOMNode()) in NameTest.js:

NamePage err.message : Wrong document
NamePage err.stack : DOMException: Wrong document
    at [object Object].core.Node.insertBefore (/Users/jenny/Documents/mycompanymy/work/projects/mycompany-myapp-portal/node_modules/jsdom/lib/jsdom/level1/core.js:579:13)
    at [object Object].core.Node.insertBefore (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/jsdom/lib/jsdom/level2/events.js:326:32)
    at insertChildAt (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/DOMChildrenOperations.js:34:14)
    at Object.DOMChildrenOperations.processUpdates (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/DOMChildrenOperations.js:106:11)
    at Object.ReactDOMIDOperations.dangerouslyProcessChildrenUpdates (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactDOMIDOperations.js:150:27)
    at Object.wrapper [as processChildrenUpdates] (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactPerf.js:70:21)
    at processQueue (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactMultiChild.js:137:31)
    at ReactDOMComponent.ReactMultiChild.Mixin.updateChildren (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactMultiChild.js:259:13)
    at ReactDOMComponent.Mixin._updateDOMChildren (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactDOMComponent.js:470:12)
    at ReactDOMComponent.Mixin.updateComponent (/Users/jenny/Documents/mycompany/work/projects/mycompany-myapp-portal/node_modules/react/lib/ReactDOMComponent.js:319:10)

I have looked into this and have tried to apply it to my code but hasn't helped me. Not sure if I have applied it correctly to my code.

Any help is highly appreciated.

0

There are 0 best solutions below