/** * @fileoverview Header Timing and Initialization Regression Tests * * These tests specifically target timing issues that could affect the header component: * 1. Double-click requirement (requestAnimationFrame timing fix) * 2. Race condition in initialization * 3. USWDS mobile menu toggle timing * * These tests run in a real browser with actual USWDS JavaScript, catching issues * that unit tests in jsdom cannot detect. */ import './index.ts'; describe('Header Timing and Initialization Regression Tests', () => { describe('Single-Click Requirement (Mobile Menu Toggle)', () => { it('should toggle mobile menu on FIRST click of menu button', () => { cy.mount(`
`); // Wait for component to initialize and USWDS to set up event handlers cy.wait(500); // Verify menu button exists cy.get('.usa-menu-btn').should('exist'); // CRITICAL: First click should immediately work cy.get('.usa-menu-btn').click(); // Give USWDS time to toggle navigation cy.wait(200); // Navigation should be visible after FIRST click (not second) cy.get('.usa-nav').should('be.visible'); cy.get('.usa-nav').should('have.attr', 'aria-hidden', 'false'); }); it('should work immediately after component initialization', () => { cy.mount(`
`); // Minimal wait - component should be ready quickly cy.wait(100); // Click immediately after initialization cy.get('.usa-menu-btn').click(); // Should work on first try cy.wait(200); cy.get('.usa-nav').should('be.visible'); }); it('should toggle correctly on each click (no skipped clicks)', () => { cy.mount(`
`); cy.wait(200); // Click 1: Should open cy.get('.usa-menu-btn').click(); cy.wait(100); cy.get('.usa-nav').should('be.visible'); // Click 2: Close button should work cy.get('.usa-nav__close').click(); cy.wait(100); cy.get('.usa-nav').should('not.be.visible'); // Click 3: Should open again cy.get('.usa-menu-btn').click(); cy.wait(100); cy.get('.usa-nav').should('be.visible'); }); }); describe('Initialization Verification', () => { it('should initialize USWDS after DOM is ready', () => { cy.mount(`
`); cy.wait(200); // After initialization, menu button should have proper attributes cy.get('.usa-menu-btn').should('have.attr', 'aria-controls'); cy.get('.usa-menu-btn').should('have.attr', 'aria-expanded'); }); it('should not duplicate event handlers on rapid property changes', () => { cy.mount(`
`); cy.wait(200); // Rapidly change properties cy.get('#rapid-test').then(($header) => { const header = $header[0] as any; header.setAttribute('data-test', '1'); header.setAttribute('data-test', '2'); header.setAttribute('data-test', '3'); }); cy.wait(100); // Menu should still work correctly (no duplicate handlers) cy.get('.usa-menu-btn').click(); cy.wait(100); cy.get('.usa-nav').should('be.visible'); // Close should work cy.get('.usa-nav__close').click(); cy.wait(100); cy.get('.usa-nav').should('not.be.visible'); // Open should work again cy.get('.usa-menu-btn').click(); cy.wait(100); cy.get('.usa-nav').should('be.visible'); }); }); describe('Accessibility Validation', () => { it('should have correct ARIA attributes', () => { cy.mount(`
`); cy.wait(200); // Menu button should have proper ARIA attributes cy.get('.usa-menu-btn').should('have.attr', 'aria-controls'); cy.get('.usa-menu-btn').should('have.attr', 'aria-expanded', 'false'); // Navigation should have aria-hidden cy.get('.usa-nav').should('have.attr', 'aria-hidden', 'true'); // Click to open cy.get('.usa-menu-btn').click(); cy.wait(100); // ARIA attributes should update cy.get('.usa-menu-btn').should('have.attr', 'aria-expanded', 'true'); cy.get('.usa-nav').should('have.attr', 'aria-hidden', 'false'); }); it('should be keyboard navigable', () => { cy.mount(`
`); cy.wait(200); // Focus menu button with keyboard cy.get('.usa-menu-btn').focus(); cy.get('.usa-menu-btn').should('have.focus'); // Press Enter to open cy.get('.usa-menu-btn').type('{enter}'); cy.wait(100); cy.get('.usa-nav').should('be.visible'); // Focus close button cy.get('.usa-nav__close').focus(); cy.get('.usa-nav__close').should('have.focus'); // Press Enter to close cy.get('.usa-nav__close').type('{enter}'); cy.wait(100); cy.get('.usa-nav').should('not.be.visible'); }); }); describe('Responsive Behavior', () => { it('should handle viewport resize correctly', () => { cy.mount(`
`); cy.wait(200); // Test mobile viewport cy.viewport(375, 667); cy.wait(100); // Menu button should be functional on mobile cy.get('.usa-menu-btn').click(); cy.wait(100); cy.get('.usa-nav').should('be.visible'); // Test desktop viewport cy.viewport(1280, 720); cy.wait(100); // Navigation state should persist or reset appropriately cy.get('.usa-navbar').should('exist'); }); }); });