import { type BrowserContext, type Page } from '@playwright/test'; const SERVER_ENDPOINTS_STORAGE_KEY = 'metoyou_server_endpoints'; const REMOVED_DEFAULT_KEYS_STORAGE_KEY = 'metoyou_removed_default_server_keys'; export interface SeededEndpointInput { id: string; name: string; url: string; isActive?: boolean; isDefault?: boolean; status?: string; } interface SeededEndpointStorageState { key: string; removedKey: string; endpoints: { id: string; name: string; url: string; isActive: boolean; isDefault: boolean; status: string; }[]; } function buildSeededEndpointStorageState( endpointsOrPort: readonly SeededEndpointInput[] | number = Number(process.env.TEST_SERVER_PORT) || 3099 ): SeededEndpointStorageState { const endpoints = Array.isArray(endpointsOrPort) ? endpointsOrPort.map((endpoint) => ({ id: endpoint.id, name: endpoint.name, url: endpoint.url, isActive: endpoint.isActive ?? true, isDefault: endpoint.isDefault ?? false, status: endpoint.status ?? 'unknown' })) : [ { id: 'e2e-test-server', name: 'E2E Test Server', url: `http://localhost:${endpointsOrPort}`, isActive: true, isDefault: false, status: 'unknown' } ]; return { key: SERVER_ENDPOINTS_STORAGE_KEY, removedKey: REMOVED_DEFAULT_KEYS_STORAGE_KEY, endpoints }; } function applySeededEndpointStorageState(storageState: SeededEndpointStorageState): void { try { const storage = window.localStorage; const currentUserId = storage.getItem('metoyou_currentUserId')?.trim() || null; const generalSettings = JSON.stringify({ reopenLastViewedChat: false }); storage.setItem(storageState.key, JSON.stringify(storageState.endpoints)); storage.setItem(storageState.removedKey, JSON.stringify([ 'default', 'toju-primary', 'toju-sweden' ])); storage.setItem('metoyou_general_settings', generalSettings); if (currentUserId) { storage.setItem(`metoyou_general_settings__${encodeURIComponent(currentUserId)}`, generalSettings); } const keysToRemove: string[] = []; for (let index = 0; index < storage.length; index += 1) { const key = storage.key(index); if (key === 'metoyou_lastViewedChat' || key?.startsWith('metoyou_lastViewedChat__')) { keysToRemove.push(key); } } for (const key of keysToRemove) { storage.removeItem(key); } } catch { // about:blank and some Playwright UI pages deny localStorage access. } } export async function disableLastViewedChatResume(page: Page): Promise { await page.evaluate(() => { const currentUserId = localStorage.getItem('metoyou_currentUserId')?.trim() || null; const generalSettings = JSON.stringify({ reopenLastViewedChat: false }); const keysToRemove: string[] = []; localStorage.setItem('metoyou_general_settings', generalSettings); if (currentUserId) { localStorage.setItem(`metoyou_general_settings__${encodeURIComponent(currentUserId)}`, generalSettings); } for (let index = 0; index < localStorage.length; index += 1) { const key = localStorage.key(index); if (key === 'metoyou_lastViewedChat' || key?.startsWith('metoyou_lastViewedChat__')) { keysToRemove.push(key); } } for (const key of keysToRemove) { localStorage.removeItem(key); } }); } export async function installTestServerEndpoint( context: BrowserContext, port: number = Number(process.env.TEST_SERVER_PORT) || 3099 ): Promise { const storageState = buildSeededEndpointStorageState(port); await context.addInitScript(applySeededEndpointStorageState, storageState); } export async function installTestServerEndpoints( context: BrowserContext, endpoints: readonly SeededEndpointInput[] ): Promise { const storageState = buildSeededEndpointStorageState(endpoints); await context.addInitScript(applySeededEndpointStorageState, storageState); } /** * Seed localStorage with a single signal endpoint pointing at the test server. * Must be called AFTER navigating to the app origin (localStorage is per-origin) * but BEFORE the app reads from storage (i.e. before the Angular bootstrap is * relied upon - calling it in the first goto() landing page is fine since the * page will re-read on next navigation/reload). * * Typical usage: * await page.goto('/'); * await seedTestServerEndpoint(page); * await page.reload(); // App now picks up the test endpoint */ export async function seedTestServerEndpoint( page: Page, port: number = Number(process.env.TEST_SERVER_PORT) || 3099 ): Promise { const storageState = buildSeededEndpointStorageState(port); await page.evaluate(applySeededEndpointStorageState, storageState); } export async function seedTestServerEndpoints( page: Page, endpoints: readonly SeededEndpointInput[] ): Promise { const storageState = buildSeededEndpointStorageState(endpoints); await page.evaluate(applySeededEndpointStorageState, storageState); }