I created a popup component in React using the element. The element comes with a useful pseudo element "::backdrop". I created functionality that when a user clicks on the backdrop, the popup closes. I'm trying to test this behaviour in React testing library, but without success. I can't seem to interact with this ::backdrop element. Is there a way to do it which I'm overlooking, or maybe another way to test this behaviour?
Unfortunately it is impossible to directly interact with/target pseudo elements and that includes ::backdrop
.
When you click on the "backdrop" you actually click on the <dialog>
element, so in order to test that, you need to target that element.
Give your dialog element a role="dialog"
and in your test use getByRole('dialog', { hidden: true })
to grab it. the hidden: true
option is necessary as RTL doesn't fully support the dialog element yet so at the moment it always considers it "hidden", even when it is open.
After grabbing the dialog element, just simulate a click using the userEvent
api and check that your function was called.
P.S - You might want include this workaround mentioned in this thread to mock the showModal
and close
methods for the same reason that jsdom doesn't fully support it yet
In the end your test might look like something along these lines:
// workaround until dialog elements are supported in jest/jsdom
beforeAll(() => {
HTMLDialogElement.prototype.showModal = jest.fn();
HTMLDialogElement.prototype.close = jest.fn();
});
it('closes the dialog when the backdrop is clicked', async () => {
const { user } = render(<Modal {...props} />);
const backdrop = screen.getByRole('dialog', { hidden: true });
await user.click(backdrop);
expect(onBackdropClick).toHaveBeenCalledTimes(1);
});
I was creating a modal component based on the <dialog>
element very recently and these 2 resources helped me a lot: