byRole 没有返回 DOM 元素

byRole is not returning the DOM element

我正在将我以前使用 Jest 和 Enzyme 编写的一些单元测试用例迁移到 React 测试库。我正在使用 Material UI 的 Select 组件并且我知道,为了打开下拉菜单,我们必须在相应的 [=17] 上触发 mouseDown 事件=].以下是我在 Enzyme 中的做法(有效):

wrapper.find('[role="button"]').simulate('mousedown', { button: 0 });

我正在尝试通过以下方式使用 React 测试库实现相同的效果,但它不起作用:

const { container, getAllByRole, getByRole } = renderComponent(mockProps);
fireEvent.mouseDown(getByRole('button')); // trigger the mouseDown on div having role=button

在此之后,我尝试访问 listbox 元素,即 ul 元素:

getByRole('listbox')

它抛出一个错误并说:

TestingLibraryElementError: Unable to find an accessible element with the role "listbox"

There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the `hidden` option to `true`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole

我已经验证并且 ul 元素可见(它和它的父元素都没有显示 none 或隐藏可见性)

更新 - 1

我尝试了以下所有方法来等待元素出现在DOM中:

在这两种情况下都会抛出错误 Unable to find role="listbox"

怎么了?

确保动画不会影响您的结果。如果动画改变不透明度或显示并且它们在 jest 断言之前没有完成......它可能会抛出错误。

如果在第一次渲染时无法访问该元素,则可能会出现此错误,您可以尝试将隐藏的选项传递给 getByRole 的第二个参数中的选项键,如果这不起作用,您可以尝试使用 findByRole,即方法等待元素,如果你想确定元素的可见性,你可以尝试在测试中添加一个 waitFor。

getByRole('listbox', { options: { hidden: true } });

我找到了这个问题的根本原因。我在 disablePortal 模式下使用来自 MUI 的 Select 组件,这使得菜单列表在父组件而不是文档主体内呈现。但是当 MUI 这样做时,它不会从父组件的 div 中删除 aria-hidden 属性,并且由于该测试库无法在其中找到 listbox (ul) 元素.

这里报告了一个问题: https://github.com/mui/material-ui/issues/19450

因此,作为变通方法,我将 data-testid 传递给 menu 组件 (MenuListProps) 并使用它来获取 listbox.