5
votes

I'm using jsdom with enzyme+mocha+chai to test the behavior of a React component. The component has a method to focus a DOM node (using the usual node.focus()) and I want to test the node is actually focused when it's called.

To know which node is focused, I compare document.activeElement to the node I expect to be focused.

However, after upgrading to jsdom 9.1+, document.activeElement seems always be HTMLBodyElement, even after calling the node's focus() method.

With jsdom 9.0 the tests run fine.

I read jsdom 9.1+ contains some changes related to the focus event, yet I couldn't understand how make document.activeElement behave as expected. Any help?

3

3 Answers

5
votes

Could it be that you are missing a tabindex attribute on the element that you are trying to focus? It must be set to a valid integer for jsdom to interpret it as focusable.

You can see this in the jsdom source code.

2
votes

To extend @Epeli's answer:

The element to be focussed must indeed be added to the DOM tree before document.activeElement can be set to it.

If you are mounting a component and want to check if something inside of that component got focussed, try to add the following inside your test:

test(() => {
    const wrapper = mount(<SomeComponent />)
    document.body.appendChild(wrapper.find('#FocusElement').getDOMNode())
    // the rest of your test...
})
0
votes

One reason it might not work is that the element has not been added to the DOM tree.

const input = document.createElement("input");
document.body.appendChild(input);

input.focus();
console.log(document.activeElement === input)