GlassSwitch Tests
The GlassSwitch component has a comprehensive test suite that covers rendering, state management, accessibility, styling, and component props.
Test file location
src/components/GlassSwitch.test.jsx
Running the tests
# Run all tests
npm test
# Run only GlassSwitch tests
npm test -- GlassSwitch.test.jsx
# Run tests in watch mode
npm test -- --watch GlassSwitch.test.jsx
Test organization
1. Basic rendering
- Renders a switch button with the correct role
2. Checked state management
- Sets
aria-checkedto "true" whenisOn={true} - Sets
aria-checkedto "false" whenisOn={false}
3. User interaction
- Calls
onChangecallback when clicked - Is keyboard accessible (focusable and responds to Enter key)
4. CSS class application
- Applies correct CSS classes when checked (includes
checkedclass) - Does not apply checked class when unchecked
5. Thumb content
- Renders custom
thumbContentwhen provided - Renders fallback thumb content
- Off styling: when
thumbContentis not provided and isOff - On styling: when
thumbContentis not provided and isOn
- Off styling: when
6. Component props
- Can be disabled via
disabledprop - Sets correct
aria-labelfor accessibility
Mocking strategy
- Tooltip component: Mocked as a simple wrapper that renders children
- CSS modules: Mocked to verify class name application and styling logic
- userEvent: Used from
@testing-library/user-eventfor realistic user interactions
Example test snippets
Testing checked state
it('sets aria-checked to true when checked', () => {
render(<GlassSwitch isOn={true} onChange={() => {}} ariaLabel="Toggle" />);
expect(screen.getByRole('switch')).toHaveAttribute('aria-checked', 'true');
});
Testing user interaction
it('calls onChange when clicked', async () => {
const user = userEvent.setup();
const onChange = vi.fn();
render(<GlassSwitch isOn={false} onChange={onChange} ariaLabel="Toggle" />);
await user.click(screen.getByRole('switch'));
expect(onChange).toHaveBeenCalledOnce();
});
Testing keyboard accessibility
it('is keyboard accessible', async () => {
const user = userEvent.setup();
const onChange = vi.fn();
render(<GlassSwitch isOn={false} onChange={onChange} ariaLabel="Toggle" />);
const button = screen.getByRole('switch');
button.focus();
expect(button).toHaveFocus();
await user.keyboard('{Enter}');
expect(onChange).toHaveBeenCalled();
});
Testing CSS classes
it('applies correct CSS classes when checked', () => {
render(<GlassSwitch isOn={true} onChange={() => {}} ariaLabel="Toggle" />);
const switchButton = screen.getByRole('switch');
expect(switchButton).toHaveClass('mocked-switch-class');
expect(switchButton).toHaveClass('mocked-checked-class');
});
Testing custom thumb content
it('renders with thumbContent when provided', () => {
const thumbContent = <span data-testid="custom-thumb">Custom</span>;
render(<GlassSwitch isOn={false} onChange={() => {}} ariaLabel="Toggle" thumbContent={thumbContent} />);
expect(screen.getByTestId('custom-thumb')).toBeInTheDocument();
});
Testing disabled state
it('can be disabled', () => {
const onChange = vi.fn();
render(<GlassSwitch isOn={false} onChange={onChange} ariaLabel="Toggle" disabled={true} />);
const switchButton = screen.getByRole('switch');
expect(switchButton).toBeDisabled();
});
Testing aria-label
it('sets correct aria-label', () => {
render(<GlassSwitch isOn={false} onChange={() => {}} ariaLabel="My Custom Label" />);
expect(screen.getByLabelText('My Custom Label')).toBeInTheDocument();
});
Test utilities
- Vitest - Test framework with mocking capabilities
- @testing-library/react - Component rendering and querying
- @testing-library/user-event - User interaction simulation
Test coverage areas
The test suite ensures:
- Accessibility: ARIA attributes, keyboard navigation, labels
- Functionality: Click handlers, state management
- Styling: CSS class application based on props
- Props: All component props work correctly
- Edge cases: Fallback content, disabled state