test(08-01): add failing tests for ThemeToggle component
- Test renders three buttons: Light, Dark, System - Test default state is System when localStorage is empty - Test clicking Dark adds .dark class to documentElement - Test clicking Light removes .dark class from documentElement - Test clicking Dark writes to localStorage key r2b-theme - Test active/inactive aria-pressed state - Test group has aria-label="Theme"
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
// @vitest-environment jsdom
|
||||||
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
|
import userEvent from '@testing-library/user-event';
|
||||||
|
import { ThemeToggle } from './ThemeToggle';
|
||||||
|
|
||||||
|
describe('ThemeToggle', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Reset DOM and localStorage before each test
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders three buttons: Light, Dark, System', () => {
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
expect(screen.getByRole('button', { name: /light/i })).toBeInTheDocument();
|
||||||
|
expect(screen.getByRole('button', { name: /dark/i })).toBeInTheDocument();
|
||||||
|
expect(screen.getByRole('button', { name: /system/i })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('default state is System (aria-pressed="true" on System button) when localStorage is empty', () => {
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
const systemButton = screen.getByRole('button', { name: /system/i });
|
||||||
|
const lightButton = screen.getByRole('button', { name: /light/i });
|
||||||
|
const darkButton = screen.getByRole('button', { name: /dark/i });
|
||||||
|
expect(systemButton).toHaveAttribute('aria-pressed', 'true');
|
||||||
|
expect(lightButton).toHaveAttribute('aria-pressed', 'false');
|
||||||
|
expect(darkButton).toHaveAttribute('aria-pressed', 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clicking Dark adds .dark class to document.documentElement', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
const darkButton = screen.getByRole('button', { name: /dark/i });
|
||||||
|
await user.click(darkButton);
|
||||||
|
expect(document.documentElement.classList.contains('dark')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clicking Light removes .dark class from document.documentElement', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
// Start with dark class applied
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
const lightButton = screen.getByRole('button', { name: /light/i });
|
||||||
|
await user.click(lightButton);
|
||||||
|
expect(document.documentElement.classList.contains('dark')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clicking Dark writes "dark" to localStorage under key "r2b-theme"', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
const darkButton = screen.getByRole('button', { name: /dark/i });
|
||||||
|
await user.click(darkButton);
|
||||||
|
expect(localStorage.getItem('r2b-theme')).toBe('dark');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('active button has aria-pressed="true", others have aria-pressed="false"', async () => {
|
||||||
|
const user = userEvent.setup();
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
const darkButton = screen.getByRole('button', { name: /dark/i });
|
||||||
|
await user.click(darkButton);
|
||||||
|
expect(darkButton).toHaveAttribute('aria-pressed', 'true');
|
||||||
|
expect(screen.getByRole('button', { name: /light/i })).toHaveAttribute('aria-pressed', 'false');
|
||||||
|
expect(screen.getByRole('button', { name: /system/i })).toHaveAttribute('aria-pressed', 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('component group has aria-label="Theme"', () => {
|
||||||
|
render(<ThemeToggle />);
|
||||||
|
expect(screen.getByRole('group', { name: 'Theme' })).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user