import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { getScrollbarWidth } from '../scrollbar-width.js'; import { selectOrMatches } from '../select-or-matches.js'; import { FocusTrap } from '../focus-trap.js'; describe('USWDS Utilities', () => { describe('getScrollbarWidth', () => { it('should return scrollbar width as string with px unit', () => { const width = getScrollbarWidth(); expect(width).toMatch(/^\d+px$/); }); it('should return consistent width on multiple calls', () => { const width1 = getScrollbarWidth(); const width2 = getScrollbarWidth(); expect(width1).toBe(width2); }); }); describe('selectOrMatches', () => { let container: HTMLElement; beforeEach(() => { container = document.createElement('div'); container.innerHTML = ` Link `; document.body.appendChild(container); }); afterEach(() => { container.remove(); }); it('should select elements matching selector', () => { const buttons = selectOrMatches('.usa-button', container); expect(buttons).toHaveLength(2); }); it('should include context element if it matches selector', () => { const div = document.createElement('div'); div.className = 'usa-button'; div.innerHTML = 'Inner'; document.body.appendChild(div); const elements = selectOrMatches('.usa-button', div); expect(elements).toHaveLength(1); // Just the div itself (no inner .usa-button) expect(elements[0]).toBe(div); div.remove(); }); it('should return empty array for non-matching selector', () => { const elements = selectOrMatches('.nonexistent', container); expect(elements).toHaveLength(0); }); }); describe('FocusTrap', () => { let container: HTMLElement; beforeEach(() => { container = document.createElement('div'); container.innerHTML = ` `; document.body.appendChild(container); }); afterEach(() => { container.remove(); }); it('should create focus trap controller', () => { const trap = FocusTrap(container); expect(trap).toHaveProperty('on'); expect(trap).toHaveProperty('off'); expect(trap).toHaveProperty('update'); }); it('should focus first element on activation', () => { const trap = FocusTrap(container); trap.on(); const firstButton = container.querySelector('#first') as HTMLElement; expect(document.activeElement).toBe(firstButton); trap.off(); }); it('should handle escape key when binding provided', () => { let escapeCalled = false; const trap = FocusTrap(container, { Escape: () => { escapeCalled = true; }, }); trap.on(); // Simulate escape key const event = new KeyboardEvent('keydown', { key: 'Escape' }); document.dispatchEvent(event); expect(escapeCalled).toBe(true); trap.off(); }); it('should update state based on parameter', () => { const trap = FocusTrap(container); trap.update(true); const firstButton = container.querySelector('#first') as HTMLElement; expect(document.activeElement).toBe(firstButton); trap.update(false); // Focus trap deactivated }); }); });