import { test, expect, type Page } from '@playwright/test' import { executeCommand, openCommandPalette } from './helpers' type MockHandlers = Record unknown> type MockWindow = Window & { __markVaultMissing?: () => void } const entry = { path: '/vault/note/runtime.md', filename: 'runtime.md', title: 'Runtime Vault Note', isA: 'Note', aliases: [], belongsTo: [], relatedTo: [], status: null, archived: false, modifiedAt: 1700000000, createdAt: 1700000000, fileSize: 64, snippet: 'Loaded before the vault path disappears.', wordCount: 7, relationships: {}, icon: null, color: null, order: null, sidebarLabel: null, template: null, sort: null, view: null, visible: true, organized: false, favorite: false, favoriteIndex: null, listPropertiesDisplay: [], outgoingLinks: [], properties: {}, hasH1: true, fileKind: 'markdown', } async function installMissingVaultMock(page: Page): Promise { await page.addInitScript((noteEntry: typeof entry) => { localStorage.setItem('tolaria_welcome_dismissed', '1') localStorage.setItem('tolaria:ai-agents-onboarding-dismissed', '1') localStorage.setItem('tolaria:claude-code-onboarding-dismissed', '1') const missingError = () => new Error('Active vault is not available') const mockWindow = window as MockWindow let vaultAvailable = true let handlers: MockHandlers | null = null mockWindow.__markVaultMissing = () => { vaultAvailable = false } Object.defineProperty(window, '__mockHandlers', { configurable: true, set(value: unknown) { handlers = value as MockHandlers handlers.load_vault_list = () => ({ vaults: [{ label: 'Runtime Vault', path: '/vault' }], active_vault: '/vault', hidden_defaults: [], }) handlers.check_vault_exists = () => vaultAvailable handlers.get_default_vault_path = () => '/vault' handlers.get_settings = () => ({ auto_pull_interval_minutes: null, auto_advance_inbox_after_organize: null, telemetry_consent: true, crash_reporting_enabled: null, analytics_enabled: null, anonymous_id: null, release_channel: null, }) handlers.get_vault_settings = () => ({ theme: null }) handlers.list_vault = () => vaultAvailable ? [noteEntry] : Promise.reject(new Error('No such file or directory')) handlers.reload_vault = () => vaultAvailable ? [noteEntry] : Promise.reject(new Error('No such file or directory')) handlers.list_vault_folders = () => vaultAvailable ? [] : Promise.reject(missingError()) handlers.list_views = () => vaultAvailable ? [] : Promise.reject(missingError()) handlers.get_modified_files = () => vaultAvailable ? [] : Promise.reject(missingError()) handlers.get_all_content = () => ({ [noteEntry.path]: '# Runtime Vault Note\n\nBody.' }) handlers.get_note_content = () => vaultAvailable ? '# Runtime Vault Note\n\nBody.' : Promise.reject(missingError()) handlers.is_git_repo = () => true handlers.sync_mcp_bridge_vault = () => null }, get() { return handlers }, }) }, entry) } test('missing active vault reload shows recovery state and clears stale notes', async ({ page }) => { await installMissingVaultMock(page) await page.goto('/', { waitUntil: 'domcontentloaded' }) await expect(page.getByText('Runtime Vault Note')).toBeVisible({ timeout: 5_000 }) await page.evaluate(() => { (window as MockWindow).__markVaultMissing?.() }) await openCommandPalette(page) await executeCommand(page, 'Reload Vault') await expect(page.getByText('Vault not found')).toBeVisible({ timeout: 5_000 }) await expect(page.getByTestId('welcome-open-folder')).toContainText('Choose a different folder') await expect(page.getByText('Runtime Vault Note')).not.toBeVisible() })