UNPKG

@vertisanpro/flowbite-react

Version:

Non-Official React components built for Flowbite and Tailwind CSS

125 lines (124 loc) 6.72 kB
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');