Testing Menu

General setup

Menu supports long press interactions in certain configurations. See the following sections on how to handle these behaviors in your tests.

Test utils

@react-spectrum/test-utils offers common menu interaction testing utilities. Install it with your preferred package manager.

Initialize a User object at the top of your test file, and use it to create a Menu pattern tester in your test cases. The tester has methods that you can call within your test to query for specific subcomponents or simulate common interactions.

// Menu.test.ts
import {render} from '@testing-library/react';
import {User} from '@react-spectrum/test-utils';

let testUtilUser = new User({
  interactionType: 'mouse'
});
// ...

it('Menu can open its submenu via keyboard', async function () {
  // Render your test component/app and initialize the menu tester
  let {getByTestId} = render(
    <MenuTrigger>
      <Button data-testid="test-menutrigger">Menu trigger</Button>
      ...
    </MenuTrigger>
  );
  let menuTester = testUtilUser.createTester('Menu', {root: getByTestId('test-menutrigger'), interactionType: 'keyboard'});

  await menuTester.open();
  expect(menuTester.menu).toBeInTheDocument();
  let submenuTriggers = menuTester.submenuTriggers;
  expect(submenuTriggers).toHaveLength(1);

  let submenuTester = await menuTester.openSubmenu({submenuTrigger: 'Share…'});
  expect(submenuTester.menu).toBeInTheDocument();

  await submenuTester.selectOption({option: submenuTester.options()[0]});
  expect(submenuTester.menu).not.toBeInTheDocument();
  expect(menuTester.menu).not.toBeInTheDocument();
});

API

User

Properties

NameTypeDefault
advanceTimer['advanceTimer']Default:
A function used by the test utils to advance timers during interactions. Required for certain aria patterns (e.g. table).
interactionType['interactionType']Default: mouse
The interaction type (mouse, touch, keyboard) that the test util user will use when interacting with a component. This can be overridden at the aria pattern util level if needed.

Methods

constructor(opts: ): void
createTester<T extends >(patternName: T, opts: <T>): <T>
Creates an aria pattern tester, inheriting the options provided to the original user.

Properties

NameType
submenuTriggersHTMLElement[]
Returns the menu's submenu triggers if any.
sectionsHTMLElement[]
Returns the menu's sections if any.
menuHTMLElementnull
Returns the menu if present.
triggerHTMLElement
Returns the menu's trigger.

Methods

constructor(opts: ): void
setInteractionType(type: ['interactionType']): void
Set the interaction type used by the menu tester.
open(opts: ): Promise<void>
Opens the menu. Defaults to using the interaction type set on the menu tester.
findOption(opts: {
optionIndexOrText: numberstring
}): HTMLElement
Returns a option matching the specified index or text content.
selectOption(opts: ): Promise<void>
Selects the desired menu option. Defaults to using the interaction type set on the menu tester. If necessary, will open the menu dropdown beforehand. The desired option can be targeted via the option's node, the option's text, or the option's index.
openSubmenu(opts: ): Promise<null>
Opens the submenu. Defaults to using the interaction type set on the menu tester. The submenu trigger can be targeted via the trigger's node or the trigger's text.
close(): Promise<void>
Closes the menu.
options(opts: {
element?: HTMLElement
}): HTMLElement[]
Returns the menu's options if present. Can be filtered to a subsection of the menu if provided via element.

Testing FAQ