veza/apps/web/src/components/ui/focus-trap.test.tsx
senke 37981c2c17 chore(refactor/sumi-migration): commit pending changes — tests, stream server, dist_verification
- apps/web: test updates (Vitest/setup), playbackAnalyticsService, TrackGrid, serviceErrorHandler
- veza-common: logging, metrics, traits, validation, random
- veza-stream-server: audio pipeline, codecs, cache, monitoring, routes
- apps/web/dist_verification: refresh build assets (content-hashed filenames)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-13 19:39:18 +01:00

98 lines
2.5 KiB
TypeScript

import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { FocusTrap } from './focus-trap';
describe('FocusTrap Component', () => {
beforeEach(() => {
// Reset focus before each test
document.body.focus();
});
it('renders children', () => {
render(
<FocusTrap>
<button>Button 1</button>
<button>Button 2</button>
</FocusTrap>,
);
expect(screen.getByText('Button 1')).toBeInTheDocument();
expect(screen.getByText('Button 2')).toBeInTheDocument();
});
it('focuses first element when active', () => {
render(
<FocusTrap active={true}>
<button>Button 1</button>
<button>Button 2</button>
</FocusTrap>,
);
const button1 = screen.getByText('Button 1');
expect(document.activeElement).toBe(button1);
});
it('traps focus with Tab key', () => {
render(
<FocusTrap active={true}>
<button>Button 1</button>
<button>Button 2</button>
</FocusTrap>,
);
const button1 = screen.getByText('Button 1');
const button2 = screen.getByText('Button 2');
// Focus the last element
button2.focus();
expect(document.activeElement).toBe(button2);
// Tab from last element should wrap to first
fireEvent.keyDown(document, { key: 'Tab' });
expect(document.activeElement).toBe(button1);
});
it('traps focus with Shift+Tab key', () => {
render(
<FocusTrap active={true}>
<button>Button 1</button>
<button>Button 2</button>
</FocusTrap>,
);
const button1 = screen.getByText('Button 1');
const button2 = screen.getByText('Button 2');
button1.focus();
fireEvent.keyDown(document, { key: 'Tab', shiftKey: true });
// Should wrap to last button
expect(document.activeElement).toBe(button2);
});
it('calls onEscape when Escape key is pressed', () => {
const mockOnEscape = vi.fn();
render(
<FocusTrap active={true} onEscape={mockOnEscape}>
<button>Button 1</button>
</FocusTrap>,
);
fireEvent.keyDown(document, { key: 'Escape' });
expect(mockOnEscape).toHaveBeenCalled();
});
it('does not trap focus when active is false', () => {
render(
<FocusTrap active={false}>
<button>Button 1</button>
</FocusTrap>,
);
const button1 = screen.getByText('Button 1');
// Focus should not be automatically set
expect(document.activeElement).not.toBe(button1);
});
});