Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jsdom 9.1+ does not set document.activeElement when focusing a node

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?

like image 366
gpbl Avatar asked Jul 31 '16 07:07

gpbl


2 Answers

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.

like image 183
Josh Minzner Avatar answered Nov 05 '22 03:11

Josh Minzner


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...
})
like image 21
Marnix.hoh Avatar answered Nov 05 '22 02:11

Marnix.hoh