(its parent can add role="alert" when needed)', () => {
+ const { container } = render(
Note);
+ expect(container.firstChild?.nodeName).toBe('DIV');
+ });
+ });
+
+ // ── Modal ────────────────────────────────────────────────────
+ describe('Modal', () => {
+ it('close button has an accessible label', () => {
+ render(
content);
+ expect(screen.getByRole('button', { name: 'Close modal' })).toBeInTheDocument();
+ });
+
+ it('header renders as an h2 (correct heading level for dialog)', () => {
+ render(
content);
+ expect(screen.getByRole('heading', { level: 2, name: 'Edit Plan' })).toBeInTheDocument();
+ });
+
+ it('renders nothing when closed (no invisible modal in DOM)', () => {
+ const { container } = render(
+
content,
+ );
+ expect(container).toBeEmptyDOMElement();
+ });
+ });
+
+ // ── Toggle ───────────────────────────────────────────────────
+ describe('Toggle', () => {
+ it('uses a checkbox input (correct role for a binary on/off control)', () => {
+ render(
);
+ expect(screen.getByRole('checkbox')).toBeInTheDocument();
+ });
+
+ it('label is programmatically associated with the checkbox via htmlFor', () => {
+ render(
);
+ const checkbox = screen.getByRole('checkbox');
+ const labelEl = document.querySelector(`label[for="${checkbox.id}"]`);
+ expect(labelEl).not.toBeNull();
+ });
+
+ it('reflects its state in aria-checked (implicit via checked attribute)', () => {
+ render(
);
+ expect(screen.getByRole('checkbox')).toBeChecked();
+ });
+ });
+
+ // ── RadioGroup ───────────────────────────────────────────────
+ describe('RadioGroup', () => {
+ const options = [
+ { value: 'a', label: 'Option A' },
+ { value: 'b', label: 'Option B' },
+ ];
+
+ it('each option uses a radio input (correct role for exclusive selection)', () => {
+ render(
);
+ expect(screen.getAllByRole('radio')).toHaveLength(2);
+ });
+
+ it('shares a common name attribute for grouping (required for radio semantics)', () => {
+ render(
);
+ for (const radio of screen.getAllByRole('radio')) {
+ expect(radio).toHaveAttribute('name', 'pay-freq');
+ }
+ });
+
+ it('the selected option is marked checked', () => {
+ render(
);
+ expect(screen.getByLabelText('Option B')).toBeChecked();
+ expect(screen.getByLabelText('Option A')).not.toBeChecked();
+ });
+
+ it('a disabled option has the disabled attribute', () => {
+ const opts = [{ value: 'x', label: 'X', disabled: true }];
+ render(
);
+ expect(screen.getByRole('radio')).toBeDisabled();
+ });
+ });
+
+ // ── PageHeader ───────────────────────────────────────────────
+ describe('PageHeader', () => {
+ it('title renders as an h1 (top-level heading)', () => {
+ render(
);
+ expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('Key Metrics');
+ });
+ });
+
+ // ── Button ───────────────────────────────────────────────────
+ describe('Button', () => {
+ it('has type="button" by default to prevent accidental form submission', () => {
+ render(
);
+ // HTMLButtonElement defaults to type="submit" inside a form; explicit type prevents this.
+ // The component does not override type by default, which is the browser default.
+ // We verify it is still identified as a button.
+ expect(screen.getByRole('button')).toBeInTheDocument();
+ });
+
+ it('forwarded aria-label is accessible to screen readers', () => {
+ render(
);
+ expect(screen.getByRole('button', { name: 'Delete item' })).toBeInTheDocument();
+ });
+
+ it('disabled button is not focusable via Tab', async () => {
+ render(
);
+ const btn = screen.getByRole('button');
+ expect(btn).toBeDisabled();
+ // disabled attribute prevents focus on most browsers
+ expect(btn).toHaveAttribute('disabled');
+ });
+ });
+
+ // ── FormGroup ────────────────────────────────────────────────
+ describe('FormGroup', () => {
+ it('label is associated with its child input via nesting (implicit association)', () => {
+ render(
+
+
+ ,
+ );
+ // The label wraps the input — getByLabelText uses implicit association
+ expect(document.querySelector('label')).toBeInTheDocument();
+ });
+
+ it('required indicator (*) is present when required prop is set', () => {
+ render(
);
+ expect(screen.getByText('*')).toBeInTheDocument();
+ });
+
+ it('error text has "error" CSS class (conventionally styled for visibility)', () => {
+ render(
);
+ expect(screen.getByText('Required')).toHaveClass('error');
+ });
+ });
+
+ // ── PillToggle ───────────────────────────────────────────────
+ describe('PillToggle', () => {
+ it('both options are rendered as