import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import './usa-footer.ts';
import type { USAFooter } from './usa-footer.js';
/**
* USWDS Footer Alignment Validation Tests
*
* These tests ensure our footer implementation exactly matches USWDS patterns.
* They catch structural misalignments that cause styling and behavior issues.
*
* CRITICAL: These tests must pass to ensure USWDS compliance.
*/
describe('Footer USWDS Alignment Validation', () => {
let element: USAFooter;
beforeEach(() => {
element = document.createElement('usa-footer') as USAFooter;
document.body.appendChild(element);
});
afterEach(() => {
element.remove();
});
describe('Medium Footer USWDS Structure Validation', () => {
beforeEach(async () => {
element.variant = 'medium';
element.agencyName = 'Test Agency';
element.sections = [
{ title: 'About', links: [{ label: 'Mission', href: '/mission' }] },
{ title: 'Services', links: [{ label: 'Digital', href: '/digital' }] }
];
await element.updateComplete;
});
it('should have correct primary section structure per USWDS medium footer', () => {
// USWDS Medium Footer: Primary section contains nav with grid-row
const primarySection = element.querySelector('.usa-footer__primary-section');
const nav = element.querySelector('.usa-footer__nav');
const gridContainer = element.querySelector('.usa-footer__primary-section .grid-container');
const gridRow = element.querySelector('.usa-footer__nav .grid-row');
expect(primarySection, 'Primary section must exist').toBeTruthy();
expect(nav, 'Navigation must exist within primary section').toBeTruthy();
expect(gridContainer, 'Grid container must exist in primary section').toBeTruthy();
expect(gridRow, 'Grid row must exist in navigation').toBeTruthy();
// Verify proper nesting: primary-section > nav > grid-container > grid-row
expect(primarySection?.contains(nav!), 'Nav must be inside primary section').toBe(true);
expect(nav?.contains(gridContainer!), 'Grid container must be inside nav').toBe(true);
expect(gridContainer?.contains(gridRow!), 'Grid row must be inside grid container').toBe(true);
});
it('should use primary links as elements (not headings) per USWDS medium pattern', () => {
const primaryLinks = element.querySelectorAll('.usa-footer__primary-link');
expect(primaryLinks.length, 'Should have primary links').toBeGreaterThan(0);
primaryLinks.forEach((link, index) => {
expect(link.tagName.toLowerCase(), `Primary link ${index} must be element for medium footer`).toBe('a');
expect(link.getAttribute('href'), `Primary link ${index} must have href attribute`).toBeTruthy();
});
});
it('should have proper list structure without bullets', () => {
const mainList = element.querySelector('.usa-footer__nav ul');
const listItems = element.querySelectorAll('.usa-footer__nav li');
expect(mainList, 'Main navigation list must exist').toBeTruthy();
expect(mainList?.classList.contains('usa-list--unstyled'), 'List must be unstyled (no bullets)').toBe(true);
expect(mainList?.classList.contains('grid-row'), 'List must have grid-row class').toBe(true);
expect(listItems.length, 'Should have list items for each section').toBe(2);
});
it('should have proper secondary section with contact info', () => {
const secondarySection = element.querySelector('.usa-footer__secondary-section');
const agencyName = element.querySelector('.usa-footer__logo-heading');
const contactHeading = element.querySelector('.usa-footer__contact-heading');
const address = element.querySelector('.usa-footer__address');
expect(secondarySection, 'Secondary section must exist for medium footer').toBeTruthy();
expect(agencyName, 'Agency name must be in secondary section').toBeTruthy();
expect(contactHeading, 'Contact heading must exist').toBeTruthy();
expect(address, 'Address element must exist').toBeTruthy();
expect(agencyName?.textContent?.trim(), 'Agency name must be displayed').toBe('Test Agency');
});
});
describe('Big Footer USWDS Structure Validation', () => {
beforeEach(async () => {
element.variant = 'big';
element.agencyName = 'Test Agency';
element.sections = [
{
title: 'About',
links: [
{ label: 'Mission', href: '/mission' },
{ label: 'History', href: '/history' }
]
},
{
title: 'Services',
links: [
{ label: 'Digital', href: '/digital' },
{ label: 'Support', href: '/support' }
]
}
];
await element.updateComplete;
});
it('should have correct big footer grid structure per USWDS', () => {
// USWDS Big Footer: Primary section > grid-container > grid-row > tablet:grid-col-8 + tablet:grid-col-4
const primarySection = element.querySelector('.usa-footer__primary-section');
const outerGridContainer = element.querySelector('.usa-footer__primary-section > .grid-container');
const outerGridRow = element.querySelector('.usa-footer__primary-section .grid-row');
const contentColumn = element.querySelector('.tablet\\:grid-col-8');
const sidebarColumn = element.querySelector('.tablet\\:grid-col-4');
expect(primarySection, 'Primary section must exist').toBeTruthy();
expect(outerGridContainer, 'Outer grid container must exist').toBeTruthy();
expect(outerGridRow, 'Outer grid row must exist').toBeTruthy();
expect(contentColumn, 'Content column (tablet:grid-col-8) must exist').toBeTruthy();
expect(sidebarColumn, 'Sidebar column (tablet:grid-col-4) must exist').toBeTruthy();
});
it('should use headings (not links) for section titles per USWDS big pattern', () => {
const primaryLinks = element.querySelectorAll('.usa-footer__primary-link');
expect(primaryLinks.length, 'Should have primary headings').toBeGreaterThan(0);
primaryLinks.forEach((heading, index) => {
expect(heading.tagName.toLowerCase(), `Primary heading ${index} must be