@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
125 lines (124 loc) • 6.72 kB
JavaScript
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { describe, expect, it } from 'vitest';
import { Dropdown } from './Dropdown';
describe('Components / Dropdown', () => {
describe('A11y', async () => {
it('should use `role="menu"` in menu container', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
await act(() => user.click(button()));
expect(screen.getByRole('menu')).toBe(dropdown());
});
it('should use `role="menuitem"` in dropdown items', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
await act(() => user.click(button()));
expect(screen.getAllByRole('menuitem')).toHaveLength(4);
});
it('should not open when `disabled={true}`', async () => {
const user = userEvent.setup();
const { rerender } = render(React.createElement(TestDropdown, { disabled: true }));
expect(button()).toBeDisabled();
await act(() => user.click(button()));
expect(dropdown()).not.toBeInTheDocument();
rerender(React.createElement(TestDropdown, { disabled: true, trigger: "hover" }));
await act(() => user.hover(button()));
expect(dropdown()).not.toBeInTheDocument();
});
});
describe('Keyboard interactions', () => {
it('should collapse if expanded when `Space` is pressed', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
expect(dropdown()).not.toBeInTheDocument();
await act(() => user.click(button()));
expect(dropdown()).toBeInTheDocument();
});
it('should expand if collapsed when `Space` is pressed', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
await act(() => user.click(button()));
await act(() => user.click(button()));
expect(dropdown()).not.toBeInTheDocument();
});
});
describe('Mouse interactions', () => {
it('should collapse if item is clicked', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
await act(() => user.click(button()));
await act(() => userEvent.click(dropdownItem()));
expect(dropdown()).not.toBeInTheDocument();
});
it('should collapse if CustomTriggerItem is clicked', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, { renderTrigger: () => React.createElement("button", { type: "button" }) }));
await act(() => user.click(screen.getByRole('button')));
await act(() => userEvent.click(dropdownItem()));
expect(dropdown()).not.toBeInTheDocument();
});
it('should always collapse when item is clicked', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, null));
await act(() => user.click(button()));
await act(() => userEvent.click(dropdownItem()));
expect(dropdown()).not.toBeInTheDocument();
await act(() => user.click(button()));
await act(() => userEvent.click(dropdownItem()));
expect(dropdown()).not.toBeInTheDocument();
});
it('should not collapse in case item is clicked if dismissOnClick = false', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, { dismissOnClick: false }));
expect(dropdown()).not.toBeInTheDocument();
await act(() => user.click(button()));
expect(dropdown()).toBeInTheDocument();
await act(() => userEvent.click(dropdownItem()));
expect(dropdown()).toBeInTheDocument();
});
it('should open on hover when `trigger="hover"`', async () => {
const user = userEvent.setup();
render(React.createElement(TestDropdown, { trigger: "hover" }));
expect(dropdown()).not.toBeInTheDocument();
await act(() => user.hover(button()));
expect(dropdown()).toBeInTheDocument();
});
});
describe('Type of button', async () => {
it('should be of type `button`', async () => {
render(React.createElement(TestDropdown, null));
expect(button()).toHaveAttribute('type', 'button');
});
it('should be of type `button` with inline', async () => {
render(React.createElement(TestDropdown, { inline: true }));
expect(button()).toHaveAttribute('type', 'button');
});
});
describe('Dropdown item render', async () => {
it('should override Dropdownn.Item base component when using `as` prop', async () => {
const user = userEvent.setup();
const CustomBaseItem = ({ children }) => {
return React.createElement("a", { href: "#" }, children);
};
render(React.createElement(Dropdown, { label: "Dropdown button", placement: "right" },
React.createElement(Dropdown.Item, { as: CustomBaseItem }, "Settings")));
await act(() => user.click(button()));
const item = screen.getByText('Settings');
expect(screen.getByRole('link')).toBe(item);
});
});
});
const TestDropdown = ({ dismissOnClick = true, inline = false, disabled, trigger, renderTrigger, }) => (React.createElement(Dropdown, { label: "Dropdown button", placement: "right", dismissOnClick: dismissOnClick, inline: inline, trigger: trigger, disabled: disabled, renderTrigger: renderTrigger },
React.createElement(Dropdown.Header, null,
React.createElement("span", { className: "block text-sm" }, "Bonnie Green"),
React.createElement("span", { className: "block truncate text-sm font-medium" }, "name@flowbite.com")),
React.createElement(Dropdown.Item, null, "Dashboard"),
React.createElement(Dropdown.Item, null, "Settings"),
React.createElement(Dropdown.Item, null, "Earnings"),
React.createElement(Dropdown.Divider, null),
React.createElement(Dropdown.Item, null, "Sign out")));
const button = () => screen.getByRole('button', { name: /Dropdown button/i });
const dropdown = () => screen.queryByTestId('flowbite-dropdown');
const dropdownItem = () => screen.getByText('Dashboard');