i have a following component
const ModalComponent = () => {
const [visible, setVisible] = useState(false);
return (
<>
<Button type="primary" onClick={() => setVisible(true)}>
Open Modal
</Button>
<Modal
title="Modal title"
centered
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
>
content
</Modal>
</>
);
};
and this modal is closed when ESC key is pressed. However my test fails for some reason. My test is:
it("closes modal on ESC press", async () => {
render(<ModalComponent />)
expect(
await screen.findByText(
"content",
),
).toBeVisible();
fireEvent.keyDown(document, { key: "Escape", keyCode: 27 });
await waitFor(async () => {
expect(
await screen.findByText(
"content",
),
).not.toBeVisible();
});
});
Element is still visible
Since antd modal component use rc-dialog, there is a role='dialog' attribute in the div element of Panel component.
Also check "esc to close" test case, you will know the keyboard event is not added to document, but the element that has .rc-dialog className.
antd passes its own prefixCls to rc-dialog component. So there is no .rc-dialog className anymore when you use antd modal. So we should not use .rc-dialog as the selector to find the element, we could use role='dialog' mentioned above. RTL provides a getByRole query to do this.
Final solution:
index.tsx:
import { Button, Modal } from 'antd';
import React from 'react';
import { useState } from 'react';
export const ModalComponent = () => {
const [visible, setVisible] = useState(false);
return (
<>
<Button type="primary" onClick={() => setVisible(true)}>
Open Modal
</Button>
<Modal
title="Modal title"
centered
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
>
content
</Modal>
</>
);
};
index.test.tsx:
import { fireEvent, render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { ModalComponent } from '.';
describe('ModalComponent', () => {
test('should pass', async () => {
render(<ModalComponent />);
const openModalButton = screen.getByText(/open modal/i);
fireEvent.click(openModalButton);
expect(await screen.findByText('content')).toBeVisible();
const dialog = screen.getByRole('dialog');
fireEvent.keyDown(dialog, { keyCode: '27' });
expect(await screen.findByText('content')).not.toBeVisible();
});
});
Test result:
PASS stackoverflow/73147451/index.test.tsx (11.646 s)
ModalComponent
✓ should pass (158 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 90 | 100 | 75 | 88.89 |
index.tsx | 90 | 100 | 75 | 88.89 | 16
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.199 s
package version:
"antd": "^4.16.12",