React, Jest, and CustomEvent testing

Simple problem: I need my React component to communicate an event to a JQuery plugin in Rails.

Super complicated solution: I have the component emit an event so that a JQuery event listener can know to do its thing.

Easy enough. I set to work writing tests first, but Jest keeps spitting out an error:

1
ReferenceError: CustomEvent is not defined

React and Jest don’t know about the CustomEvent constructor for some reason. I need the assurance that an event will be fired every time an agent clicks the clear button on an input box.

The component looks a little like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var Tagger = React.createClass({ displayName: 'Tagger',
/**
* Clear the tagBox input
*/
clear: function(evt) {
this.refs.tagBox.getDOMNode().value = '';
// I can't get jquery-tokeninput to play nicely. This
// event signals the listner defined in queries.coffee
window.dispatchEvent(new CustomEvent('clear-tags'));
},

// ...

render: function() {
// ...
}
});
module.exports = Tagger;

In the corresponding test file, I provide my own CustomeEvent and mock the window.dispatchEvent function:

1
2
3
4
if (!window.CustomEvent) {
CustomEvent = function(name, params){ return params;};
}
window.dispatchEvent = jest.genMockFunction();

By doing all that, I can perform meaningful tests like this:

1
2
3
4
5
6
7
8
9
10
11
12
it('should emit a clear-tags event', function() {
var tagger = TestUtils.renderIntoDocument(<Tagger model="pick" />);
expect(window.dispatchEvent.mock.calls.length).toEqual(0);

// Enter some tags
tagger.refs.tagBox.getDOMNode().value = 'bill murray, comedy, movies';

// Clear
TestUtils.Simulate.click(tagger.refs.clearButton.getDOMNode());

expect(window.dispatchEvent.mock.calls.length).toEqual(1);
});