/**
* @fileoverview Banner Timing and Initialization Regression Tests
*
* These tests specifically target timing issues that could affect the banner component:
* 1. Double-click requirement (requestAnimationFrame timing fix)
* 2. Race condition in initialization
* 3. USWDS banner toggle button 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('Banner Timing and Initialization Regression Tests', () => {
describe('Single-Click Requirement (Banner Toggle)', () => {
it('should toggle banner content on FIRST click of toggle button', () => {
cy.mount(`
An official website of the United States government
Here's how you know
Official websites use .gov A
.gov website belongs to an official government
organization in the United States.
Secure .gov websites use HTTPS A
lock or https:// means you've
safely connected to the .gov website.
`);
// Wait for component to initialize and USWDS to set up event handlers
cy.wait(500);
// Verify banner button exists
cy.get('.usa-banner__button').should('exist');
// CRITICAL: First click should immediately work
cy.get('.usa-banner__button').click();
// Give USWDS time to toggle content
cy.wait(200);
// Banner content should be visible after FIRST click (not second)
cy.get('.usa-banner__content').should('be.visible');
cy.get('.usa-banner__content').should('not.have.attr', 'hidden');
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'true');
});
it('should work immediately after component initialization', () => {
cy.mount(`
Quick test content
`);
// Minimal wait - component should be ready quickly
cy.wait(100);
// Click immediately after initialization
cy.get('.usa-banner__button').click();
// Should work on first try
cy.wait(200);
cy.get('.usa-banner__content').should('be.visible');
});
it('should toggle correctly on each click (no skipped clicks)', () => {
cy.mount(`
Toggle test content
`);
cy.wait(200);
// Click 1: Should expand
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'true');
// Click 2: Should collapse
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('not.be.visible');
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'false');
// Click 3: Should expand again
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'true');
});
});
describe('Initialization Verification', () => {
it('should initialize USWDS after DOM is ready', () => {
cy.mount(`
Init test content
`);
cy.wait(200);
// After initialization, banner button should have proper attributes
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'false');
cy.get('.usa-banner__button').should('have.attr', 'aria-controls', 'init-test');
cy.get('.usa-banner__content').should('have.attr', 'id', 'init-test');
});
it('should not duplicate event handlers on rapid property changes', () => {
cy.mount(`
Rapid test content
`);
cy.wait(200);
// Rapidly change properties
cy.get('#rapid-test').then(($banner) => {
const banner = $banner[0] as any;
banner.setAttribute('data-test', '1');
banner.setAttribute('data-test', '2');
banner.setAttribute('data-test', '3');
});
cy.wait(100);
// Banner toggle should still work correctly (no duplicate handlers)
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
// Collapse
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('not.be.visible');
// Expand again
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
});
it('should handle pre-expanded state correctly', () => {
cy.mount(`
Pre-expanded content
`);
cy.wait(200);
// Content should be visible initially
cy.get('.usa-banner__content').should('be.visible');
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'true');
// Click should collapse
cy.get('.usa-banner__button').click();
cy.wait(100);
cy.get('.usa-banner__content').should('not.be.visible');
});
});
describe('Accessibility Validation', () => {
it('should have correct ARIA attributes', () => {
cy.mount(`
Accessibility test content
`);
cy.wait(200);
// Button should have proper ARIA attributes
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'false');
cy.get('.usa-banner__button').should('have.attr', 'aria-controls', 'a11y-test');
// Content should be hidden initially
cy.get('.usa-banner__content').should('have.attr', 'hidden');
// Click to expand
cy.get('.usa-banner__button').click();
cy.wait(100);
// ARIA attributes should update
cy.get('.usa-banner__button').should('have.attr', 'aria-expanded', 'true');
cy.get('.usa-banner__content').should('not.have.attr', 'hidden');
});
it('should be keyboard navigable', () => {
cy.mount(`
Keyboard test content
`);
cy.wait(200);
// Focus banner button with keyboard
cy.get('.usa-banner__button').focus();
cy.get('.usa-banner__button').should('have.focus');
// Press Enter to expand
cy.get('.usa-banner__button').type('{enter}');
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
// Press Enter to collapse
cy.get('.usa-banner__button').type('{enter}');
cy.wait(100);
cy.get('.usa-banner__content').should('not.be.visible');
// Press Space to expand
cy.get('.usa-banner__button').type(' ');
cy.wait(100);
cy.get('.usa-banner__content').should('be.visible');
});
});
describe('Content Structure', () => {
it('should maintain proper banner header structure', () => {
cy.mount(`