// Component tests for usa-footer import './index.ts'; describe('USA Footer Component Tests', () => { it('should render footer with default properties', () => { cy.mount(``); cy.get('usa-footer').should('exist'); cy.get('.usa-footer').should('exist'); cy.get('footer').should('have.attr', 'role', 'contentinfo'); }); it('should render medium variant by default', () => { cy.mount(``); cy.get('.usa-footer').should('have.class', 'usa-footer--medium'); }); it('should handle different variants', () => { const variants = ['slim', 'medium', 'big']; variants.forEach(variant => { cy.mount(``); cy.get('.usa-footer').should('have.class', `usa-footer--${variant}`); }); }); it('should render footer sections', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Services', links: [ { label: 'Service 1', href: '/service1' }, { label: 'Service 2', href: '/service2' } ] }, { title: 'Resources', links: [ { label: 'Documentation', href: '/docs' }, { label: 'Support', href: '/support' } ] } ]; }); cy.get('.usa-footer__nav').should('exist'); cy.get('.usa-footer__primary-content').should('have.length', 2); cy.get('.usa-footer__primary-link').should('contain.text', 'Services'); cy.get('.usa-footer__primary-link').should('contain.text', 'Resources'); }); it('should render footer section links', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Quick Links', links: [ { label: 'About Us', href: '/about' }, { label: 'Contact', href: '/contact' }, { label: 'Privacy Policy', href: '/privacy' } ] } ]; }); cy.get('.usa-footer__secondary-link').should('have.length', 3); cy.get('.usa-footer__secondary-link a').should('contain.text', 'About Us'); cy.get('.usa-footer__secondary-link a').should('contain.text', 'Contact'); cy.get('.usa-footer__secondary-link a').should('contain.text', 'Privacy Policy'); // Check href attributes cy.get('.usa-footer__secondary-link a[href="/about"]').should('exist'); cy.get('.usa-footer__secondary-link a[href="/contact"]').should('exist'); cy.get('.usa-footer__secondary-link a[href="/privacy"]').should('exist'); }); it('should handle footer link clicks', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Links', links: [ { label: 'Test Link', href: '/test' } ] } ]; const linkClickSpy = cy.stub(); footer.addEventListener('footer-link-click', linkClickSpy); cy.get('.usa-footer__secondary-link a').contains('Test Link').click(); cy.then(() => { expect(linkClickSpy).to.have.been.calledWith( Cypress.sinon.match({ detail: Cypress.sinon.match({ label: 'Test Link', href: '/test' }) }) ); }); }); }); it('should render agency identifier', () => { cy.mount(` `); cy.get('.usa-identifier').should('exist'); cy.get('.usa-identifier__section--masthead').should('exist'); cy.get('.usa-identifier__identity-domain') .should('contain.text', 'Department of Example Services'); }); it('should render identifier links', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.identifierLinks = [ { label: 'About this site', href: '/about-site' }, { label: 'Accessibility', href: '/accessibility' }, { label: 'Privacy Policy', href: '/privacy' }, { label: 'FOIA Requests', href: '/foia' } ]; }); cy.get('.usa-identifier__section--required-links').should('exist'); cy.get('.usa-identifier__required-links-item').should('have.length', 4); cy.get('.usa-identifier__required-link').should('contain.text', 'About this site'); cy.get('.usa-identifier__required-link').should('contain.text', 'Accessibility'); cy.get('.usa-identifier__required-link').should('contain.text', 'Privacy Policy'); cy.get('.usa-identifier__required-link').should('contain.text', 'FOIA Requests'); }); it('should handle identifier link clicks', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.identifierLinks = [ { label: 'Privacy Policy', href: '/privacy' } ]; const linkClickSpy = cy.stub(); footer.addEventListener('footer-link-click', linkClickSpy); cy.get('.usa-identifier__required-link').contains('Privacy Policy').click(); cy.then(() => { expect(linkClickSpy).to.have.been.calledWith( Cypress.sinon.match({ detail: Cypress.sinon.match({ label: 'Privacy Policy', href: '/privacy' }) }) ); }); }); }); it('should handle complete footer structure', () => { cy.mount(` `); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Services', links: [ { label: 'Online Services', href: '/services/online' }, { label: 'In-Person Services', href: '/services/in-person' } ] }, { title: 'About', links: [ { label: 'Our Mission', href: '/about/mission' }, { label: 'Leadership', href: '/about/leadership' }, { label: 'History', href: '/about/history' } ] }, { title: 'Resources', links: [ { label: 'Publications', href: '/resources/publications' }, { label: 'Data & Statistics', href: '/resources/data' } ] } ]; footer.identifierLinks = [ { label: 'About this site', href: '/about-site' }, { label: 'Accessibility', href: '/accessibility' }, { label: 'Privacy Policy', href: '/privacy' }, { label: 'FOIA Requests', href: '/foia' }, { label: 'No FEAR Act Data', href: '/no-fear' }, { label: 'Inspector General', href: '/ig' } ]; }); // Check variant cy.get('.usa-footer').should('have.class', 'usa-footer--big'); // Check sections cy.get('.usa-footer__primary-content').should('have.length', 3); cy.get('.usa-footer__secondary-link').should('have.length', 7); // Check identifier cy.get('.usa-identifier__identity-domain') .should('contain.text', 'U.S. Department of Examples'); cy.get('.usa-identifier__required-links-item').should('have.length', 6); }); it('should handle accessibility attributes correctly', () => { cy.mount(` `); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.identifierLinks = [ { label: 'Accessibility', href: '/accessibility' } ]; }); // Footer role cy.get('footer').should('have.attr', 'role', 'contentinfo'); // Identifier section accessibility cy.get('.usa-identifier__section--masthead') .should('have.attr', 'aria-label', 'Agency identifier'); cy.get('.usa-identifier__identity') .should('have.attr', 'aria-label', 'Agency description'); cy.get('.usa-identifier__section--required-links') .should('have.attr', 'aria-label', 'Important links'); }); it('should handle empty footer gracefully', () => { cy.mount(``); // Should render basic footer structure cy.get('.usa-footer').should('exist'); cy.get('footer').should('have.attr', 'role', 'contentinfo'); // Should not render nav section when no sections cy.get('.usa-footer__nav').should('not.exist'); // Should not render identifier when no agency or links cy.get('.usa-identifier').should('not.exist'); }); it('should handle footer with only agency name', () => { cy.mount(` `); cy.get('.usa-identifier').should('exist'); cy.get('.usa-identifier__identity-domain') .should('contain.text', 'Minimal Agency'); cy.get('.usa-identifier__section--required-links').should('not.exist'); }); it('should handle footer with only identifier links', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.identifierLinks = [ { label: 'Privacy Policy', href: '/privacy' } ]; }); cy.get('.usa-identifier').should('exist'); cy.get('.usa-identifier__section--masthead').should('exist'); cy.get('.usa-identifier__identity-domain').should('be.empty'); cy.get('.usa-identifier__section--required-links').should('exist'); }); it('should handle custom footer content', () => { cy.mount(` `); cy.get('.custom-footer-content') .should('contain.text', 'This is custom footer content'); cy.get('.custom-footer-content button') .should('contain.text', 'Custom Button'); }); it('should handle responsive grid structure', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Section 1', links: [{ label: 'Link 1', href: '/link1' }] }, { title: 'Section 2', links: [{ label: 'Link 2', href: '/link2' }] } ]; }); // Check grid structure cy.get('.usa-footer__nav-container').should('exist'); cy.get('.grid-container').should('exist'); cy.get('.grid-row').should('exist'); cy.get('.grid-gap').should('exist'); cy.get('.grid-col').should('have.length', 2); }); it('should handle event prevention for custom link handling', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Custom Links', links: [{ label: 'Custom Action', href: '/custom' }] } ]; // Prevent default navigation footer.addEventListener('footer-link-click', (e: any) => { e.preventDefault(); }); cy.get('.usa-footer__secondary-link a').contains('Custom Action').click(); // Should not navigate (would need to verify in a different way in real app) cy.url().should('not.include', '/custom'); }); }); it('should maintain proper link styling', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Links', links: [{ label: 'Test Link', href: '/test' }] } ]; footer.identifierLinks = [ { label: 'Identifier Link', href: '/identifier' } ]; }); // Section links should not have additional classes cy.get('.usa-footer__secondary-link a').should('not.have.class', 'usa-link'); // Identifier links should have usa-link class cy.get('.usa-identifier__required-link').should('have.class', 'usa-link'); }); it('should handle large number of sections', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = Array.from({ length: 6 }, (_, i) => ({ title: `Section ${i + 1}`, links: [ { label: `Link ${i + 1}A`, href: `/link${i + 1}a` }, { label: `Link ${i + 1}B`, href: `/link${i + 1}b` } ] })); }); cy.get('.usa-footer__primary-content').should('have.length', 6); cy.get('.usa-footer__secondary-link').should('have.length', 12); }); it('should handle keyboard navigation', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Navigation', links: [ { label: 'First Link', href: '/first' }, { label: 'Second Link', href: '/second' } ] } ]; footer.identifierLinks = [ { label: 'Privacy', href: '/privacy' } ]; }); // Tab through footer links cy.get('.usa-footer__secondary-link a').first().focus(); cy.focused().should('contain.text', 'First Link'); cy.focused().tab(); cy.focused().should('contain.text', 'Second Link'); cy.focused().tab(); cy.focused().should('contain.text', 'Privacy'); }); it('should handle mobile responsive behavior', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Services', links: [ { label: 'Service 1', href: '/service1' }, { label: 'Service 2', href: '/service2' } ] } ]; footer.agencyName = 'Mobile Test Agency'; footer.identifierLinks = [ { label: 'Accessibility', href: '/accessibility' } ]; }); // Set mobile viewport cy.viewport(375, 667); // Footer should still be functional cy.get('.usa-footer').should('be.visible'); cy.get('.usa-footer__primary-link').should('be.visible'); cy.get('.usa-footer__secondary-link a').should('be.visible'); cy.get('.usa-identifier__identity-domain').should('be.visible'); cy.get('.usa-identifier__required-link').should('be.visible'); }); it('should handle dynamic content updates', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; // Initially empty cy.get('.usa-footer__nav').should('not.exist'); // Add sections footer.sections = [ { title: 'Dynamic Section', links: [{ label: 'Dynamic Link', href: '/dynamic' }] } ]; cy.get('.usa-footer__nav').should('exist'); cy.get('.usa-footer__primary-link').should('contain.text', 'Dynamic Section'); // Update agency name footer.agencyName = 'Updated Agency'; cy.get('.usa-identifier__identity-domain') .should('contain.text', 'Updated Agency'); }); }); it('should be accessible', () => { cy.mount(`

Government Website

Main content of the website.

`); cy.window().then((win) => { const footer = win.document.getElementById('government-footer') as any; footer.sections = [ { title: 'Services', links: [ { label: 'Online Services', href: '/services/online' }, { label: 'Forms & Applications', href: '/services/forms' } ] }, { title: 'About', links: [ { label: 'Our Mission', href: '/about/mission' }, { label: 'Leadership', href: '/about/leadership' } ] } ]; footer.identifierLinks = [ { label: 'About this site', href: '/about-site' }, { label: 'Accessibility', href: '/accessibility' }, { label: 'Privacy Policy', href: '/privacy' }, { label: 'FOIA Requests', href: '/foia' } ]; }); cy.injectAxe(); cy.checkAccessibility(); }); it('should handle custom CSS classes', () => { cy.mount(` `); cy.get('usa-footer').should('have.class', 'custom-footer-class'); cy.get('.usa-footer').should('exist'); }); it('should handle link focus and hover states', () => { cy.mount(``); cy.window().then((win) => { const footer = win.document.getElementById('test-footer') as any; footer.sections = [ { title: 'Focus Test', links: [{ label: 'Focus Link', href: '/focus' }] } ]; footer.identifierLinks = [ { label: 'Hover Link', href: '/hover' } ]; }); // Test focus states cy.get('.usa-footer__secondary-link a').focus(); cy.focused().should('be.visible'); // Test hover states (trigger hover) cy.get('.usa-identifier__required-link').trigger('mouseover'); cy.get('.usa-identifier__required-link').should('be.visible'); }); });