import { act } from 'react'; import { createRoot } from 'react-dom/client'; import { MemoryRouter, Route, Routes, useNavigate } from 'react-router-dom'; import { afterEach, describe, expect, it } from 'vitest'; import { RouteKeeper } from './RouteKeeper'; let container: HTMLDivElement | null = null; let root: ReturnType | null = null; afterEach(async () => { if (root) await act(async () => root?.unmount()); container?.remove(); root = null; container = null; }); function PageA() { const navigate = useNavigate(); return (
); } function PageB() { const navigate = useNavigate(); return (
); } function Harness() { return ( }> } /> } /> ); } function type(target: HTMLInputElement, value: string) { const setter = Object.getOwnPropertyDescriptor( window.HTMLInputElement.prototype, 'value', )?.set; setter?.call(target, value); target.dispatchEvent(new Event('input', { bubbles: true })); } describe('RouteKeeper', () => { it('keeps page instances and input values alive across navigation', async () => { container = document.createElement('div'); document.body.appendChild(container); root = createRoot(container); await act(async () => root?.render()); const inputA = document.querySelector('[data-testid="input-a"]') as HTMLInputElement; expect(inputA).not.toBeNull(); await act(async () => type(inputA, '待保存的学生姓名')); await act(async () => { (document.querySelector('[data-testid="go-b"]') as HTMLButtonElement).click(); }); const inputB = document.querySelector('[data-testid="input-b"]') as HTMLInputElement; expect(inputB).not.toBeNull(); await act(async () => type(inputB, '待保存的宿舍号')); await act(async () => { (document.querySelector('[data-testid="go-a"]') as HTMLButtonElement).click(); }); const keptA = document.querySelector('[data-testid="input-a"]') as HTMLInputElement; expect(keptA).not.toBeNull(); expect(keptA.value).toBe('待保存的学生姓名'); const keptB = document.querySelector('[data-testid="input-b"]') as HTMLInputElement; expect(keptB.value).toBe('待保存的宿舍号'); const pages = document.querySelectorAll('.route-keeper-page'); expect(pages.length).toBe(2); const hidden = pages[1] as HTMLElement; expect(hidden.style.display).toBe('none'); }); });