From c217860ebc4d25e6500ec0a10fdc18e9379b6209 Mon Sep 17 00:00:00 2001 From: Luca Sacchi Ricciardi Date: Sat, 25 Apr 2026 18:04:43 +0200 Subject: [PATCH] chore: rimuovi artefatti obsoleti e aggiungi test-results/ a .gitignore --- .gitignore | 3 +- package-test.json | 8 --- test_cache_navigation.js | 112 ----------------------------- test_modal_click.js | 147 --------------------------------------- test_modal_click.py | 142 ------------------------------------- 5 files changed, 2 insertions(+), 410 deletions(-) delete mode 100644 package-test.json delete mode 100644 test_cache_navigation.js delete mode 100644 test_modal_click.js delete mode 100644 test_modal_click.py diff --git a/.gitignore b/.gitignore index d296427..49cc3ec 100644 --- a/.gitignore +++ b/.gitignore @@ -134,7 +134,8 @@ node_modules/ package-lock.json # Build outputs - +test-results/ +playwright-report/ # Database *.db diff --git a/package-test.json b/package-test.json deleted file mode 100644 index 3a1b011..0000000 --- a/package-test.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "llm-monitor-test", - "version": "1.0.0", - "type": "commonjs", - "dependencies": { - "playwright": "^1.59.1" - } -} diff --git a/test_cache_navigation.js b/test_cache_navigation.js deleted file mode 100644 index 0238ea9..0000000 --- a/test_cache_navigation.js +++ /dev/null @@ -1,112 +0,0 @@ -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 diff --git a/test_modal_click.js b/test_modal_click.js deleted file mode 100644 index 5a2bdb5..0000000 --- a/test_modal_click.js +++ /dev/null @@ -1,147 +0,0 @@ -// test_modal_click.js -// Playwright test to debug modal click functionality - -const { chromium } = require('playwright'); - -const TARGET_URL = 'http://192.168.254.12:8000'; - -(async () => { - const browser = await chromium.launch({ headless: true }); - const context = await browser.newContext(); - const page = await context.newPage(); - - // Log console messages - page.on('console', msg => console.log(`[CONSOLE] ${msg.type()}: ${msg.text()}`)); - page.on('pageerror', exc => console.log(`[PAGE ERROR] ${exc.message}`)); - - try { - console.log(`\nšŸ” [TEST] Navigating to ${TARGET_URL}...`); - await page.goto(TARGET_URL, { waitUntil: 'networkidle' }); - console.log('āœ… Page loaded'); - - console.log('[WAIT] Waiting for models container to populate...'); - try { - await page.waitForSelector('[data-model-key]', { timeout: 5000 }); - console.log('āœ… [SUCCESS] Models loaded - found cards with data-model-key attribute'); - } catch (e) { - console.log(`āŒ [FAILURE] No models found: ${e.message}`); - const content = await page.content(); - console.log('\nšŸ“‹ Page content (first 1000 chars):'); - console.log(content.substring(0, 1000)); - await browser.close(); - return; - } - - // Get all model cards - const cards = await page.locator('[data-model-key]').all(); - console.log(`\nšŸ“Š Found ${cards.length} model cards`); - - if (cards.length === 0) { - console.log('āŒ No cards found'); - await browser.close(); - return; - } - - // Get first card info - const firstCard = cards[0]; - const modelKey = await firstCard.getAttribute('data-model-key'); - console.log(`\nšŸŽÆ [TARGET] First card data-model-key: ${modelKey}`); - - // Get modal state BEFORE click - const modalElement = page.locator('#model-details-modal'); - const modalExists = await modalElement.count() > 0; - - if (!modalExists) { - console.log('\nāŒ [ERROR] Modal element #model-details-modal not found!'); - await browser.close(); - return; - } - - const classAttributeBefore = await modalElement.getAttribute('class'); - const isHiddenBefore = classAttributeBefore && classAttributeBefore.includes('hidden'); - - console.log(`\nšŸ“ [BEFORE CLICK] Modal HTML class: '${classAttributeBefore}'`); - console.log(` Is hidden: ${isHiddenBefore}`); - - // Check if app is initialized - const appExists = await page.evaluate(() => typeof window.llmMonitorApp !== 'undefined'); - console.log(` App initialized: ${appExists}`); - - // Check localStorage - const localStorage = await page.evaluate(() => JSON.stringify(Object.fromEntries(Object.entries(window.localStorage)))); - const lsData = JSON.parse(localStorage); - console.log(` localStorage keys: ${Object.keys(lsData).join(', ')}`); - - // PERFORM CLICK - console.log(`\nšŸ–±ļø [CLICK] Clicking on model card...`); - await firstCard.click(); - - // Brief pause for DOM update - await page.waitForTimeout(500); - - // Get modal state AFTER click - const classAttributeAfter = await modalElement.getAttribute('class'); - const isHiddenAfter = classAttributeAfter && classAttributeAfter.includes('hidden'); - - console.log(`\nšŸ“ [AFTER CLICK] Modal HTML class: '${classAttributeAfter}'`); - console.log(` Is hidden: ${isHiddenAfter}`); - - // Evaluate if modal is visible - const modalState = await page.evaluate(() => { - const modal = document.getElementById('model-details-modal'); - if (!modal) return 'NOT_FOUND'; - const isHidden = modal.classList.contains('hidden'); - const computedStyle = window.getComputedStyle(modal); - return { - hasHiddenClass: isHidden, - display: computedStyle.display, - visibility: computedStyle.visibility, - opacity: computedStyle.opacity, - zIndex: computedStyle.zIndex - }; - }); - - console.log(`\nšŸ’» [DOM CHECK] Modal computed state:`); - console.log(JSON.stringify(modalState, null, 3)); - - // Check for event listeners and app methods - const appState = await page.evaluate(() => { - const card = document.querySelector('[data-model-key]'); - if (!card) return 'NO_CARDS'; - - if (window.llmMonitorApp && typeof window.llmMonitorApp.showModelDetails === 'function') { - return 'APP_METHOD_EXISTS'; - } - return 'NO_APP_METHOD'; - }); - - console.log(`\nšŸ”— [LISTENERS] Event handler state: ${appState}`); - - // Take screenshot - const screenshotPath = '/tmp/modal-test-after-click.png'; - await page.screenshot({ path: screenshotPath }); - console.log(`\nšŸ“ø Screenshot saved: ${screenshotPath}`); - - // Final verdict - console.log('\n' + '='.repeat(70)); - if (isHiddenBefore !== undefined && isHiddenAfter !== undefined) { - if (isHiddenBefore && !isHiddenAfter) { - console.log('āœ… [PASS] Modal successfully opened on click!'); - } else if (isHiddenBefore && isHiddenAfter) { - console.log('āŒ [FAIL] Modal still has "hidden" class after click'); - console.log(' → Event handler may not be attached'); - console.log(' → app.js may not be loaded/initialized'); - } else { - console.log('āš ļø [UNCLEAR] Unexpected modal state'); - } - } else { - console.log('āŒ [ERROR] Could not compare modal states'); - } - console.log('='.repeat(70)); - - } catch (error) { - console.error('Test error:', error.message); - } finally { - await browser.close(); - } -})(); diff --git a/test_modal_click.py b/test_modal_click.py deleted file mode 100644 index d54a4f1..0000000 --- a/test_modal_click.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python3 -""" -Playwright test to debug modal click functionality on live LLM Monitor instance -""" -import asyncio -import json -from playwright.async_api import async_playwright - -TARGET_URL = "http://192.168.254.12:8000" - -async def test_modal_click(): - async with async_playwright() as p: - browser = await p.chromium.launch(headless=True) - context = await browser.new_context() - page = await context.new_page() - - # Enable console logging - page.on("console", lambda msg: print(f"[CONSOLE] {msg.type}: {msg.text}")) - page.on("pageerror", lambda exc: print(f"[PAGE ERROR] {exc}")) - - print(f"\nšŸ” [TEST] Navigating to {TARGET_URL}...") - await page.goto(TARGET_URL, wait_until="networkidle") - - # Wait for models to load - print("[WAIT] Waiting for models container to populate...") - try: - await page.wait_for_selector("[data-model-key]", timeout=5000) - print("āœ… [SUCCESS] Models loaded - found cards with data-model-key attribute") - except Exception as e: - print(f"āŒ [FAILURE] No models found: {e}") - print("\nšŸ“‹ Page content:") - content = await page.content() - print(content[:2000]) - await browser.close() - return - - # Get all model cards - cards = await page.query_selector_all("[data-model-key]") - print(f"\nšŸ“Š Found {len(cards)} model cards") - - if len(cards) == 0: - print("āŒ No cards found after waiting") - await browser.close() - return - - # Get first card info - first_card = cards[0] - model_key = await first_card.get_attribute("data-model-key") - print(f"\nšŸŽÆ [TARGET] First card data-model-key: {model_key}") - - # Get modal state BEFORE click - modal_before = await page.query_selector("#model-details-modal") - if modal_before: - hidden_class_before = await modal_before.get_attribute("class") - is_hidden_before = "hidden" in (hidden_class_before or "") - print(f"\nšŸ“ [BEFORE CLICK] Modal HTML class: '{hidden_class_before}'") - print(f" Is hidden: {is_hidden_before}") - else: - print("\nāŒ [ERROR] Modal element #model-details-modal not found!") - - # Check if app is initialized - app_exists = await page.evaluate("typeof window.llmMonitorApp !== 'undefined'") - print(f" App initialized: {app_exists}") - - # Check localStorage - localStorage = await page.evaluate("JSON.stringify(localStorage)") - print(f" localStorage keys: {list(json.loads(localStorage).keys())}") - - # PERFORM CLICK - print(f"\nšŸ–±ļø [CLICK] Clicking on model card...") - await first_card.click() - - # Brief pause for DOM update - await page.wait_for_timeout(500) - - # Get modal state AFTER click - modal_after = await page.query_selector("#model-details-modal") - if modal_after: - hidden_class_after = await modal_after.get_attribute("class") - is_hidden_after = "hidden" in (hidden_class_after or "") - print(f"\nšŸ“ [AFTER CLICK] Modal HTML class: '{hidden_class_after}'") - print(f" Is hidden: {is_hidden_after}") - else: - print("\nāŒ [ERROR] Modal element #model-details-modal not found after click!") - - # Evaluate if modal is visible - is_visible = await page.evaluate(""" - () => { - const modal = document.getElementById('model-details-modal'); - if (!modal) return 'NOT_FOUND'; - const isHidden = modal.classList.contains('hidden'); - const computedStyle = window.getComputedStyle(modal); - return { - hasHiddenClass: isHidden, - display: computedStyle.display, - visibility: computedStyle.visibility, - opacity: computedStyle.opacity, - zIndex: computedStyle.zIndex - }; - } - """) - print(f"\nšŸ’» [DOM CHECK] Modal computed state:\n {json.dumps(is_visible, indent=3)}") - - # Check for event listeners - listeners = await page.evaluate(""" - () => { - const card = document.querySelector('[data-model-key]'); - if (!card) return 'NO_CARDS'; - - // Try to trigger click manually via app if it exists - if (window.llmMonitorApp && typeof window.llmMonitorApp.showModelDetails === 'function') { - return 'APP_METHOD_EXISTS'; - } - return 'NO_APP_METHOD'; - } - """) - print(f"\nšŸ”— [LISTENERS] Event handler state: {listeners}") - - # Take screenshot - screenshot_path = "/tmp/modal-test-after-click.png" - await page.screenshot(path=screenshot_path) - print(f"\nšŸ“ø Screenshot saved: {screenshot_path}") - - # Final verdict - print("\n" + "="*70) - if hidden_class_before is not None and hidden_class_after is not None: - if is_hidden_before and not is_hidden_after: - print("āœ… [PASS] Modal successfully opened on click!") - elif is_hidden_before and is_hidden_after: - print("āŒ [FAIL] Modal still has 'hidden' class after click") - print(" → Event handler may not be attached") - print(" → app.js may not be loaded/initialized") - else: - print("āš ļø [UNCLEAR] Unexpected modal state") - else: - print("āŒ [ERROR] Could not compare modal states") - print("="*70) - - await browser.close() - -if __name__ == "__main__": - asyncio.run(test_modal_click())