【问题标题】:How to test key down event on material ui MenuList component using react-testing-library如何使用 react-testing-library 测试材料 ui MenuList 组件上的按键事件
【发布时间】:2020-06-11 04:48:00
【问题描述】:

我有以下 MenuList 组件,我想在其上测试按键事件。

组件

import MenuItem from '@material-ui/core/MenuItem';
import MenuList from '@material-ui/core/MenuList';
import * as React from 'react';

export default function App() {
  return (
    <div>
      <MenuList autoFocusItem={true}>
        <MenuItem>option 1</MenuItem>
        <MenuItem>option 2</MenuItem>
        <MenuItem>option 3</MenuItem>
      </MenuList>
    </div>
  );
}

测试

import {
    fireEvent,
    render,
} from 'test-utils';
import React from 'react';
import TestMenuList from './TestMenuList';

test('that on key down press, the focus on menu list item moves down', async () => {
    // Render component
    const { getAllByRole, getByRole } = render(<TestMenuList />, {});

    let MenuItem1 = getAllByRole('menuitem')[0];
    expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(true); // assert 1

    const Menu = getByRole('menu');
    fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });

    MenuItem1 = getAllByRole('menuitem')[0];
    const MenuItem2 = getAllByRole('menuitem')[1];
    expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(false); // assert 2
    expect(MenuItem2.classList.contains('Mui-focusVisible')).toBe(true); // assert 3
});

为了确保某个菜单项处于焦点位置,我正在检查该菜单项是否具有 Mui-focusVisible 类。因为我在MenuList 中设置了autoFocusItem={true},所以第一个菜单项应该自动添加Mui-focusVisible 类。那就是正在通过的断言语句 1。

    let MenuItem1 = getAllByRole('menuitem')[0];
    expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(true); // assert 1

然后我在菜单上触发了一个按键事件

    const Menu = getByRole('menu');
    fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });

并检查Mui-focusVisible 类是否已从第一个菜单项中删除并添加到第二个菜单项中。现在,测试在断言语句 2 和 3 处失败。

    MenuItem1 = getAllByRole('menuitem')[0];
    const MenuItem2 = getAllByRole('menuitem')[1];
    expect(MenuItem1.classList.contains('Mui-focusVisible')).toBe(false); // assert 2
    expect(MenuItem2.classList.contains('Mui-focusVisible')).toBe(true); // assert 3

我为MenuItem1MenuItem2 记录了classList,以查看Mui-focusVisible 是否从第一个菜单项中删除并在按键事件后添加到第二个菜单项。但是Mui-focusVisible 类仍然在第一个菜单项中,而不是在第二个菜单项中。

我尝试添加await wait()

fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 });
await wait();

act(() =&gt; {})包装火灾事件,

act(() => fireEvent.keyDown(Menu, { Key: 'ArrowDown', code: 40 }));
await wait()

在第一个菜单列表项而不是菜单本身上触发按键事件。

act(() => fireEvent.keyDown(MenuItem1, { Key: 'ArrowDown', code: 40 }));
await wait()

他们都没有工作。我为这个组件创建了一个codesandbox,在这里,它似乎在 UI 中完美运行。但是测试失败了。

【问题讨论】:

    标签: javascript reactjs typescript material-ui react-testing-library


    【解决方案1】:

    我建议查看 MenuList: https://github.com/mui-org/material-ui/blob/v4.9.4/packages/material-ui/test/integration/MenuList.test.js 的集成测试。

    键盘导航经过了非常彻底的测试。但是您会发现,它主要检查具有焦点的元素,而不是检查Mui-focusVisible。焦点可见逻辑 (https://github.com/mui-org/material-ui/blob/v4.9.4/packages/material-ui/src/utils/focusVisible.js) 依赖于在文档级别跟踪鼠标和键盘事件,并且在测试框架中可靠地触发这一点并不容易(尽管您可以在此处查看焦点可见逻辑的测试:@ 987654323@)。我建议将您的测试从焦点移开,并依靠 Material-UI 来管理和测试应用 Mui-focusVisible 类。

    【讨论】:

      猜你喜欢
      • 2020-03-15
      • 2020-03-10
      • 1970-01-01
      • 2021-02-23
      • 2020-12-20
      • 2019-06-14
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多