Tests
This page documents the Vitest test suite for the Tooltip component and provides guidance for writing reliable tests,
including for keyboard accessibility and portal behavior.
Individual Test Explanations
- does not show tooltip content by default
- Ensures the tooltip is not rendered until user interaction.
react-tooltipappends the tooltip node todocument.body, accessible viascreenqueries in jsdom.
- Ensures the tooltip is not rendered until user interaction.
- shows tooltip on hover
userEvent.hovertriggers pointer events. The tooltip library mounts the tooltip node in response.
- hides tooltip when mouse leaves
- Uses
waitFor()to accommodate any hide delays or CSS transitions.
- Uses
- shows tooltip on keyboard focus
- Tests accessibility: the tooltip appears when the trigger element receives keyboard focus.
- hides tooltip when focus leaves
- Confirms the tooltip hides when the trigger loses focus.
waitFor()ensures the test accounts for any hide transition delays.
- Confirms the tooltip hides when the trigger loses focus.
Common Flakiness and Fixes
- Portal timing / animations
react-tooltipmay delay mounting/unmounting for animations. Wrap visibility assertions inawait waitFor()or usefindBy*queries to retry until the tooltip appears/disappears:expect(await screen.findByText('Hello tooltip')).toBeVisible();
await waitFor(() => expect(screen.queryByText('Hello tooltip')).not.toBeInTheDocument());- You can also disable CSS transitions in test setup for deterministic results.
- Missing jsdom environment
Tooltiprenders portals todocument.body. Ensure Vitest is running withenvironment: 'jsdom'.
- Event ordering
- Always use
userEvent.setup()andawaitinteractions. Avoid manually firing low-level events unless necessary.
- Always use
- Double focus / tab issues
- When testing tooltips on interactive elements, pass a single focusable element (e.g.,
<button>or<Link>) aschildren. If the component wraps non-element children in a<span tabIndex={0}>, account for that extra tab stop in tests.
- When testing tooltips on interactive elements, pass a single focusable element (e.g.,
- React strict mode / act warnings
- Vitest + Testing Library usually handles
act()automatically. Ensureglobals: truein your test setup and keep dependencies updated.
- Vitest + Testing Library usually handles
Testing Recommendations
- Always test tooltips attached to real interactive elements (buttons, links,
<Link>from react-router-dom) to avoid duplicate tab stops. - When testing external links or non-focusable nodes, account for the optional wrapper
<span tabIndex={0}>. - Use
findBy*for asserting tooltip visibility; it retries until the tooltip appears. - Wrap hide assertions in
waitFor()to accommodate CSS transitions or delayed unmounts.