test: integrate playwright cache navigation spec
This commit is contained in:
@@ -376,6 +376,9 @@ pytest tests/ -v
|
|||||||
# Test con coverage
|
# Test con coverage
|
||||||
pytest tests/ --cov=app
|
pytest tests/ --cov=app
|
||||||
|
|
||||||
|
# Browser E2E test (cache-first navigation)
|
||||||
|
OLLAMA_HOST=http://192.168.254.115:11434 npm run test:e2e
|
||||||
|
|
||||||
# Hot reload durante sviluppo
|
# Hot reload durante sviluppo
|
||||||
uvicorn main:app --reload
|
uvicorn main:app --reload
|
||||||
```
|
```
|
||||||
|
|||||||
+4
-1
@@ -1,13 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "llm-monitor",
|
"name": "llm-monitor",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
"type": "commonjs",
|
||||||
"description": "Dashboard per controllare i modelli caricati in Ollama",
|
"description": "Dashboard per controllare i modelli caricati in Ollama",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tailwind:dev": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css --watch",
|
"tailwind:dev": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css --watch",
|
||||||
"tailwind:build": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css"
|
"tailwind:build": "tailwindcss -i ./app/web/static/css/input.css -o ./app/web/static/css/output.css",
|
||||||
|
"test:e2e": "playwright test tests/e2e/cache-navigation.spec.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@playwright/test": "^1.59.1",
|
||||||
"tailwindcss": "^3.4.0"
|
"tailwindcss": "^3.4.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const { defineConfig } = require('@playwright/test');
|
||||||
|
|
||||||
|
const baseURL = process.env.TARGET_URL || 'http://127.0.0.1:8011';
|
||||||
|
|
||||||
|
module.exports = defineConfig({
|
||||||
|
testDir: './tests/e2e',
|
||||||
|
timeout: 45000,
|
||||||
|
fullyParallel: false,
|
||||||
|
retries: 0,
|
||||||
|
reporter: 'list',
|
||||||
|
use: {
|
||||||
|
baseURL,
|
||||||
|
headless: true,
|
||||||
|
serviceWorkers: 'block'
|
||||||
|
},
|
||||||
|
webServer: {
|
||||||
|
command: 'python3 -m uvicorn main:app --host 127.0.0.1 --port 8011',
|
||||||
|
url: baseURL,
|
||||||
|
reuseExistingServer: true,
|
||||||
|
timeout: 30000
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
const { test, expect } = require('@playwright/test');
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
test.describe('cache-first server navigation', () => {
|
||||||
|
test.beforeEach(async ({ 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
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('serves cached data when navigating between running and available pages', async ({ context, page }) => {
|
||||||
|
const apiRequests = [];
|
||||||
|
|
||||||
|
context.on('request', (request) => {
|
||||||
|
const url = new URL(request.url());
|
||||||
|
if (url.pathname.startsWith('/api/v1/')) {
|
||||||
|
apiRequests.push(url.pathname + url.search);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const resetApiRequests = () => {
|
||||||
|
apiRequests.length = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const waitForQuietWindow = async (label) => {
|
||||||
|
await page.waitForTimeout(QUIET_WINDOW_MS);
|
||||||
|
expect(apiRequests, `${label} should not issue API requests while cache is fresh`).toEqual([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
await page.goto(`/models-running?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' });
|
||||||
|
|
||||||
|
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 }
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(apiRequests.length).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
resetApiRequests();
|
||||||
|
await page.goto(`/models-available?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' });
|
||||||
|
await waitForQuietWindow('running -> available');
|
||||||
|
|
||||||
|
resetApiRequests();
|
||||||
|
await page.goto(`/models-running?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' });
|
||||||
|
await waitForQuietWindow('available -> running');
|
||||||
|
|
||||||
|
resetApiRequests();
|
||||||
|
await page.goto(`/models-available?server=${SERVER_ID}`, { waitUntil: 'domcontentloaded' });
|
||||||
|
await waitForQuietWindow('running -> available again');
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user