const { chromium } = require('playwright'); const TARGET_URL = process.env.TARGET_URL || 'http://127.0.0.1:8001'; const OLLAMA_HOST = process.env.OLLAMA_HOST || 'http://192.168.254.115:11434'; const SERVER_ID = process.env.TEST_SERVER_ID || 'srv_e2e_cache'; const SERVER_NAME = process.env.TEST_SERVER_NAME || 'E2E Cache Server'; const QUIET_WINDOW_MS = Number(process.env.QUIET_WINDOW_MS || 1500); const CACHE_WAIT_TIMEOUT_MS = Number(process.env.CACHE_WAIT_TIMEOUT_MS || 20000); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } async function waitForCache(page) { await page.waitForFunction( (serverId) => { return ['health', 'models', 'running'].every((suffix) => { return Boolean(localStorage.getItem(`llm_monitor_${suffix}_${serverId}`)); }); }, SERVER_ID, { timeout: CACHE_WAIT_TIMEOUT_MS } ); } async function configureServer(page) { await page.addInitScript( ({ serverId, serverName, host }) => { localStorage.setItem( 'llm_monitor_servers', JSON.stringify([ { id: serverId, name: serverName, host } ]) ); localStorage.setItem('llm_monitor_active_server', serverId); }, { serverId: SERVER_ID, serverName: SERVER_NAME, host: OLLAMA_HOST } ); } async function main() { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext({ serviceWorkers: 'block' }); const page = await context.newPage(); const apiRequests = []; context.on('request', (request) => { const url = new URL(request.url()); if (url.pathname.startsWith('/api/v1/')) { apiRequests.push(url.pathname + url.search); } }); page.on('console', (msg) => console.log(`[console:${msg.type()}] ${msg.text()}`)); page.on('pageerror', (error) => console.log(`[pageerror] ${error.message}`)); const resetApiRequests = () => { apiRequests.length = 0; }; const expectNoApiRequests = async (label) => { await sleep(QUIET_WINDOW_MS); if (apiRequests.length > 0) { throw new Error(`${label}: expected no API requests, got ${apiRequests.length} -> ${apiRequests.join(', ')}`); } console.log(`PASS ${label}: no API requests during ${QUIET_WINDOW_MS}ms quiet window`); }; try { await configureServer(page); console.log(`Opening first page at ${TARGET_URL}/models-running?server=${SERVER_ID}`); await page.goto(`${TARGET_URL}/models-running?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' }); await waitForCache(page); if (apiRequests.length === 0) { throw new Error('Initial page load did not perform any API requests, cache warmup could not be verified'); } console.log(`PASS initial load warmed cache with ${apiRequests.length} API requests`); resetApiRequests(); await page.goto(`${TARGET_URL}/models-available?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' }); await expectNoApiRequests('navigate running -> available'); resetApiRequests(); await page.goto(`${TARGET_URL}/models-running?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' }); await expectNoApiRequests('navigate available -> running'); resetApiRequests(); await page.goto(`${TARGET_URL}/models-available?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' }); await expectNoApiRequests('navigate running -> available again'); console.log('PASS cache-first navigation test completed successfully'); } finally { await context.close(); await browser.close(); } } main().catch((error) => { console.error(`FAIL ${error.message}`); process.exitCode = 1; });