@amsterdam/design-system-react
Version:
All React components from the Amsterdam Design System. Use it to compose pages in your website or application.
199 lines (198 loc) • 10.5 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { PlusIcon } from '@amsterdam/design-system-react-icons';
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { createRef } from 'react';
import { describe, expect, it, vi } from 'vitest';
import './matchMedia.mock'; // Must be imported before PageHeader
import { PageHeader } from './PageHeader';
describe('PageHeader', () => {
it('renders', () => {
render(_jsx(PageHeader, {}));
const component = screen.getByRole('banner');
expect(component).toBeInTheDocument();
expect(component).toBeVisible();
});
it('renders a design system BEM class name', () => {
render(_jsx(PageHeader, {}));
const component = screen.getByRole('banner');
expect(component).toHaveClass('ams-page-header');
});
it('renders an extra class name', () => {
render(_jsx(PageHeader, { className: "extra" }));
const component = screen.getByRole('banner');
expect(component).toHaveClass('ams-page-header extra');
});
it('supports ForwardRef in React', () => {
const ref = createRef();
render(_jsx(PageHeader, { ref: ref }));
const component = screen.getByRole('banner');
expect(ref.current).toBe(component);
});
it('renders a logo link', () => {
render(_jsx(PageHeader, {}));
const component = screen.getByRole('link');
expect(component).toHaveClass('ams-page-header__logo-link');
});
it('renders a different brand logo', () => {
const { container } = render(_jsx(PageHeader, { logoBrand: "ggd-amsterdam" }));
const component = container.querySelector('.ams-logo__text-secondary');
expect(component).toBeInTheDocument();
});
it('renders a custom logo link', () => {
render(_jsx(PageHeader, { logoLink: "/home" }));
const logoLink = screen.getByRole('link');
expect(logoLink).toHaveAttribute('href', '/home');
});
it('renders a custom logo link title', () => {
render(_jsx(PageHeader, { logoLinkTitle: "Go to homepage" }));
const logoLinkTitle = screen.getByRole('link', { name: 'Gemeente Amsterdam logo Go to homepage' });
expect(logoLinkTitle).toBeInTheDocument();
});
it('renders a custom accessible name for the logo', () => {
render(_jsx(PageHeader, { logoAccessibleName: "Custom accessible name" }));
const logoLinkTitle = screen.getByRole('link', { name: 'Custom accessible name Ga naar de homepage' });
expect(logoLinkTitle).toBeInTheDocument();
});
it('renders an application name', () => {
render(_jsx(PageHeader, { brandName: "Application name" }));
const brandName = screen.getByText('Application name');
expect(brandName).toBeInTheDocument();
});
it('renders the correct class for the responsive logo', () => {
const { container } = render(_jsx(PageHeader, { brandName: "Application name" }));
const logoContainer = container.querySelector('.ams-page-header__logo-container');
expect(logoContainer).toBeInTheDocument();
});
it('renders a nav section', () => {
render(_jsx(PageHeader, { children: "Test" }));
const component = screen.getByRole('navigation');
expect(component).toHaveClass('ams-page-header__navigation');
});
it('renders a nav section with the default accessible name', () => {
render(_jsx(PageHeader, { children: "Test" }));
const component = screen.getByRole('navigation', { name: 'Hoofdmenu' });
expect(component).toBeInTheDocument();
});
it('renders a nav section with a custom accessible name', () => {
render(_jsx(PageHeader, { navigationLabel: "Custom Navigation", children: "Test" }));
const component = screen.getByRole('navigation', { name: 'Custom Navigation' });
expect(component).toBeInTheDocument();
});
it('renders a menu', () => {
render(_jsx(PageHeader, { menuItems: _jsx(PageHeader.MenuLink, { children: "Menu Item" }) }));
const component = screen.getByRole('list');
expect(component).toHaveClass('ams-page-header__menu');
});
it('renders menu items', () => {
render(_jsx(PageHeader, { menuItems: [
_jsx(PageHeader.MenuLink, { href: "/", children: "Menu Item 1" }, 1),
_jsx(PageHeader.MenuLink, { href: "/", children: "Menu Item 2" }, 2),
] }));
const item1 = screen.getByRole('link', { name: 'Menu Item 1' });
const item2 = screen.getByRole('link', { name: 'Menu Item 2' });
expect(item1).toBeInTheDocument();
expect(item2).toBeInTheDocument();
});
it('renders a menu button', () => {
render(_jsx(PageHeader, { children: "Test" }));
const component = screen.getByRole('button', { hidden: true, name: 'Laat navigatiemenu zien' });
expect(component).toHaveClass('ams-page-header__mega-menu-button');
});
it('renders a menu button icon', () => {
const { container } = render(_jsx(PageHeader, { children: "Test" }));
const component = container.querySelector('.ams-page-header__menu-icon');
expect(component).toBeInTheDocument();
});
it('renders a custom menu button text', () => {
render(_jsx(PageHeader, { menuButtonText: "Custom button text", children: "Test" }));
const component = screen.getAllByText('Custom button text');
expect(component[0]).toBeInTheDocument();
});
it('renders the correct class when noMenuButtonOnWideWindow is true', () => {
render(_jsx(PageHeader, { noMenuButtonOnWideWindow: true, children: "Test" }));
const component = screen.getByRole('listitem', { hidden: true });
expect(component).toHaveClass('ams-page-header__mega-menu-button-item--hide-on-wide-window');
});
it('opens and closes the mega menu', async () => {
const user = userEvent.setup();
const { container } = render(_jsx(PageHeader, { children: "Test" }));
const closedMegaMenu = container.querySelector('.ams-page-header__mega-menu--closed');
expect(closedMegaMenu).toBeInTheDocument();
const menuButton = screen.getByRole('button', { hidden: true, name: 'Laat navigatiemenu zien' });
await user.click(menuButton);
const openMegaMenu = container.querySelector('.ams-page-header__mega-menu');
expect(openMegaMenu).toBeInTheDocument();
expect(openMegaMenu).not.toHaveClass('ams-page-header__mega-menu--closed');
});
it('updates the menu button text for screen readers when the menu is opened and closed', async () => {
const user = userEvent.setup();
render(_jsx(PageHeader, { children: "Test" }));
const menuButton = screen.getByRole('button', { hidden: true });
expect(menuButton).toHaveTextContent('Laat navigatiemenu zien');
await user.click(menuButton);
expect(menuButton).toHaveTextContent('Verberg navigatiemenu');
await user.click(menuButton);
expect(menuButton).toHaveTextContent('Laat navigatiemenu zien');
});
it('renders custom texts for screen readers on the menu button', async () => {
const user = userEvent.setup();
render(_jsx(PageHeader, { menuButtonTextForHide: "Custom hide text", menuButtonTextForShow: "Custom show text", children: "Test" }));
const menuButton = screen.getByRole('button', { hidden: true });
expect(menuButton).toHaveTextContent('Custom show text');
await user.click(menuButton);
expect(menuButton).toHaveTextContent('Custom hide text');
});
it('closes the mega menu when it is open and the screen width passes the breakpoint', async () => {
let changeListener;
const mediaQueryList = {
addEventListener: vi.fn((_event, listener) => {
changeListener = listener;
}),
matches: false,
removeEventListener: vi.fn(),
};
const originalMatchMedia = window.matchMedia;
window.matchMedia = vi.fn().mockReturnValue(mediaQueryList);
try {
const user = userEvent.setup();
const { container } = render(_jsx(PageHeader, { noMenuButtonOnWideWindow: true, children: "Test" }));
const menuButton = screen.getByRole('button', { hidden: true, name: 'Laat navigatiemenu zien' });
await user.click(menuButton);
expect(container.querySelector('.ams-page-header__mega-menu')).not.toHaveClass('ams-page-header__mega-menu--closed');
// Simulate the viewport crossing the 'wide' breakpoint
mediaQueryList.matches = true;
act(() => {
changeListener?.();
});
expect(container.querySelector('.ams-page-header__mega-menu')).toHaveClass('ams-page-header__mega-menu--closed');
}
finally {
window.matchMedia = originalMatchMedia;
}
});
it('renders a short brand name', () => {
render(_jsx(PageHeader, { brandName: "Application name", brandNameShort: "App" }));
const component = screen.getByText('App');
expect(component).toBeInTheDocument();
expect(component).toHaveClass('ams-page-header__brand-name-short');
});
it('renders a custom logo link component', () => {
const CustomLink = (props) => _jsx("a", { "data-test": true, ...props });
render(_jsx(PageHeader, { logoLinkComponent: CustomLink }));
const customLink = screen.getByRole('link', { name: 'Gemeente Amsterdam logo Ga naar de homepage' });
expect(customLink).toHaveAttribute('data-test');
});
it('renders a custom icon', () => {
render(_jsx(PageHeader, { menuButtonIcon: _jsx(PlusIcon, { "aria-label": "plus-icon", className: "test-class" }), children: "Test" }));
const icon = screen.getByLabelText('plus-icon');
expect(icon).toHaveClass('test-class');
});
it('passes additional props', () => {
render(_jsx(PageHeader, { "aria-hidden": "false", "data-test": "data-test", id: "id" }));
const component = screen.getByRole('banner');
expect(component).toHaveAttribute('aria-hidden', 'false');
expect(component).toHaveAttribute('id', 'id');
expect(component).toHaveAttribute('data-test', 'data-test');
});
});