import React from 'react'; import { act, screen } from '@testing-library/react'; import { render } from '../../../../vitest/render'; import { InputDialog } from './InputDialog'; describe('InputDialog', () => { // The Vitest setup fails tests on console output, so this also guards against the core // Dialog.Overlay "no accessible name" warning false-positiving before Dialog.Title registers. it('derives the accessible name from a non-string label via Dialog.Title', () => { render( Choose} onOpenChange={() => {}} trigger={}>
content
); const dialog = screen.getByRole('dialog'); const labelledBy = dialog.getAttribute('aria-labelledby'); expect(labelledBy).toBeTruthy(); expect(document.getElementById(labelledBy!)?.textContent).toBe('Choose'); const inputDialog = document.querySelector('.inputDialog'); expect(inputDialog).not.toBeNull(); expect(inputDialog!.style.getPropertyValue('--visual-viewport-height')).toMatch(/^\d+px$/); }); it('moves focus into the dialog when opened while kept mounted', () => { const dialogTree = (isOpen: boolean) => ( {}} trigger={}> ); const { rerender } = render(dialogTree(false)); expect(document.querySelector('.inputDialog')).toBeNull(); rerender(dialogTree(true)); const dialog = screen.getByRole('dialog'); // focusSafely defers the move behind one rAF when the interaction modality — module-global, // shared across files under `isolate: false` — leaked 'virtual' from an earlier test. The // rAF sits on the suite's fake timers, so advance a frame to land it either way. act(() => vi.advanceTimersToNextFrame()); expect(dialog.contains(document.activeElement)).toBe(true); }); it('clears data-entering after the enter animation settles', () => { render( {}} trigger={}>
content
); // Without Web Animations (jsdom) the enter animation settles synchronously. const inputDialog = document.querySelector('.inputDialog')!; expect(Object.hasOwn(inputDialog.dataset, 'entering')).toBe(false); expect(Object.hasOwn(document.querySelector('.inputDialog__modal')!.dataset, 'entering')).toBe(false); }); });