Simulate keydown on document for JEST unit testing
Asked Answered
A

3

24

Using JEST to unit test a component that has a keydown listener attached to the document.

How can I test this in JEST? How do I simulate the keydown event on the document? I need the event listener to be on the document since it is supposed to respond the keyboard action irrespective of the focussed element.

EDIT: The question here is about simulating the event on the document or the document.body. All the examples are regarding an actual DOM node, that works fine but the document does not.

Currently trying to do this:

TestUtils.Simulate.keyDown(document, {keyCode : 37}); // handler not invoked
Absent answered 10/11, 2015 at 19:53 Comment(1)
Possible duplicate of React's TestUtils.Simulate.keyDown does not workAdalie
M
47

I had the exact same problem and unfortunately couldn't find any details on how to solve this using TestUtils.Simulate. However this issue gave me the idea of simply calling .dispatchEvent with a KeyboardEvent inside my jest tests directly:

var event = new KeyboardEvent('keydown', {'keyCode': 37});
document.dispatchEvent(event);

You can find details on the KeyboardEvent here: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent

Majorette answered 24/1, 2016 at 18:18 Comment(3)
For me it only worked when changing 'keydown' to 'keypress'Huppah
As of 2020 and latest version of Jest, this works for me if I use global.dispatchEvent instead of window.dispatchEventReadjustment
In addition, you may need bubbles: true in the event data.Haroldson
A
5

You can also replace the whole document.eventListener with mock function before you mount the component:

let events;
document.addEventListener = jest.fn((event, cb) => {
  events[event] = cb;
});

And simulate event by calling events[event] after mounting, e.g.:

events.keydown({ keyCode: 37 })

Also, it's quite comfortable to do first part in beforeEach() function if you have many tests dealing with DOM events.

Accordingly answered 17/1, 2019 at 5:6 Comment(0)
T
2

Following @Iris Schaffer answer, If your code makes use of ctrl/alt/shift keys, you will need to init them, as well as mocking implementation of getModifierState method on KeyboardEvent

const keyboardEvent = new KeyboardEvent('keydown', { keyCode, shiftKey, altKey, ctrlKey });
jest.spyOn(keyboardEvent, 'getModifierState').mockImplementation((modifier) => {
     switch (modifier) {
          case 'Alt':
               return altKey;
          case 'Control':
               return ctrlKey;
          case 'Shift':
               return shiftKey;
     }
});
Tucky answered 18/5, 2020 at 21:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.