UNPKG

@vertisanpro/flowbite-react

Version:

Non-Official React components built for Flowbite and Tailwind CSS

150 lines (149 loc) 7.36 kB
import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React, { useState } from 'react'; import { describe, expect, it, vi } from 'vitest'; import { Flowbite } from '../Flowbite'; import { TextInput } from '../TextInput'; import { ToggleSwitch } from './ToggleSwitch'; describe('Components / Toggle switch', () => { describe('A11y', () => { it('should have `role="switch"` by default', () => { render(React.createElement(ToggleSwitch, { checked: false, label: "Enable", onChange: console.log })); expect(toggleSwitch()).toBeInTheDocument(); }); it('should have an accessible name', () => { render(React.createElement(ToggleSwitch, { checked: false, label: "Enable notifications", name: "notifications", onChange: console.log })); expect(toggleSwitch()).toHaveAccessibleName('Enable notifications'); }); }); describe('Keyboard interaction', () => { it("shouldn't toggle when `Enter` is pressed", async () => { const user = userEvent.setup(); const handleChange = vi.fn(); render(React.createElement(ToggleSwitch, { checked: false, label: "Enable notifications", name: "notifications", onChange: handleChange })); await user.tab(); expect(toggleSwitch()).toHaveFocus(); await user.keyboard('[Enter]'); expect(handleChange).not.toHaveBeenCalled(); }); it("shouldn't submit surrounding form when `Enter` is pressed", async () => { const handleSubmit = vi.fn(); const user = userEvent.setup(); render(React.createElement("form", { onSubmit: (event) => { event.preventDefault(); handleSubmit(); } }, React.createElement(ToggleSwitch, { checked: false, label: "Enable notifications", name: "notifications", onChange: console.log }))); await user.tab(); expect(toggleSwitch()).toHaveFocus(); await user.keyboard('[Enter]'); expect(handleSubmit).not.toHaveBeenCalled(); }); it('should toggle when `Space` is pressed', async () => { const handleChange = vi.fn(); const user = userEvent.setup(); const TestToggleSwitch = () => { const [state, setState] = useState(false); return (React.createElement(ToggleSwitch, { checked: state, label: "Enable notifications", name: "notifications", onChange: (value) => { setState(value); handleChange(value); } })); }; render(React.createElement(TestToggleSwitch, null)); await user.tab(); expect(toggleSwitch()).toHaveFocus(); await user.keyboard('[Space]'); expect(toggleSwitch()).toHaveAttribute('aria-checked', 'true'); await user.keyboard('[Space]'); expect(toggleSwitch()).toHaveAttribute('aria-checked', 'false'); }); it('should focus when `Tab` is pressed', async () => { const user = userEvent.setup(); render(React.createElement(ToggleSwitch, { checked: false, label: "Enable notifications", name: "notifications", onChange: console.log })); await user.tab(); expect(toggleSwitch()).toHaveFocus(); }); it('should allow the user to `Tab` away', async () => { const user = userEvent.setup(); render(React.createElement("form", null, React.createElement(ToggleSwitch, { checked: false, label: "Enable notifications", name: "notifications", onChange: console.log }), React.createElement(TextInput, { type: "text" }))); await user.tab(); await user.tab(); expect(toggleSwitch()).not.toHaveFocus(); expect(screen.getByRole('textbox')).toHaveFocus(); }); }); describe('Props', () => { it('should allow HTML attributes for `<button>`s', () => { render(React.createElement(ToggleSwitch, { checked: false, label: "Enable", onChange: console.log, type: "submit" })); expect(toggleSwitch()).toHaveAttribute('type', 'submit'); }); }); describe('Theme', () => { it('should use `base` classes', () => { const theme = { toggleSwitch: { root: { base: 'text-cyan-100', }, }, }; render(React.createElement(Flowbite, { theme: { theme } }, React.createElement(ToggleSwitch, { checked: false, label: "Enable", onChange: console.log, type: "submit" }))); expect(toggleSwitch()).toHaveClass('text-cyan-100'); }); it('should use `active` classes', () => { const theme = { toggleSwitch: { root: { active: { off: 'text-cyan-200', on: 'text-cyan-300', }, }, }, }; render(React.createElement(Flowbite, { theme: { theme } }, React.createElement(ToggleSwitch, { checked: false, label: "Enable", onChange: console.log, type: "submit" }), React.createElement(ToggleSwitch, { disabled: true, checked: false, label: "Enable", onChange: console.log, type: "submit" }))); const activeToggleSwitch = toggleSwitches()[0]; const disabledToggleSwitch = toggleSwitches()[1]; expect(activeToggleSwitch).toHaveClass('text-cyan-300'); expect(disabledToggleSwitch).toHaveClass('text-cyan-200'); }); it('should use `label` classes', () => { const theme = { toggleSwitch: { root: { label: 'test-label', }, }, }; render(React.createElement(Flowbite, { theme: { theme } }, React.createElement(ToggleSwitch, { checked: false, label: "Enable", onChange: console.log, type: "submit" }))); expect(label()).toHaveClass('test-label'); }); it('should use `toggle` classes', () => { const theme = { toggleSwitch: { toggle: { base: 'h-6 w-11', checked: { color: { blue: 'bg-pink-700', }, }, }, }, }; render(React.createElement(Flowbite, { theme: { theme } }, React.createElement(ToggleSwitch, { checked: true, label: "Enable", onChange: console.log, type: "submit" }))); expect(toggle()).toHaveClass('h-6 w-11 bg-pink-700'); }); }); }); const toggleSwitch = () => screen.getByRole('switch'); const toggleSwitches = () => screen.getAllByRole('switch'); const label = () => screen.getByTestId('flowbite-toggleswitch-label'); const toggle = () => screen.getByTestId('flowbite-toggleswitch-toggle');