/** * Smoke + behaviour test for the mini-player webview tree. The component * itself is mostly composition; the meaningful logic is the storage-event * cross-window state-sync handler. */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; // vi.mock factories run before module-level vars are initialized; route the // shared mocks through vi.hoisted() so the references resolve in time. const { themeRehydrate, fontRehydrate, keybindingsRehydrate } = vi.hoisted(() => ({ themeRehydrate: vi.fn(), fontRehydrate: vi.fn(), keybindingsRehydrate: vi.fn(), })); vi.mock('../store/themeStore', () => ({ useThemeStore: { persist: { rehydrate: themeRehydrate } }, })); vi.mock('../store/fontStore', () => ({ useFontStore: { persist: { rehydrate: fontRehydrate } }, })); vi.mock('../store/keybindingsStore', () => ({ useKeybindingsStore: { persist: { rehydrate: keybindingsRehydrate } }, })); vi.mock('../utils/perf/perfFlags', () => ({ usePerfProbeFlags: () => ({ disableTooltipPortal: true }), })); vi.mock('../i18n', () => ({ default: { changeLanguage: vi.fn() }, })); vi.mock('../components/MiniPlayer', () => ({ default: () =>
})); vi.mock('../components/GlobalConfirmModal', () => ({ default: () => })); vi.mock('../components/TooltipPortal', () => ({ default: () => })); vi.mock('../components/FpsOverlay', () => ({ default: () => })); vi.mock('../contexts/DragDropContext', () => ({ DragDropProvider: ({ children }: { children: React.ReactNode }) => <>{children}>, })); import { render, cleanup } from '@testing-library/react'; import MiniPlayerApp from './MiniPlayerApp'; import i18n from '../i18n'; beforeEach(() => { themeRehydrate.mockClear(); fontRehydrate.mockClear(); keybindingsRehydrate.mockClear(); vi.mocked(i18n.changeLanguage).mockClear(); }); afterEach(() => { cleanup(); }); function fireStorage(key: string | null, newValue: string | null = 'x'): void { // jsdom does not synthesize cross-tab storage events from setItem on the // same window — dispatch one manually. window.dispatchEvent(new StorageEvent('storage', { key: key ?? '', newValue: newValue ?? '' })); } describe('MiniPlayerApp', () => { it('renders the mini-player tree (smoke)', () => { const { getByTestId } = render(