123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import type {ComponentProps} from 'react';
- import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
- import DeprecatedDropdownMenu from 'sentry/components/deprecatedDropdownMenu';
- describe('dropdownMenuDeprecated', function () {
- function DeprecatedDropdownImplementation(
- props: Partial<ComponentProps<typeof DeprecatedDropdownMenu>> = {}
- ) {
- return (
- <DeprecatedDropdownMenu {...props}>
- {({getRootProps, getActorProps, getMenuProps, isOpen}) => (
- <span {...getRootProps({})}>
- <button {...getActorProps({})}>Open Dropdown</button>
- {isOpen && (
- <ul {...getMenuProps({})}>
- <li>Dropdown Menu Item 1</li>
- </ul>
- )}
- </span>
- )}
- </DeprecatedDropdownMenu>
- );
- }
- it('renders', function () {
- render(<DeprecatedDropdownImplementation />);
- });
- it('can toggle dropdown menu with actor', async function () {
- render(<DeprecatedDropdownImplementation />);
- await userEvent.click(screen.getByRole('button'));
- expect(screen.getByRole('listbox')).toBeInTheDocument();
- await userEvent.click(screen.getByRole('button'));
- expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
- });
- it('closes dropdown when clicking on anything in menu', async function () {
- render(<DeprecatedDropdownImplementation />);
- await userEvent.click(screen.getByRole('button'));
- await userEvent.click(screen.getByRole('listitem'));
- expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
- });
- it('closes dropdown when clicking outside of menu', async function () {
- render(
- <div data-test-id="outside-element">
- <DeprecatedDropdownImplementation />
- </div>
- );
- await userEvent.click(screen.getByRole('button'));
- await userEvent.click(screen.getByTestId('outside-element'));
- expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
- });
- it('closes dropdown when pressing escape', async function () {
- render(<DeprecatedDropdownImplementation />);
- await userEvent.click(screen.getByRole('button'));
- await userEvent.keyboard('{Escape}');
- expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
- });
- it('ignores "Escape" key if `closeOnEscape` is false', async function () {
- render(<DeprecatedDropdownImplementation closeOnEscape={false} />);
- await userEvent.click(screen.getByRole('button'));
- await userEvent.keyboard('{Escape}');
- expect(screen.getByRole('listbox')).toBeInTheDocument();
- });
- it('keeps dropdown open when clicking on anything in menu with `keepMenuOpen` prop', async function () {
- render(<DeprecatedDropdownImplementation keepMenuOpen />);
- await userEvent.click(screen.getByRole('button'));
- await userEvent.click(screen.getByRole('listitem'));
- expect(screen.getByRole('listbox')).toBeInTheDocument();
- });
- it('render prop getters all extend props and call original onClick handlers', async function () {
- const rootClick = jest.fn();
- const actorClick = jest.fn();
- const menuClick = jest.fn();
- render(
- <DeprecatedDropdownMenu keepMenuOpen>
- {({getRootProps, getActorProps, getMenuProps, isOpen}) => (
- <span {...getRootProps({onClick: rootClick})} data-test-id="root">
- <button {...getActorProps({onClick: actorClick})} data-test-id="actor">
- Open Dropdown
- </button>
- {isOpen && (
- <ul {...getMenuProps({onClick: menuClick})} data-test-id="menu">
- <li>Dropdown Menu Item 1</li>
- </ul>
- )}
- </span>
- )}
- </DeprecatedDropdownMenu>
- );
- expect(screen.queryByRole('listbox')).not.toBeInTheDocument();
- await userEvent.click(screen.getByTestId('root'));
- expect(rootClick).toHaveBeenCalled();
- await userEvent.click(screen.getByTestId('actor'));
- expect(actorClick).toHaveBeenCalled();
- await userEvent.click(screen.getByTestId('menu'));
- expect(menuClick).toHaveBeenCalled();
- expect(screen.queryByRole('listbox')).toBeInTheDocument();
- });
- it('always rendered menus should attach document event listeners only when opened', async function () {
- const addSpy = jest.spyOn(document, 'addEventListener');
- const removeSpy = jest.spyOn(document, 'removeEventListener');
- render(
- <DeprecatedDropdownMenu alwaysRenderMenu>
- {({getRootProps, getActorProps, getMenuProps}) => (
- <span {...getRootProps({className: 'root'})}>
- <button {...getActorProps({className: 'actor'})}>Open Dropdown</button>
- <ul {...getMenuProps({className: 'menu'})}>
- <li>Dropdown Menu Item 1</li>
- </ul>
- </span>
- )}
- </DeprecatedDropdownMenu>
- );
- // Make sure this is only called when menu is open
- expect(addSpy).not.toHaveBeenCalled();
- await userEvent.click(screen.getByRole('button'));
- expect(addSpy).toHaveBeenCalled();
- expect(removeSpy).not.toHaveBeenCalled();
- await userEvent.click(screen.getByRole('button'));
- expect(removeSpy).toHaveBeenCalled();
- addSpy.mockRestore();
- removeSpy.mockRestore();
- });
- it('does not close nested dropdown on actor clicks', async function () {
- render(
- <DeprecatedDropdownMenu isNestedDropdown>
- {({getRootProps, getActorProps, getMenuProps}) => (
- <span {...getRootProps({})}>
- <button {...getActorProps({})}>Open Dropdown</button>
- <ul {...getMenuProps({})}>
- <li data-test-id="menu-item">Dropdown Menu Item 1</li>
- </ul>
- </span>
- )}
- </DeprecatedDropdownMenu>
- );
- await userEvent.hover(screen.getByRole('button'));
- expect(screen.getByTestId('menu-item')).toBeInTheDocument();
- await userEvent.click(screen.getByRole('button'));
- // Should still be visible.
- expect(screen.getByTestId('menu-item')).toBeInTheDocument();
- });
- });
|