/** * @fileoverview Character Count Timing and Initialization Regression Tests * * These tests specifically target timing issues that could affect the character count component: * 1. Real-time character counting (input event handler timing) * 2. Status message updates (debounced updates) * 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('Character Count Timing and Initialization Regression Tests', () => { describe('Single-Click Requirement (USWDS Integration)', () => { it('should update character count on FIRST keystroke', () => { cy.mount(` `); cy.wait(500); // Type immediately - should update count on FIRST character cy.get('.usa-character-count__field').type('a'); cy.wait(100); // Character count should update immediately // USWDS creates .usa-character-count__status.usa-hint (visible) and .usa-character-count__sr-status (screen reader only) cy.get('.usa-character-count__status.usa-hint').should('contain', '24 characters left'); }); it('should work immediately after component initialization', () => { cy.mount(` `); // Minimal wait - component should be ready quickly cy.wait(300); // Status message should exist immediately // USWDS creates .usa-character-count__status.usa-hint element dynamically cy.get('.usa-character-count__status.usa-hint').should('exist'); cy.get('.usa-character-count__status.usa-hint').should('contain', '50 characters allowed'); }); it('should handle rapid typing without double-update', () => { cy.mount(` `); cy.wait(500); // Type rapidly - each character should be counted cy.get('.usa-character-count__field').type('hello world'); cy.wait(100); // Should show correct count (11 characters typed, 89 left) cy.get('.usa-character-count__status.usa-hint').should('contain', '89 characters left'); }); }); describe('Character Count-Specific Timing Tests', () => { it('should show status message immediately on mount', () => { cy.mount(` `); cy.wait(500); // Status message should be visible and correct cy.get('.usa-character-count__status.usa-hint').should('be.visible'); cy.get('.usa-character-count__status.usa-hint').should('contain', '30 characters allowed'); }); it('should handle textarea character counting', () => { cy.mount(` `); cy.wait(500); // Type into textarea cy.get('textarea.usa-character-count__field').type('Testing textarea counting'); cy.wait(100); // Should count characters correctly (25 characters typed) cy.get('.usa-character-count__status.usa-hint').should('contain', '125 characters left'); }); it('should update count as user types continuously', () => { cy.mount(` `); cy.wait(500); // Initial state cy.get('.usa-character-count__status.usa-hint').should('contain', '20 characters allowed'); // Type one character cy.get('.usa-character-count__field').type('a'); cy.wait(50); cy.get('.usa-character-count__status.usa-hint').should('contain', '19 characters left'); // Type more characters cy.get('.usa-character-count__field').type('bc'); cy.wait(50); cy.get('.usa-character-count__status.usa-hint').should('contain', '17 characters left'); }); it('should show error state when limit exceeded', () => { cy.mount(` `); cy.wait(500); // Type beyond limit cy.get('.usa-character-count__field').type('This is too long'); cy.wait(100); // Should show error state cy.get('.usa-form-group').should('have.class', 'usa-form-group--error'); cy.get('.usa-character-count__status.usa-hint').should('have.class', 'usa-character-count__status--invalid'); }); it('should handle deleting characters', () => { cy.mount(` `); cy.wait(500); // Type some text cy.get('.usa-character-count__field').type('hello'); cy.wait(100); cy.get('.usa-character-count__status.usa-hint').should('contain', '20 characters left'); // Delete characters cy.get('.usa-character-count__field').type('{backspace}{backspace}'); cy.wait(100); // Should update count correctly (3 characters left, 22 remaining) cy.get('.usa-character-count__status.usa-hint').should('contain', '22 characters left'); }); }); 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 functional cy.get('.usa-character-count__status.usa-hint').should('exist'); cy.get('.usa-character-count__sr-status').should('exist'); // Screen reader status cy.get('.usa-character-count__field').should('exist'); }); it('should not duplicate event handlers on rapid property changes', () => { cy.mount(` `); const characterCount = cy.get('#handler-test'); cy.wait(500); // Rapidly change properties (could trigger initialization multiple times) characterCount.then(($input) => { const input = $input[0] as any; input.disabled = true; input.required = true; input.disabled = false; input.required = false; }); cy.wait(200); // Component should still work correctly (no duplicate handlers) cy.get('.usa-character-count__field').type('test'); cy.wait(100); // Should count correctly (4 characters, 46 left) cy.get('.usa-character-count__status.usa-hint').should('contain', '46 characters left'); }); }); describe('Disabled State', () => { it('should handle disabled state correctly', () => { cy.mount(` `); cy.wait(500); // Input should be disabled cy.get('.usa-character-count__field').should('be.disabled'); }); it('should toggle disabled state dynamically', () => { cy.mount(` `); const characterCount = cy.get('#toggle-disabled-test'); cy.wait(500); // Initially enabled - input should work cy.get('.usa-character-count__field').should('not.be.disabled'); // Disable the character count characterCount.then(($input) => { const input = $input[0] as any; input.disabled = true; }); cy.wait(100); // Should be disabled cy.get('.usa-character-count__field').should('be.disabled'); }); }); describe('Required State', () => { it('should handle required attribute', () => { cy.mount(` `); cy.wait(500); // Input should be required cy.get('.usa-character-count__field').should('have.attr', 'required'); }); }); describe('Max Length Enforcement', () => { it('should respect max-length attribute', () => { cy.mount(` `); cy.wait(500); // Character count element should have data-maxlength attribute // USWDS moves maxlength from input to data attribute on container cy.get('.usa-character-count').should('have.attr', 'data-maxlength', '15'); }); it('should handle dynamic max-length changes', () => { cy.mount(` `); const characterCount = cy.get('#dynamic-maxlength-test'); cy.wait(500); // Change max-length attribute characterCount.then(($input) => { const input = $input[0] as any; input.maxLength = 50; }); cy.wait(100); // Status should update (though this may require re-initialization in practice) cy.get('.usa-character-count__status.usa-hint').should('exist'); }); }); });