// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import '@testing-library/jest-dom';
import { fireEvent, waitFor } from '@testing-library/dom';
import { act } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { Simulate } from 'react-dom/test-utils';
import PopOver from '../../../../src/components/ui/PopOver';
import PopOverItem from '../../../../src/components/ui/PopOver/PopOverItem';
import PopOverSubMenu from '../../../../src/components/ui/PopOver/PopOverSubMenu';
import lightTheme from '../../../../src/theme/light';
import { renderWithTheme } from '../../../test-helpers';
let mockFunction: any, value: string, label: string;
function click(it: HTMLElement) {
act(() => {
fireEvent.click(it);
});
}
describe('PopOver', () => {
beforeEach(() => {
label = 'test-label';
value = 'test-value';
mockFunction = jest.fn();
});
const popOverButton = (isOpen: boolean) =>
Test Button
;
const testChild = Test Child
;
it('should render a PopOver component in the document', () => {
const component = (
);
const { getByTestId } = renderWithTheme(lightTheme, component);
const element = getByTestId('popover');
expect(element).toBeInTheDocument();
});
it('should render a toggle button when renderButton is passed', () => {
const component = (
);
const { getByRole } = renderWithTheme(lightTheme, component);
const element = getByRole('button');
expect(element).toBeInTheDocument();
});
it('should render the contents of renderButtonWrapper when passed', () => {
const renderFn = () => ;
const component = (
);
const { getByRole } = renderWithTheme(lightTheme, component);
const element = getByRole('button');
expect(element).toBeInTheDocument();
});
it('should render a toggle with an a11yLabel', () => {
const component = (
);
const { getByLabelText } = renderWithTheme(lightTheme, component);
const element = getByLabelText('test-label');
expect(element).toBeInTheDocument();
});
it('should open a menu when clicked', async () => {
const component = (
);
const { getByTestId } = renderWithTheme(lightTheme, component);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = getByTestId('menu');
await waitFor(() => expect(menu).toBeInTheDocument());
});
it('should close the popper when toggle button is clicked', () => {
const component = (
);
const { getByTestId, queryByTestId } = renderWithTheme(
lightTheme,
component
);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = queryByTestId('menu');
click(toggle);
expect(menu).not.toBeInTheDocument();
});
it('should close the popper when an item is selected', () => {
const component = (
Test Item} />
);
const { getByText, getByTestId, queryByTestId } = renderWithTheme(
lightTheme,
component
);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = queryByTestId('menu');
const item = getByText('Test Item');
click(item);
expect(menu).not.toBeInTheDocument();
});
it('should NOT close the popper when an item is selected if closeOnClick is false', () => {
const component = (
Test Item} />
);
const { getByText, getByTestId, queryByTestId } = renderWithTheme(
lightTheme,
component
);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = queryByTestId('menu');
const item = getByText('Test Item');
click(item);
expect(menu).toBeInTheDocument();
});
it('should not close the popper when a submenu item is clicked', async () => {
const component = (
Submenu Item}
/>
);
const { getByText, getByTestId, queryByTestId } = renderWithTheme(
lightTheme,
component
);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = queryByTestId('menu');
const item = getByText('Submenu Item');
click(item);
await waitFor(() => expect(menu).toBeInTheDocument());
});
it('should focus down the menu when tab is pressed', async () => {
const testChildren = [
Option 1} key="1" />,
Option 2}
key="2"
data-testid="option 2"
/>,
];
const component = (
);
const { getByTestId } = renderWithTheme(lightTheme, component);
const toggle = getByTestId('popover-toggle');
click(toggle);
const option2 = getByTestId('option 2');
await userEvent.tab();
await userEvent.tab();
await waitFor(() => expect(option2).toHaveFocus());
});
// TODO: Consider replacing these Simulate methods with
// the 'user' from the 'user-event' library when they are supported (in development).
// https://github.com/testing-library/user-event/issues/354
it('should focus down the menu when down is pressed', async () => {
const testChildren = [
Option 1} key="1" />,
Option 2}
key="2"
data-testid="option 2"
/>,
];
const component = (
);
const { getByTestId } = renderWithTheme(lightTheme, component);
const toggle = getByTestId('popover-toggle');
click(toggle);
const option2 = getByTestId('option 2');
act(() => {
Simulate.keyDown(document.activeElement || document.body, {
key: 'ArrowDown',
keyCode: 40,
which: 40,
}); // key down to Option 1
Simulate.keyDown(document.activeElement || document.body, {
key: 'ArrowDown',
keyCode: 40,
which: 40,
}); // key down to Option 2
});
await waitFor(() => expect(option2).toHaveFocus());
});
it('should focus up the menu when up is pressed', async () => {
const testChildren = [
Option 1}
key="1"
data-testid="option 1"
/>,
Option 2} key="2" />,
];
const component = (
);
const { getByTestId } = renderWithTheme(lightTheme, component);
const toggle = getByTestId('popover-toggle');
click(toggle);
const option1 = getByTestId('option 1');
act(() => {
Simulate.keyDown(document.activeElement || document.body, {
key: 'ArrowDown',
keyCode: 40,
which: 40,
}); // key down to Option 1
Simulate.keyDown(document.activeElement || document.body, {
key: 'ArrowDown',
keyCode: 40,
which: 40,
}); // key down to Option 2
Simulate.keyDown(document.activeElement || document.body, {
key: 'ArrowUp',
keyCode: 38,
which: 38,
}); // key up to Option 1
});
await waitFor(() => expect(option1).toHaveFocus());
});
it('should close the popper when esc is pressed', async () => {
const component = (
);
const { getByTestId, queryByTestId } = renderWithTheme(
lightTheme,
component
);
const toggle = getByTestId('popover-toggle');
click(toggle);
const menu = queryByTestId('menu');
act(() => {
Simulate.keyDown(document.activeElement || document.body, {
key: 'Escape',
keyCode: 27,
which: 27,
});
});
await waitFor(() => expect(menu).not.toBeInTheDocument());
});
});