Search code examples
htmlreactjsjestjsreact-testing-library

Testing <dialog>'s backdrop clicks in React testing library


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?


Solution

  • 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:

    1. React modal using dialog element - article
    2. introduction to dialog element - video