Search code examples
reactjsjestjsmaterial-uiintegration-testingreact-testing-library

Is there a way to trigger Material-UI Modal close manually


I use the Popover component, it is like Modal.
I have a test like this:

  test('should close popover when clicked two times', () => {
    userEvent.click(targetElem);
    let popover = screen.getByTestId('popover');
    document.body.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape' }));
  });

I want to close my Popover, but this code doesn't work correctly.
How can I test popover close case in jest, react-testing-library?


Solution

  • Assuming you have the following simple component with a button that triggers a Modal on click.

    import React, { useState } from 'react'
    import Modal from '@material-ui/core/Modal'
    
    const SimpleModal = () => {
        const [open, setOpen] = useState(false)
    
        const handleOpen = () => {
            setOpen(true)
        }
        const handleClose = () => {
            setOpen(false)
        }
    
        return (
            <div>
                <button type="button" onClick={handleOpen}>
                    Open Modal
                </button>
                <Modal open={open} onClose={handleClose}>
                    <h1>Text in Modal</h1>
                </Modal>
            </div>
        )
    }
    
    export default SimpleModal
    

    You can simulate an Escape key event using fireEvent.keyDown on the modal itself once it's showing, which will close the modal.

    test('should close modal when "Escape" key is pressed', () => {
        render(<SimpleModal />);
        fireEvent.click(screen.getByText('Open Modal'));
        expect(screen.getByText('Text in Modal')).toBeInTheDocument();
        fireEvent.keyDown(screen.getByText('Text in Modal'), {
          key: 'Escape',
          code: 'Escape'
        });
        expect(screen.queryByText('Text in Modal')).not.toBeInTheDocument();
    });