/**
* @fileoverview Time Picker Timing and Initialization Regression Tests
*
* These tests specifically target timing issues that could affect the time picker component:
* 1. Double-click requirement (requestAnimationFrame timing fix)
* 2. Race condition in setupEventHandlers
* 3. USWDS initialization 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('Time Picker Timing and Initialization Regression Tests', () => {
describe('Single-Click Requirement (USWDS Integration)', () => {
it('should open time list on FIRST click of input', () => {
cy.mount(`
`);
// Wait for component to initialize and USWDS to transform
cy.wait(500);
// CRITICAL: First click should immediately work
cy.get('.usa-combo-box__input').click();
// Time list should be visible after FIRST click (not second)
cy.get('.usa-combo-box__list').should('be.visible');
});
it('should work immediately after component initialization', () => {
cy.mount(`
`);
// Minimal wait - component should be ready quickly
cy.wait(300);
// Click immediately after initialization
cy.get('.usa-combo-box__input').click();
// Should work on first try
cy.get('.usa-combo-box__list').should('be.visible');
});
it('should toggle correctly on each action (no skipped clicks)', () => {
cy.mount(`
`);
cy.wait(500);
// Click 1: Should open
cy.get('.usa-combo-box__input').click();
cy.wait(100);
cy.get('.usa-combo-box__list').should('be.visible');
// Click 2: Should close (press escape)
cy.get('body').type('{esc}');
cy.wait(100);
cy.get('.usa-combo-box__list').should('not.be.visible');
// Click 3: Should open again
cy.get('.usa-combo-box__input').click();
cy.wait(100);
cy.get('.usa-combo-box__list').should('be.visible');
});
});
describe('Time Picker-Specific Timing Tests', () => {
it('should filter times on first keypress', () => {
cy.mount(`
`);
cy.wait(500);
// Type to filter - should work on FIRST keypress
cy.get('.usa-combo-box__input').type('2');
cy.wait(200);
// Should show filtered results immediately
cy.get('.usa-combo-box__list').should('be.visible');
cy.get('.usa-combo-box__list-option').should('exist');
});
it('should select time on first click', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
cy.get('.usa-combo-box__list').should('be.visible');
// Click a time - should select on FIRST click
cy.get('.usa-combo-box__list-option').first().click();
cy.wait(100);
// Input should have selected value (not empty)
cy.get('.usa-combo-box__input').invoke('val').should('not.be.empty');
cy.get('.usa-combo-box__list').should('not.be.visible');
});
it('should handle keyboard navigation immediately', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
// Use arrow keys - should work immediately
cy.get('.usa-combo-box__input').type('{downarrow}');
cy.wait(50);
// First option should be focused
cy.get('.usa-combo-box__list-option--focused').should('exist');
});
it('should close list on Escape key', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
cy.get('.usa-combo-box__list').should('be.visible');
// Press Escape - should close on FIRST press
cy.get('.usa-combo-box__input').type('{esc}');
cy.wait(100);
cy.get('.usa-combo-box__list').should('not.be.visible');
});
it('should handle time step configuration', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
// Should show times with 60-minute intervals
cy.get('.usa-combo-box__list-option').should('exist');
});
});
describe('USWDS Initialization Timing', () => {
it('should initialize USWDS after DOM is ready', () => {
cy.mount(`
`);
// Wait for initialization
cy.wait(500);
// USWDS-created elements should exist and be clickable
cy.get('.usa-combo-box__input').should('exist');
cy.get('.usa-combo-box__input').should('be.visible');
// Click should work immediately
cy.get('.usa-combo-box__input').click();
cy.get('.usa-combo-box__list').should('be.visible');
});
it('should not duplicate event handlers on rapid property changes', () => {
cy.mount(`
`);
const picker = cy.get('#handler-test');
cy.wait(500);
// Rapidly change properties (could trigger initialization multiple times)
picker.then(($picker) => {
const p = $picker[0] as any;
p.disabled = true;
p.required = true;
p.disabled = false;
p.required = false;
});
cy.wait(200);
// Component should still work correctly (no duplicate handlers)
cy.get('.usa-combo-box__input').click();
cy.wait(50);
cy.get('.usa-combo-box__list').should('be.visible');
cy.get('body').type('{esc}');
cy.wait(50);
cy.get('.usa-combo-box__list').should('not.be.visible');
});
});
describe('Disabled State', () => {
it('should handle disabled state correctly', () => {
cy.mount(`
`);
cy.wait(500);
// Input should be disabled
cy.get('.usa-combo-box__input').should('be.disabled');
// Should not open on click
cy.get('.usa-combo-box__input').click({ force: true });
cy.wait(100);
cy.get('.usa-combo-box__list').should('not.be.visible');
});
it('should toggle disabled state dynamically', () => {
cy.mount(`
`);
const picker = cy.get('#toggle-disabled-test');
cy.wait(500);
// Initially enabled - should work
cy.get('.usa-combo-box__input').click();
cy.wait(100);
cy.get('.usa-combo-box__list').should('be.visible');
// Close list
cy.get('body').type('{esc}');
cy.wait(100);
// Disable the picker
picker.then(($picker) => {
const p = $picker[0] as any;
p.disabled = true;
});
cy.wait(100);
// Should be disabled
cy.get('.usa-combo-box__input').should('be.disabled');
});
});
describe('Min/Max Time Constraints', () => {
it('should handle min time constraint', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
// Should have times starting from min time
cy.get('.usa-combo-box__list-option').should('exist');
});
it('should handle max time constraint', () => {
cy.mount(`
`);
cy.wait(500);
// Open list
cy.get('.usa-combo-box__input').click();
cy.wait(100);
// List should render without errors
cy.get('.usa-combo-box__list-option').should('exist');
});
});
describe('Initial Value', () => {
it('should display initial value immediately', () => {
cy.mount(`
`);
cy.wait(500);
// Input should have initial value
cy.get('.usa-combo-box__input').should('have.value', '2:30pm');
});
it('should update value dynamically', () => {
cy.mount(`
`);
const picker = cy.get('#dynamic-value-test');
cy.wait(500);
// Set value programmatically
picker.then(($picker) => {
const p = $picker[0] as any;
p.value = '10:00';
});
cy.wait(200);
// Input should update
cy.get('.usa-combo-box__input').should('have.value', '10:00am');
});
});
describe('Required State', () => {
it('should handle required attribute', () => {
cy.mount(`
`);
cy.wait(500);
// Input should be required
cy.get('.usa-combo-box__input').should('have.attr', 'required');
});
});
});