jsdom 9.1+ 在聚焦节点时不设置 document.activeElement

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

我正在使用 jsdom 和 enzyme+mocha+chai 来测试 React 组件的行为。该组件有一个聚焦 DOM 节点的方法(使用通常的 node.focus()),我想测试该节点在调用时是否真正聚焦。

为了知道哪个节点被聚焦,我将 document.activeElement 与我希望聚焦的节点进行比较。

然而,在升级到 jsdom 9.1+ 之后,document.activeElement 似乎总是 HTMLBodyElement,即使在调用节点的 focus() 方法之后。

使用 jsdom 9.0 测试 运行 没问题。

我阅读了 jsdom 9.1+ contains some changes 与焦点事件相关的内容,但我无法理解如何使 document.activeElement 的行为符合预期。有帮助吗?

可能是您要聚焦的元素缺少 tabindex 属性?必须将其设置为有效整数,以便 jsdom 将其解释为可聚焦。

您可以在 jsdom source code 中看到这个。

它可能不起作用的一个原因是该元素尚未添加到 DOM 树中。

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

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

扩展@Epeli 的回答:

要聚焦的元素确实必须先添加到 DOM 树中,然后才能设置 document.activeElement。

如果您正在安装一个组件并想检查该组件内部的某些内容是否获得了焦点,请尝试在您的测试中添加以下内容:

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