import { describe, expect, it } from 'vitest'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { configureAxe } from 'jest-axe'; import { Button } from '@/components/button'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/dialog'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/dropdown-menu'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/tooltip'; import { cases } from './cases'; /** * `color-contrast` needs a layout engine and computed colours, neither of which * jsdom has — it can only ever report "incomplete" here, so contrast is checked * in Storybook (addon-a11y runs against a real browser) instead. `region` wants * every node inside a landmark, which is a page-level concern a component * fragment cannot satisfy. */ const axe = configureAxe({ rules: { 'color-contrast': { enabled: false }, region: { enabled: false }, }, }); describe('a11y smoke', () => { it.each(cases)('%s has no axe violations', async (_name, element) => { const { container } = render(element); expect(await axe(container)).toHaveNoViolations(); }); /* Overlays render through a portal, so the audit has to look at the whole document — auditing the render container would find an empty div. */ it('dialog has no axe violations while open', async () => { const user = userEvent.setup(); render( Delete workspace This cannot be undone. ); await user.click(screen.getByRole('button', { name: 'Open' })); await screen.findByRole('dialog'); expect(await axe(document.body)).toHaveNoViolations(); }); it('dropdown menu has no axe violations while open', async () => { const user = userEvent.setup(); render( Rename Duplicate ); await user.click(screen.getByRole('button', { name: 'Actions' })); await screen.findByRole('menu'); expect(await axe(document.body)).toHaveNoViolations(); }); it('tooltip has no axe violations while open', async () => { const user = userEvent.setup(); render( Copy link to clipboard ); await user.hover(screen.getByRole('button', { name: 'Copy link' })); await screen.findByRole('tooltip'); expect(await axe(document.body)).toHaveNoViolations(); }); });