// @vitest-environment jsdom import { mount } from '@vue/test-utils' import { beforeEach, describe, expect, it, vi } from 'vitest' const routeMock = vi.hoisted(() => ({ name: 'hermes.chat' as string })) const appStoreMock = vi.hoisted(() => ({ nodeVersion: '23.0.0', sidebarOpen: true, toggleSidebar: vi.fn(), closeSidebar: vi.fn(), loadModels: vi.fn(), startHealthPolling: vi.fn(), stopHealthPolling: vi.fn(), })) vi.mock('vue-router', async (importOriginal) => { const actual = await importOriginal() return { ...actual, useRoute: () => routeMock, } }) vi.mock('vue-i18n', () => ({ useI18n: () => ({ t: (key: string, params?: Record) => params?.version ? `${key}:${params.version}` : key, }), })) vi.mock('@/composables/useTheme', () => ({ useTheme: () => ({ isDark: false, isComic: false }), })) vi.mock('@/composables/useKeyboard', () => ({ useKeyboard: vi.fn(), })) vi.mock('@/stores/hermes/app', () => ({ useAppStore: () => appStoreMock, })) vi.mock('@/styles/theme', () => ({ getThemeOverrides: () => ({}), })) vi.mock('@/components/hermes/pets/WebPet.vue', () => ({ default: { name: 'WebPet', template: '
' }, })) vi.mock('@/components/auth/AuthEventListener.vue', () => ({ default: { name: 'AuthEventListener', template: '
' }, })) vi.mock('@/components/auth/DefaultCredentialPrompt.vue', () => ({ default: { name: 'DefaultCredentialPrompt', template: '
' }, })) vi.mock('@/components/hermes/chat/SessionSearchModal.vue', () => ({ default: { name: 'SessionSearchModal', template: '
' }, })) vi.mock('@/components/layout/AppSidebar.vue', () => ({ default: { name: 'AppSidebar', template: '