// Component tests for usa-card
import './index.ts';
describe('USA Card Component Tests', () => {
it('should render card with default properties', () => {
cy.mount(``);
cy.get('usa-card').should('exist');
cy.get('.usa-card__container').should('exist');
cy.get('usa-card').should('have.class', 'usa-card');
});
it('should render heading with correct level', () => {
cy.mount(`
`);
cy.get('.usa-card__header').should('exist');
cy.get('.usa-card__heading').should('contain.text', 'Test Card Title');
cy.get('h2.usa-card__heading').should('exist');
});
it('should render body text', () => {
cy.mount(`
`);
cy.get('.usa-card__body').should('exist');
cy.get('.usa-card__body p').should('contain.text', 'This is the card body text content.');
});
it('should render footer text', () => {
cy.mount(`
`);
cy.get('.usa-card__footer').should('exist');
cy.get('.usa-card__footer p').should('contain.text', 'Card footer information');
});
it('should render complete card with all content', () => {
cy.mount(`
`);
cy.get('h1.usa-card__heading').should('contain.text', 'Complete Card');
cy.get('.usa-card__body p').should('contain.text', 'This card has all content types.');
cy.get('.usa-card__footer p').should('contain.text', 'Footer information');
});
it('should render image media', () => {
cy.mount(`
`);
cy.get('.usa-card__media').should('exist');
cy.get('.usa-card__img').should('exist');
cy.get('.usa-card__img img')
.should('have.attr', 'src', '/img/test-image.jpg')
.should('have.attr', 'alt', 'Test image description')
.should('have.attr', 'loading', 'lazy');
});
it('should render video media', () => {
cy.mount(`
`);
cy.get('.usa-card__media').should('exist');
cy.get('.usa-card__video').should('exist');
cy.get('.usa-card__video video')
.should('have.attr', 'src', '/videos/test-video.mp4')
.should('have.attr', 'controls')
.should('have.attr', 'aria-label', 'Test video description');
});
it('should handle different media positions', () => {
const positions = ['inset', 'exdent', 'right'];
positions.forEach(position => {
cy.mount(`
`);
if (position === 'right') {
cy.get('usa-card').should('have.class', 'usa-card--media-right');
} else {
cy.get('.usa-card__media').should('have.class', `usa-card__media--${position}`);
}
});
});
it('should handle flag layout', () => {
cy.mount(`
`);
cy.get('usa-card').should('have.class', 'usa-card--flag');
});
it('should handle header-first layout', () => {
cy.mount(`
`);
cy.get('usa-card').should('have.class', 'usa-card--header-first');
// Verify order: header should come before media
cy.get('.usa-card__container').children().first().should('have.class', 'usa-card__header');
});
it('should handle actionable cards', () => {
cy.mount(`
`);
cy.get('usa-card')
.should('have.attr', 'role', 'button')
.should('have.attr', 'tabindex', '0');
cy.get('.usa-card__container').should('have.class', 'usa-card__container--actionable');
});
it('should emit card-click events when clicked', () => {
cy.mount(`
`);
cy.window().then((win) => {
const card = win.document.getElementById('test-card') as any;
const clickSpy = cy.stub();
card.addEventListener('card-click', clickSpy);
// Stub window navigation for testing
cy.stub(win, 'location').value({ href: '' });
cy.get('usa-card').click();
cy.then(() => {
expect(clickSpy).to.have.been.calledWith(
Cypress.sinon.match({
detail: Cypress.sinon.match({
heading: 'Clickable Card',
href: '/clicked-page'
})
})
);
});
});
});
it('should handle keyboard interaction on actionable cards', () => {
cy.mount(`
`);
cy.window().then((win) => {
const card = win.document.getElementById('test-card') as any;
const clickSpy = cy.stub();
card.addEventListener('card-click', clickSpy);
// Test Enter key
cy.get('usa-card').focus().type('{enter}');
cy.then(() => {
expect(clickSpy).to.have.been.called;
});
// Test Space key
cy.get('usa-card').focus().type(' ');
cy.then(() => {
expect(clickSpy).to.have.been.calledTwice;
});
});
});
it('should handle target="_blank" for actionable cards', () => {
cy.mount(`
`);
cy.window().then((win) => {
// Stub window.open for testing
cy.stub(win, 'open').as('windowOpen');
cy.get('usa-card').click();
cy.get('@windowOpen').should('have.been.calledWith', 'https://example.com', '_blank');
});
});
it('should handle custom slotted content', () => {
cy.mount(`
Custom body content with HTML.
Custom footer with links.
`);
cy.get('.usa-card__body').should('contain.text', 'Custom body content with HTML');
cy.get('.usa-card__body button').should('contain.text', 'Custom Button');
cy.get('.usa-card__footer').should('contain.text', 'Custom footer with links');
cy.get('.usa-card__footer a').should('have.attr', 'href', '/link');
});
it('should handle completely custom content with default slot', () => {
cy.mount(`
Completely Custom Card
This content is not using the standard card structure.
`);
cy.get('.custom-card-content').should('exist');
cy.get('.custom-card-content h2').should('contain.text', 'Completely Custom Card');
});
it('should handle media-right with non-flag layout', () => {
cy.mount(`
`);
cy.get('usa-card').should('have.class', 'usa-card--media-right');
cy.get('usa-card').should('not.have.class', 'usa-card--flag');
});
it('should handle flag layout with media right', () => {
cy.mount(`
`);
cy.get('usa-card')
.should('have.class', 'usa-card--flag')
.should('have.class', 'usa-card--media-right');
});
it('should handle different heading levels', () => {
const levels = ['1', '2', '3', '4', '5', '6'];
levels.forEach(level => {
cy.mount(`
`);
cy.get(`h${level}.usa-card__heading`).should('contain.text', `Heading Level ${level}`);
});
});
it('should not render sections without content', () => {
cy.mount(``);
// Should not render header, body, or footer when empty
cy.get('.usa-card__header').should('not.exist');
cy.get('.usa-card__body').should('not.exist');
cy.get('.usa-card__footer').should('not.exist');
cy.get('.usa-card__media').should('not.exist');
});
it('should update classes when properties change', () => {
cy.mount(``);
cy.window().then((win) => {
const card = win.document.getElementById('test-card') as any;
// Initially not flag layout
cy.get('usa-card').should('not.have.class', 'usa-card--flag');
// Change to flag layout
card.flagLayout = true;
cy.get('usa-card').should('have.class', 'usa-card--flag');
// Change to actionable
card.actionable = true;
cy.get('usa-card').should('have.attr', 'role', 'button');
cy.get('.usa-card__container').should('have.class', 'usa-card__container--actionable');
// Change to header first
card.headerFirst = true;
cy.get('usa-card').should('have.class', 'usa-card--header-first');
});
});
it('should handle complex card with all features', () => {
cy.mount(`
Additional custom content can be added via slots.
- Online applications available
- 24/7 customer support
- Multi-language assistance
`);
// Verify all elements are rendered correctly
cy.get('usa-card').should('have.class', 'usa-card--flag');
cy.get('usa-card').should('have.attr', 'role', 'button');
cy.get('h2.usa-card__heading').should('contain.text', 'Complex Government Service Card');
cy.get('.usa-card__media--inset').should('exist');
cy.get('.usa-card__body').should('contain.text', 'This card demonstrates all available features');
cy.get('.usa-card__body ul').should('exist');
cy.get('.usa-card__footer').should('contain.text', 'Updated: March 2024');
});
it('should handle accessibility correctly', () => {
cy.mount(`
`);
// Check actionable accessibility
cy.get('usa-card')
.should('have.attr', 'role', 'button')
.should('have.attr', 'tabindex', '0');
// Check image accessibility
cy.get('.usa-card__img img')
.should('have.attr', 'alt', 'Descriptive alternative text for screen readers');
// Check keyboard navigation
cy.get('usa-card').focus();
cy.focused().should('be.visible');
});
it('should handle focus and hover states', () => {
cy.mount(`
`);
// Test focus
cy.get('usa-card').focus();
cy.focused().should('have.class', 'usa-card');
// Test hover (trigger hover event)
cy.get('usa-card').trigger('mouseover');
cy.get('usa-card').should('be.visible');
});
it('should cleanup event listeners on disconnect', () => {
cy.mount(`
`);
cy.window().then((win) => {
// Verify card is interactive
cy.get('usa-card').should('have.attr', 'role', 'button');
// Remove card from DOM
container!.removeChild(card);
// Should not cause errors when removed
cy.get('body').click();
});
});
it('should handle non-actionable cards correctly', () => {
cy.mount(`
`);
cy.get('usa-card')
.should('not.have.attr', 'role')
.should('not.have.attr', 'tabindex');
cy.get('.usa-card__container').should('not.have.class', 'usa-card__container--actionable');
// Click should not emit events
cy.window().then((win) => {
const card = win.document.getElementById('static-card') as any;
const clickSpy = cy.stub();
card.addEventListener('card-click', clickSpy);
cy.get('usa-card').click();
cy.then(() => {
expect(clickSpy).not.to.have.been.called;
});
});
});
it('should handle responsive behavior', () => {
cy.mount(`
`);
// Set mobile viewport
cy.viewport(375, 667);
cy.get('.usa-card').should('be.visible');
cy.get('.usa-card__heading').should('be.visible');
cy.get('.usa-card__body').should('be.visible');
cy.get('.usa-card__media').should('be.visible');
// Set desktop viewport
cy.viewport(1200, 800);
cy.get('.usa-card').should('be.visible');
cy.get('usa-card').should('have.class', 'usa-card--flag');
cy.get('usa-card').should('have.class', 'usa-card--media-right');
});
it('should be accessible', () => {
cy.mount(`
`);
cy.injectAxe();
cy.checkAccessibility();
});
it('should handle custom CSS classes', () => {
cy.mount(`
`);
cy.get('usa-card')
.should('have.class', 'custom-card-class')
.should('have.class', 'special-styling')
.should('have.class', 'usa-card');
});
});