英文:
How do I tab to a non-standard element while unit-testing for keyboard accessibility?
问题
## 背景
我有一个React/TypeScript项目,我使用Jest和React Testing Library (RTL)进行测试。我有一个通过的测试,测试了RTL的`userEvent.tab()`,通过按Tab键来测试按钮的可访问性。
```javascript
test('that the button is keyboard accessible', () => {
// 安排
const page = render(<BrowserRouter><Page/></BrowserRouter>).container;
const button: HTMLElement = within(page).getByText('Form button');
// 行动
for (let i = 0; i < 5; ++i) {
userEvent.tab();
}
// 断言
expect(button).toHaveFocus();
});
<br>
问题
我有另一个类似的键盘可访问性测试失败了:
test('that My button is keyboard accessible', () => {
// 安排
const nextPage: HTMLElement = render(<NextPage />).container;
const button = screen.getByText('My button');
// 行动
for (let i = 0; i < 3; ++i) {
userEvent.tab();
}
// 断言
expect(button).toHaveFocus();
});
错误信息:
预期具有焦点的元素:
<my-button>My button</my-button> // 注意:`<my-button>`是我公司设计系统中特定的按钮组件。
接收到具有焦点的元素:
<body><div><div class="nextPage">... 更多标签在这里...<div class="bodyButtons"><my-button>My button</my-button></div></div></div></div></div></body>
无论我多少次使用userEvent.tab()
,接收到具有焦点的元素始终是<body>
。我认为这是因为尝试定位公司设计系统中的非标准按钮(<my-button>
)引起的。
<br>
问题
如何在我的单元测试中使用键盘访问此页面上的"Account"按钮? 在部署的应用程序上键盘操作正常工作。
<br>
我尝试过的事情
- 根据第一个单元测试使用
within
- 将
userEvent.tab()
的次数从0更改为1、2、5、10 - 使用
fireEvent
而不是userEvent
- 渲染组件时不使用container
- 最初在按Tab键之前使用
button.focus()
,但我也无法将焦点放在按钮上 - 将
<my-button>
更改为使用标准HTML标签<button>
- 使用
querySelector('my-button')
获取按钮
<details>
<summary>英文:</summary>
## Background
I have a React/TypeScript project that I test with Jest and React Testing Library (RTL). I have one passing test that tests keyboard accessibility with RTL's `userEvent.tab()` by tabbing to a button.
test('that the button is keyboard accessible', () => {
// Arrange
const page = render(<BrowserRouter><Page/></BrowserRouter>).container;
const button: HTMLElement = within(page).getByText('Form button');
// Act
for (let i = 0; i < 5; ++i) {
userEvent.tab();
}
// Assert
expect(button).toHaveFocus();
});
<br>
## Problem
I have another similar keyboard accessibility test that fails:
test('that My button is keyboard accessible', () => {
// Arrange
const nextPage: HTMLElement = render(<NextPage />).container;
const button = screen.getByText('My button');
// Act
for (let i = 0; i < 3; ++i) {
userEvent.tab();
}
// Assert
expect(button).toHaveFocus();
});
The error:
Expected element with focus:
<my-button>My button</my-button> // Note: <my-button>
is a button component specific to the design system my company uses.
Received element with focus:
<body><div><div class="nextPage">... more tags here...<div class="bodyButtons"><my-button>My button</my-button></div></div></div></div></body>
No matter how many times I `userEvent.tab()`, the received element with focus is always `<body>`. I assume this is due to attempting to target a non-standard button (`<my-button>`) that is part of my company's design system.
<br>
## Question
**How do I keyboard to the Account button on this page with my unit test?** Keyboarding on the deployed app works just fine.
<br>
## Things I've tried
- `within` per the first unit test
- Changing the number of `userEvent.tab()`s from 0 to 1 to 2 to 5 to 10
- `fireEvent` instead of `userEvent`
- Rendering the component without the container
- Initially using `button.focus()` before tabbing, but I can't focus the button either
- Changing `<my-button>` to `<button>` to use a standard HTML tag
- Getting the button with `querySelector('my-button')`
</details>
# 答案1
**得分**: 0
> 如何在我的单元测试中使用键盘访问此页面上的“Account”按钮?
## 解决方案
我给`<my-button>`添加了`tabindex=0`属性。这使按钮可以在程序中获得焦点。
产品代码:
```jsx
<my-button onClick={handleClick} tabIndex='0'>我的按钮</my-button>
测试代码:
test('确保我的按钮可以通过键盘访问', () => {
// 安排
render(<NextPage/>);
const button: HTMLElement = screen.getByText('我的按钮');
// 操作
for (let i = 0; i < 3; ++i) {
userEvent.tab();
}
// 断言
expect(button).toHaveFocus();
});
更多信息请参阅MDN上的tabIndex
文档。
英文:
> How do I keyboard to the Account button on this page with my unit test?
Solution
I gave <my-button>
the tabindex=0
attribute. This made the button programmatically focusable.
The product code:
<my-button onClick={handleClick} tabIndex='0'>My button</my-button>
The test:
test('that My button is keyboard accessible', () => {
// Arrange
render(<NextPage/>);
const button: HTMLElement = screen.getByText('My button');
// Act
for (let i = 0; i < 3; ++i) {
userEvent.tab();
}
// Assert
expect(button).toHaveFocus();
});
More info from MDN on tabIndex
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论