使用带有表单输入元素的 ReactBootstrap 模态单元测试 React 组件
Unit Testing React Component using ReactBootstrap Modal with a Form Input element
我已经反应 - bootstrap 的模态组件有一个输入,当我对 Focus 进行单元测试时,它说它收到了整个文档,而不仅仅是输入元素。
有谁知道为什么focus to whole doc(Does Modal make the whole document to have focused)。非常感谢您的帮助。下面是我的代码
Signup.js
import { Container, Form, Modal } from 'react-bootstrap';
const Signup = () => {
const handleClick = (e) => {
e.preventDefault();
const element = e.currentTarget;
const id = element.getAttribute('id');
if (id === 'userEmail') {
const emailLabel = document.getElementById('emailLabel');
emailLabel.style.fontSize = '30px';
}
};
return (
<Container>
<Modal show={true} autoFocus>
<Modal.Header>Header</Modal.Header>
<Modal.Body>
<Form>
<Form.Group>
<Form.Label>
<span id="emailLabel">Email</span>
<Form.Control
name="userEmail"
id="userEmail"
data-testid="userEmail"
type="email"
onClick={(e) => handleClick(e)}
/>
</Form.Label>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
</Container>
);
};
export default Signup;
Signup.test.js
import Signup from '.';
describe('helo', () => {
it('signup', async () => {
render(<Signup />);
const emailInput = screen.getByTestId('userEmail');
fireEvent.click(emailInput);
expect(emailInput).toHaveFocus();
});
});
结果
Expected element with focus:
<input class="form-control" data-testid="userEmail" id="userEmail" name="userEmail" type="email" />
Received element with focus:
<div aria-modal="true" class="fade modal show" role="dialog" style="display: block;" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header">Header</div><div class="modal-body"><form class=""><div class="form-group"><label class="form-label"><span id="emailLabel" style="font-size: 30px;">Email</span><input class="form-control" data-testid="userEmail" id="userEmail" name="userEmail" type="email" /></label></div></form></div></div></div></div>
123 | const emailInput = screen.getByTestId('userEmail');
124 | fireEvent.click(emailInput);
> 125 | expect(emailInput).toHaveFocus();
| ^
126 | });
127 | });
128 |
考虑 fireEvent.click,它创建一个点击事件并在给定的 DOM 节点上分派该事件。这适用于大多数情况,当您只是想测试单击元素时发生的情况,但当用户实际单击您的元素时,通常会触发这些事件(按顺序):
fireEvent.mouseOver(element)
fireEvent.mouseMove(element)
fireEvent.mouseDown(element)
element.focus() (if that element is focusable)
fireEvent.mouseUp(element)
fireEvent.click(element)
看看这个 post 博客 https://testing-library.com/docs/guide-events/
首先,我觉得您导入注册组件的方式很奇怪:import Signup from '.';
而且我认为您应该传递 render(<Signup show={true}/>);
以呈现模态并能够聚焦输入,因为只有浏览器上的可见元素是可聚焦的
我已经反应 - bootstrap 的模态组件有一个输入,当我对 Focus 进行单元测试时,它说它收到了整个文档,而不仅仅是输入元素。
有谁知道为什么focus to whole doc(Does Modal make the whole document to have focused)。非常感谢您的帮助。下面是我的代码
Signup.js
import { Container, Form, Modal } from 'react-bootstrap';
const Signup = () => {
const handleClick = (e) => {
e.preventDefault();
const element = e.currentTarget;
const id = element.getAttribute('id');
if (id === 'userEmail') {
const emailLabel = document.getElementById('emailLabel');
emailLabel.style.fontSize = '30px';
}
};
return (
<Container>
<Modal show={true} autoFocus>
<Modal.Header>Header</Modal.Header>
<Modal.Body>
<Form>
<Form.Group>
<Form.Label>
<span id="emailLabel">Email</span>
<Form.Control
name="userEmail"
id="userEmail"
data-testid="userEmail"
type="email"
onClick={(e) => handleClick(e)}
/>
</Form.Label>
</Form.Group>
</Form>
</Modal.Body>
</Modal>
</Container>
);
};
export default Signup;
Signup.test.js
import Signup from '.';
describe('helo', () => {
it('signup', async () => {
render(<Signup />);
const emailInput = screen.getByTestId('userEmail');
fireEvent.click(emailInput);
expect(emailInput).toHaveFocus();
});
});
结果
Expected element with focus:
<input class="form-control" data-testid="userEmail" id="userEmail" name="userEmail" type="email" />
Received element with focus:
<div aria-modal="true" class="fade modal show" role="dialog" style="display: block;" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header">Header</div><div class="modal-body"><form class=""><div class="form-group"><label class="form-label"><span id="emailLabel" style="font-size: 30px;">Email</span><input class="form-control" data-testid="userEmail" id="userEmail" name="userEmail" type="email" /></label></div></form></div></div></div></div>
123 | const emailInput = screen.getByTestId('userEmail');
124 | fireEvent.click(emailInput);
> 125 | expect(emailInput).toHaveFocus();
| ^
126 | });
127 | });
128 |
考虑 fireEvent.click,它创建一个点击事件并在给定的 DOM 节点上分派该事件。这适用于大多数情况,当您只是想测试单击元素时发生的情况,但当用户实际单击您的元素时,通常会触发这些事件(按顺序):
fireEvent.mouseOver(element)
fireEvent.mouseMove(element)
fireEvent.mouseDown(element)
element.focus() (if that element is focusable)
fireEvent.mouseUp(element)
fireEvent.click(element)
看看这个 post 博客 https://testing-library.com/docs/guide-events/
首先,我觉得您导入注册组件的方式很奇怪:import Signup from '.';
而且我认为您应该传递 render(<Signup show={true}/>);
以呈现模态并能够聚焦输入,因为只有浏览器上的可见元素是可聚焦的