`);
cy.get('input')
.should('have.attr', 'aria-labelledby', 'input-label')
.should('have.attr', 'aria-describedby', 'input-hint');
});
it('should work in form submission', () => {
cy.mount(`
`);
cy.window().then((win) => {
const form = win.document.getElementById('test-form') as HTMLFormElement;
const submitSpy = cy.stub();
form.addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(form);
submitSpy(formData.get('user-email'));
});
cy.get('button[type="submit"]').click();
cy.then(() => {
expect(submitSpy).to.have.been.calledWith('user@agency.gov');
});
});
});
it('should handle focus and blur events', () => {
cy.mount(`
`);
cy.window().then((win) => {
const input = win.document.getElementById('test-input') as any;
const focusSpy = cy.stub();
const blurSpy = cy.stub();
input.addEventListener('focus', focusSpy);
input.addEventListener('blur', blurSpy);
cy.get('input').focus();
cy.get('input').blur();
cy.then(() => {
expect(focusSpy).to.have.been.called;
expect(blurSpy).to.have.been.called;
});
});
});
it('should handle validation on blur', () => {
cy.mount(`
`);
// Enter invalid email and blur
cy.get('input').type('invalid-email').blur();
cy.get('input').should('have.attr', 'aria-invalid', 'true');
// Enter valid email and blur
cy.get('input').clear().type('valid@example.gov').blur();
cy.get('input').should('not.have.attr', 'aria-invalid', 'true');
});
it('should be accessible', () => {
cy.mount(`
`);
cy.injectAxe();
cy.checkAccessibility();
});
it('should handle character counting', () => {
cy.mount(`
`);
cy.get('input').type('This is a test message');
cy.get('.usa-character-count').should('contain', '22 characters of 50 used');
});
it('should handle custom CSS classes', () => {
cy.mount(`
`);
cy.get('usa-text-input').should('have.class', 'custom-input-class');
cy.get('input').should('have.class', 'usa-input');
});
it('should handle copy and paste operations', () => {
cy.mount(`
`);
// Type initial text
cy.get('input').type('Initial text');
// Select all and copy would work in real browser
cy.get('input').select(); // Select all text
// Clear and type new text (simulating paste)
cy.get('input').clear().type('Pasted content');
cy.get('input').should('have.value', 'Pasted content');
});
// Responsive Layout Tests
describe('Mobile Responsive Behavior', () => {
beforeEach(() => {
cy.viewport(375, 667); // iPhone SE
});
it('should display properly on mobile with touch targets', () => {
cy.mount(`
`);
// Input should be at least 44px high for touch targets
cy.get('input')
.should('be.visible')
.and(($input) => {
const height = $input.outerHeight();
expect(height).to.be.at.least(44);
});
});
it('should handle mobile form layout stacking', () => {
cy.mount(`
`);
// Form should stack vertically on mobile
cy.get('.usa-form-group').should('have.length', 3);
cy.get('.usa-form-group').each(($group) => {
cy.wrap($group)
.should('have.css', 'width')
.and('match', /375px|100%/);
});
});
it('should handle touch interactions properly', () => {
cy.mount(`
`);
// Touch events should work on mobile
cy.get('input').trigger('touchstart').trigger('touchend').should('be.focused');
// Virtual keyboard should be appropriate for input type
cy.get('input').should('have.attr', 'type', 'tel');
});
it('should handle mobile error states', () => {
cy.mount(`
`);
cy.get('.usa-error-message').should('be.visible');
cy.get('input').should('have.class', 'usa-input--error');
// Error message should be readable on mobile
cy.get('.usa-error-message').should('have.css', 'font-size');
});
it('should handle mobile success states', () => {
cy.mount(`
`);
cy.get('input').should('have.class', 'usa-input--success');
});
it('should handle character count display on mobile', () => {
cy.mount(`
`);
const testText = 'This is mobile content for testing';
cy.get('input').type(testText);
cy.get('.usa-character-count')
.should('be.visible')
.should('contain', `${testText.length} characters of 50 used`);
});
it('should handle different mobile input types', () => {
const mobileInputTypes = [
{ type: 'tel', placeholder: '(555) 123-4567' },
{ type: 'email', placeholder: 'user@agency.gov' },
{ type: 'url', placeholder: 'https://example.gov' },
{ type: 'search', placeholder: 'Search...' },
];
mobileInputTypes.forEach(({ type, placeholder }) => {
cy.mount(`
`);
cy.get('input')
.should('have.attr', 'type', type)
.should('have.attr', 'placeholder', placeholder);
// Test virtual keyboard activation
cy.get('input').focus().should('be.focused');
});
});
});
describe('Tablet Responsive Behavior', () => {
beforeEach(() => {
cy.viewport(768, 1024); // iPad
});
it('should display form in two-column layout on tablet', () => {
cy.mount(`
`);
// Check grid layout on tablet
cy.get('.tablet\\:grid-col-6').should('have.length', 4);
cy.get('.tablet\\:grid-col-6').each(($col) => {
cy.wrap($col).should('have.css', 'width').and('not.equal', '768px');
});
});
it('should handle tablet touch and hover states', () => {
cy.mount(`
`);
// Should work with both touch and mouse
cy.get('input').trigger('touchstart').trigger('touchend').should('be.focused');
cy.get('input').trigger('mouseover').should('have.focus');
});
it('should handle tablet large size variant', () => {
cy.mount(`
`);
cy.get('input').should('have.class', 'usa-input--large');
});
it('should handle tablet form with validation', () => {
cy.mount(`
`);
cy.get('input[name="password"]').type('password123');
cy.get('input[name="confirmPassword"]').type('password123');
cy.get('input[name="password"]').should('have.value', 'password123');
cy.get('input[name="confirmPassword"]').should('have.value', 'password123');
});
});
describe('Desktop Responsive Behavior', () => {
beforeEach(() => {
cy.viewport(1200, 800); // Desktop
});
it('should display full desktop form layout', () => {
cy.mount(`
`);
// Check three-column layout on desktop
cy.get('.desktop\\:grid-col-4').should('have.length', 3);
cy.get('.desktop\\:grid-col-6').should('have.length', 2);
});
it('should handle keyboard navigation efficiently on desktop', () => {
cy.mount(`
`);
// Should have proper four-column layout
cy.get('.desktop\\:grid-col-3').should('have.length', 4);
// Container should be properly centered
cy.get('.grid-container').should('have.css', 'max-width');
// Inputs should have adequate width on large screens
cy.get('input').each(($input) => {
cy.wrap($input).then(($el) => {
const width = $el.outerWidth();
expect(width).to.be.greaterThan(200);
});
});
});
it('should handle large desktop forms with mixed input types', () => {
cy.mount(`
`);
// Test different input types work properly
cy.get('input[type="search"]').should('have.class', 'usa-input--large');
cy.get('input[type="url"]').type('https://agency.gov');
cy.get('input[type="password"]').type('securePassword123');
cy.get('input[type="url"]').should('have.value', 'https://agency.gov');
cy.get('input[type="password"]').should('have.value', 'securePassword123');
});
});
describe('Responsive Edge Cases', () => {
it('should handle viewport transitions smoothly', () => {
cy.mount(`
`);
const transitionText = 'This text tests smooth transitions';
// Test mobile to tablet transition
cy.viewport(375, 667);
cy.get('input').type(transitionText).should('be.visible');
cy.viewport(768, 1024);
cy.get('input').should('be.visible').should('have.value', transitionText);
cy.viewport(1200, 800);
cy.get('input').should('be.visible').should('have.value', transitionText);
});
it('should handle long placeholder text at different screen sizes', () => {
const longPlaceholder =
'This is a very long placeholder text that might cause layout issues on smaller screens';
cy.mount(`
`);
// Test at different viewports
const viewports = [
[320, 568], // Small mobile
[768, 1024], // Tablet
[1200, 800], // Desktop
];
viewports.forEach(([width, height]) => {
cy.viewport(width, height);
cy.get('input').should('be.visible');
// Should not cause horizontal overflow
cy.get('input').then(($input) => {
expect($input[0].scrollWidth).to.be.at.most($input[0].clientWidth + 5);
});
});
});
it('should handle dynamic value updates at different screen sizes', () => {
cy.mount(`
`);
const scenarios = [
{ viewport: [375, 667], value: 'Mobile input' },
{ viewport: [768, 1024], value: 'Tablet input with more content' },
{
viewport: [1200, 800],
value: 'Desktop input with even more detailed content that fits well on larger screens',
},
];
scenarios.forEach(({ viewport, value }) => {
cy.viewport(viewport[0], viewport[1]);
cy.get('input').clear().type(value);
cy.get('input').should('have.value', value);
});
});
it('should maintain accessibility at all screen sizes', () => {
cy.mount(`
This input should be accessible at all screen sizes
`);
const viewports = [
[375, 667], // Mobile
[768, 1024], // Tablet
[1200, 800], // Desktop
];
viewports.forEach(([width, height]) => {
cy.viewport(width, height);
cy.injectAxe();
cy.checkAccessibility();
// Check focus indicators work at all sizes
cy.get('input')
.focus()
.should('have.focus')
.should('have.css', 'outline-width')
.and('not.equal', '0px');
});
});
it('should handle form validation at different screen sizes', () => {
cy.mount(`
`);
const scenarios = [
{ viewport: [375, 667], input: 'invalid-email' },
{ viewport: [768, 1024], input: 'user@agency.gov' },
{ viewport: [1200, 800], input: 'another.user@department.gov' },
];
scenarios.forEach(({ viewport, input }) => {
cy.viewport(viewport[0], viewport[1]);
cy.get('input').clear().type(input);
// Check validity
if (input.includes('@') && input.includes('.')) {
cy.get('input').should('satisfy', ($el) => {
return $el[0].checkValidity();
});
}
});
});
it('should handle copy-paste operations at different screen sizes', () => {
cy.mount(`
`);
const pasteContent =
'This is content that was copied from another source and pasted into the input field';
const viewports = [
[375, 667], // Mobile
[768, 1024], // Tablet
[1200, 800], // Desktop
];
viewports.forEach(([width, height]) => {
cy.viewport(width, height);
cy.get('input').clear().type(pasteContent);
cy.get('input').should('have.value', pasteContent);
// Select all and replace (simulating paste)
cy.get('input').select().type('Replaced content at different viewport');
cy.get('input').should('have.value', 'Replaced content at different viewport');
});
});
});
});