jpuri / react-draft-wysiwyg

A Wysiwyg editor build on top of ReactJS and DraftJS. https://jpuri.github.io/react-draft-wysiwyg
MIT License
6.41k stars 1.16k forks source link

Testing with mocha and jsdom #404

Open gilmillasseau opened 7 years ago

gilmillasseau commented 7 years ago

Test

import React from 'react';
import expect from 'expect';
import { mount } from 'enzyme';
import Editor from '../Editor';

describe('<Editor />', () => {
  it('should render', () => {
    const wrapper = mount(<Editor />);
    expect(wrapper.length).toBe(1);
  });
});

Subject

import React, { Component } from 'react';
import { Editor } from 'react-draft-wysiwyg';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';

export default class RichEditor extends Component {
  constructor(props) {
    super(props);

    this.onEditorStateChange = this.onEditorStateChange.bind(this);
  }

  onEditorStateChange(editorState) {
    this.setState({
      editorState,
    });
  }

  render() {
    return (
      <Editor onEditorStateChange={this.onEditorStateChange}/>
    );
  }
}

mocha setup

const jsdom = require('jsdom');

const { JSDOM } = jsdom;

const dom = new JSDOM('');
const exposedProperties = ['window', 'navigator', 'document'];

const { window } = dom;

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};

Object.keys(document.defaultView).forEach((property) => {
  if (typeof global[property] === 'undefined') {
    exposedProperties.push(property);
    global[property] = document.defaultView[property];
  }
});

I am having always the same output TypeError: Cannot read property 'addEventListener' of null

jpuri commented 7 years ago

Hi @gilmillasseau ,

This test setup works for me: https://github.com/jpuri/react-draft-wysiwyg/blob/master/config/test-setup.js for JSDOM. Looks like tests and not getting dom elements.

I have anyways added some null checks to avoid this situation. Change will be released soon.

mikeLspohn commented 7 years ago

I'm getting the same issue, even with the added HTMLElement and AnchorElement attributes added.

var jsdom = require('jsdom').jsdom
var LocalStorage = require('node-localstorage').LocalStorage

var exposedProperties = ['window', 'navigator', 'document', 'localStorage']

global.localStorage = new LocalStorage('../localStorageTemp')
global.window.localStorage = global.localStorage

global.document = jsdom('')
global.window = document.defaultView
global.window.confirm = s => s
global.HTMLElement = window.HTMLElement
global.HTMLAnchorElement = window.HTMLAnchorElement

Object.keys(document.defaultView).forEach((property) => {
  if (typeof global[property] === 'undefined') {
    exposedProperties.push(property)
    global[property] = document.defaultView[property]
  }
})

global.navigator = {
  userAgent: 'node.js'
}

Test

// ava and enzyme
test('componentDidMount sets editor state', t => {
  const Wrapper = mount(<NewCommentForm editorProps={{/* props for editor */}} />)
})

// where NewCommentForm is like
const NewCommentForm = ({editorProps}) => <div><Editor {...editorProps} /></div>

throws Cannot read proptery 'addEventListener' of null. Thank you for already looking into this!