// Component tests for usa-checkbox
import './index.ts';
describe('USA Checkbox Component Tests', () => {
it('should render checkbox with default properties', () => {
cy.mount(`
Test Checkbox
`);
cy.get('usa-checkbox').should('exist');
cy.get('usa-checkbox input[type="checkbox"]').should('have.class', 'usa-checkbox__input');
cy.get('usa-checkbox .usa-checkbox__label').should('contain.text', 'Test Checkbox');
});
it('should handle checked state changes', () => {
cy.mount(`
Test Checkbox
`);
// Initially unchecked
cy.get('input[type="checkbox"]').should('not.be.checked');
// Click to check
cy.get('input[type="checkbox"]').check();
cy.get('input[type="checkbox"]').should('be.checked');
// Click to uncheck
cy.get('input[type="checkbox"]').uncheck();
cy.get('input[type="checkbox"]').should('not.be.checked');
});
it('should handle clicking on label', () => {
cy.mount(`
I agree to the terms and conditions
`);
// Click on label should toggle checkbox
cy.get('.usa-checkbox__label').click();
cy.get('input[type="checkbox"]').should('be.checked');
cy.get('.usa-checkbox__label').click();
cy.get('input[type="checkbox"]').should('not.be.checked');
});
it('should emit change events', () => {
cy.mount(`
Subscribe to newsletter
`);
cy.window().then((win) => {
const checkbox = win.document.getElementById('test-checkbox') as any;
const changeSpy = cy.stub();
checkbox.addEventListener('change', changeSpy);
cy.get('input[type="checkbox"]').check();
cy.then(() => {
expect(changeSpy).to.have.been.called;
});
});
});
it('should handle initial checked state', () => {
cy.mount(`
Pre-selected option
`);
cy.get('input[type="checkbox"]').should('be.checked');
});
it('should handle disabled state', () => {
cy.mount(`
Disabled checkbox
`);
cy.get('input[type="checkbox"]').should('be.disabled');
cy.get('.usa-checkbox__label').should('have.class', 'usa-checkbox__label--disabled');
// Should not be clickable
cy.get('.usa-checkbox__label').click({ force: true });
cy.get('input[type="checkbox"]').should('not.be.checked');
});
it('should handle required state', () => {
cy.mount(`
I accept the required terms (Required)
`);
cy.get('input[type="checkbox"]').should('have.attr', 'required');
cy.get('input[type="checkbox"]').should('have.attr', 'aria-required', 'true');
});
it('should handle error state', () => {
cy.mount(`
I accept the terms and conditions
`);
cy.get('input[type="checkbox"]').should('have.attr', 'aria-invalid', 'true');
cy.get('.usa-checkbox').should('have.class', 'usa-checkbox--error');
cy.get('.usa-error-message').should('contain.text', 'You must accept the terms to continue');
});
it('should handle indeterminate state', () => {
cy.mount(`
Partially selected
`);
cy.get('input[type="checkbox"]').should('have.prop', 'indeterminate', true);
cy.get('.usa-checkbox__input').should('have.class', 'usa-checkbox__input--indeterminate');
});
it('should handle large size variant', () => {
cy.mount(`
Large checkbox
`);
cy.get('.usa-checkbox').should('have.class', 'usa-checkbox--large');
});
it('should handle small size variant', () => {
cy.mount(`
Small checkbox
`);
cy.get('.usa-checkbox').should('have.class', 'usa-checkbox--small');
});
it('should be keyboard accessible', () => {
cy.mount(`
Keyboard accessible checkbox
`);
// Tab to checkbox
cy.get('input[type="checkbox"]').focus();
cy.focused().should('have.attr', 'name', 'keyboard-test');
// Space to toggle
cy.focused().type(' ');
cy.get('input[type="checkbox"]').should('be.checked');
cy.focused().type(' ');
cy.get('input[type="checkbox"]').should('not.be.checked');
});
it('should handle form integration', () => {
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);
const services = formData.getAll('services');
const newsletter = formData.get('newsletter');
submitSpy({ services, newsletter });
});
// Check web design
cy.get('#checkbox1 input').check();
// Submit form
cy.get('button[type="submit"]').click();
cy.then(() => {
expect(submitSpy).to.have.been.calledWith({
services: ['web-design'],
newsletter: 'subscribe'
});
});
});
});
it('should handle grouped checkboxes', () => {
cy.mount(`
`);
// Select multiple interests
cy.get('#interest1 input').check();
cy.get('#interest3 input').check();
cy.get('input[name="interests"]:checked').should('have.length', 2);
cy.get('#interest1 input').should('be.checked');
cy.get('#interest2 input').should('not.be.checked');
cy.get('#interest3 input').should('be.checked');
});
it('should handle tile variant', () => {
cy.mount(`
Tile checkbox with more content and description
`);
cy.get('.usa-checkbox').should('have.class', 'usa-checkbox--tile');
});
it('should handle description text', () => {
cy.mount(`
Checkbox with description
`);
cy.get('.usa-checkbox__description').should('contain.text', 'This is additional descriptive text for the checkbox');
});
it('should handle aria attributes', () => {
cy.mount(`
Additional context for this choice
Checkbox with ARIA attributes
`);
cy.get('input[type="checkbox"]')
.should('have.attr', 'aria-describedby', 'checkbox-description');
});
it('should handle focus and blur events', () => {
cy.mount(`
Focus test checkbox
`);
cy.window().then((win) => {
const checkbox = win.document.getElementById('test-checkbox') as any;
const focusSpy = cy.stub();
const blurSpy = cy.stub();
checkbox.addEventListener('focus', focusSpy);
checkbox.addEventListener('blur', blurSpy);
cy.get('input[type="checkbox"]').focus();
cy.get('input[type="checkbox"]').blur();
cy.then(() => {
expect(focusSpy).to.have.been.called;
expect(blurSpy).to.have.been.called;
});
});
});
it('should handle validation on blur', () => {
cy.mount(`
Required checkbox
`);
// Focus and blur without checking (should trigger validation)
cy.get('input[type="checkbox"]').focus().blur();
cy.get('input[type="checkbox"]').should('have.attr', 'aria-invalid', 'true');
// Check and blur (should clear validation)
cy.get('input[type="checkbox"]').check().blur();
cy.get('input[type="checkbox"]').should('not.have.attr', 'aria-invalid', 'true');
});
it('should be accessible', () => {
cy.mount(`
`);
cy.injectAxe();
cy.checkAccessibility();
});
it('should handle custom CSS classes', () => {
cy.mount(`
Custom styled checkbox
`);
cy.get('usa-checkbox').should('have.class', 'custom-checkbox-class');
cy.get('.usa-checkbox').should('exist');
});
it('should handle mixed state in parent-child relationships', () => {
cy.mount(`
Select All Options
Option 1
Option 2
Option 3
`);
// Check some but not all children
cy.get('#child1 input').check();
cy.get('#child2 input').check();
// Parent should be in indeterminate state (if functionality exists)
cy.window().then((win) => {
const parentCheckbox = win.document.querySelector('#parent-checkbox input') as HTMLInputElement;
if (parentCheckbox) {
parentCheckbox.indeterminate = true;
}
});
cy.get('#parent-checkbox input').should('have.prop', 'indeterminate', true);
});
it('should handle value changes programmatically', () => {
cy.mount(`
Programmatically controlled
`);
cy.window().then((win) => {
const checkbox = win.document.getElementById('test-checkbox') as any;
// Set checked programmatically
checkbox.checked = true;
cy.get('input[type="checkbox"]').should('be.checked');
// Uncheck programmatically
checkbox.checked = false;
cy.get('input[type="checkbox"]').should('not.be.checked');
});
});
});