import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { describe, it, expect, vi } from 'vitest'; import { Tooltip, TooltipTrigger, TooltipContent } from './tooltip'; import React from 'react'; // Mocking Portal vi.mock('@radix-ui/react-tooltip', async () => { const actual = await vi.importActual('@radix-ui/react-tooltip'); return { ...actual, Portal: ({ children }: { children: React.ReactNode }) => (
{children}
), }; }); describe('Tooltip', () => { it('renders correctly', () => { render( Hover me Tooltip info ); expect(screen.getByText('Hover me')).toBeInTheDocument(); }); it('shows content when open is true', () => { render( Hover me Tooltip info ); expect(screen.getAllByText('Tooltip info')[0]).toBeInTheDocument(); }); it('shows content on hover and hides it on unhover', async () => { const user = userEvent.setup(); render( // `disableHoverableContent` skips Radix's "pointer grace area" transition, // which otherwise only closes once a follow-up pointermove is detected // outside the trigger/content polygon (not simulated by userEvent.unhover). Hover me Tooltip info ); expect(screen.queryByText('Tooltip info')).not.toBeInTheDocument(); const trigger = screen.getByText('Hover me'); await user.hover(trigger); await waitFor(() => { expect(screen.getAllByText('Tooltip info')[0]).toBeInTheDocument(); }); await user.unhover(trigger); await waitFor(() => { expect(screen.queryByText('Tooltip info')).not.toBeInTheDocument(); }); }); it('shows content on focus and hides it on Escape', async () => { const user = userEvent.setup(); render( Focus me Tooltip info ); expect(screen.queryByText('Tooltip info')).not.toBeInTheDocument(); await user.tab(); await waitFor(() => { expect(screen.getAllByText('Tooltip info')[0]).toBeInTheDocument(); }); await user.keyboard('{Escape}'); await waitFor(() => { expect(screen.queryByText('Tooltip info')).not.toBeInTheDocument(); }); }); });