From 760c9cc923a09432985f9ad5dbf16df6662b1b7e Mon Sep 17 00:00:00 2001 From: Luca Sacchi Ricciardi Date: Sat, 25 Apr 2026 16:00:46 +0200 Subject: [PATCH] test: add browser cache navigation check --- test_cache_navigation.js | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 test_cache_navigation.js diff --git a/test_cache_navigation.js b/test_cache_navigation.js new file mode 100644 index 0000000..0238ea9 --- /dev/null +++ b/test_cache_navigation.js @@ -0,0 +1,112 @@ +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; +}); \ No newline at end of file