score:1

I use @testing-library/user-event to trigger an esc press.

import {
  render,
  screen,
  waitFor,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';

test('should open and close the menu', async () => {
  render(<UserMenu />);

  // Click to open
  userEvent.click(
    // Note that grabbing by test id is frowned upon if there are other ways to grab it https://testing-library.com/docs/queries/about/#priority
    screen.getByTestId('menu-toggle')
  );

  // Wait for dialog to open
  await waitFor(() => expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: true }), {}));

  // Press `esc` to close
  userEvent.keyboard('{esc}');

  // Wait for dialog to close
  await waitFor(() => expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: false }), {}));
});

score:6

You can trigger the close by clicking on the backdrop generated by the Menu. The easiest way I found to do that was to select the backdrop via the getByRole('presentation') method of @testing-library.

Test Code:

it('should open and close the menu', () => {
  const { getByTestId, getByRole } = render(<UserMenu />);

  fireEvent.click(getByTestId('menu-toggle'));

  // Get the backdrop, then get the firstChild because this is where the event listener is attached
  fireEvent.click(getByRole('presentation').firstChild));

  expect(MockMenu).toHaveBeenLastCalledWith(expect.objectContaining({ open: false }), {});
});

Related Query

More Query from same tag