@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
150 lines (149 loc) • 7.36 kB
JavaScript
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');