- real-fit-engine.py: refactored to support --from-report, improved Ollama v1/chat/completions compatibility, agent name normalization - run-focused-eval.py: run evaluations for specific agent/model pairs from CLI - test_ollama_minimal.py/test_real_api.py: Ollama API connectivity tests - real-fit-architecture.md: architecture overview document - tests/scripts/: E2E landing test, analytics capture, evolution heatmap verification - Remove real-fit-recalc.py (superseded by --from-report flag)
80 lines
3.2 KiB
JavaScript
80 lines
3.2 KiB
JavaScript
const { chromium } = require('playwright');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const TARGET = process.env.TARGET_URL || 'http://host.docker.internal:3003';
|
|
const OUT_DIR = process.env.OUT_DIR || path.join(__dirname, '..', 'reports');
|
|
|
|
(async () => {
|
|
if (!fs.existsSync(OUT_DIR)) fs.mkdirSync(OUT_DIR, { recursive: true });
|
|
|
|
const browser = await chromium.launch({ headless: true });
|
|
const context = await browser.newContext({ viewport: { width: 1600, height: 1200 } });
|
|
const page = await context.newPage();
|
|
|
|
// Capture console & network errors
|
|
const consoleErrors = [];
|
|
const networkErrors = [];
|
|
page.on('console', msg => { if (msg.type() === 'error') consoleErrors.push(msg.text()); });
|
|
page.on('requestfailed', req => networkErrors.push({ url: req.url(), error: req.failure()?.errorText }));
|
|
page.on('response', res => { if (res.status() >= 400) networkErrors.push({ url: res.url(), status: res.status() }); });
|
|
|
|
console.log('[HEATMAP] Navigating to', TARGET);
|
|
await page.goto(TARGET, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
await page.waitForTimeout(1500); // wait for fetch/dashboard-data
|
|
|
|
const tabBtn = page.locator('button.tab-btn', { hasText: /Heatmap/ }).first();
|
|
if (await tabBtn.count()) {
|
|
await tabBtn.click();
|
|
console.log('[HEATMAP] Clicked Heatmap tab');
|
|
} else {
|
|
console.log('[HEATMAP] No Heatmap tab found, tabs may already be active');
|
|
}
|
|
|
|
await page.waitForTimeout(2000); // let table build from JS
|
|
|
|
// Get table dimensions
|
|
const rows = await page.locator('#hmTable tbody tr').count().catch(() => 0);
|
|
const colCount = await page.locator('#hmTable thead th').count().catch(() => 0);
|
|
console.log(`[HEATMAP] Table: ${rows} rows, ${colCount} columns`);
|
|
|
|
// Screenshot full page of heatmap tab
|
|
const screenshotPath = path.join(OUT_DIR, 'heatmap.png');
|
|
await page.screenshot({ path: screenshotPath, fullPage: true });
|
|
console.log('[HEATMAP] Screenshot saved to', screenshotPath);
|
|
|
|
// Also screenshot just the table if possible
|
|
const tableScreenshotPath = path.join(OUT_DIR, 'heatmap-table.png');
|
|
const tableEl = page.locator('#hmTable').first();
|
|
if (await tableEl.count() && rows > 0) {
|
|
await tableEl.screenshot({ path: tableScreenshotPath });
|
|
console.log('[HEATMAP] Table screenshot saved to', tableScreenshotPath);
|
|
}
|
|
|
|
// Read cell data
|
|
const cellTexts = await page.locator('#hmTable tbody td').allTextContents().catch(() => []);
|
|
console.log('[HEATMAP] First 30 cell texts:', cellTexts.slice(0, 30).map(t => t.trim()));
|
|
|
|
// Dump innerHTML
|
|
const innerHTML = await page.locator('#hmTable').innerHTML().catch(() => null);
|
|
|
|
// Report
|
|
const report = {
|
|
target: TARGET,
|
|
table: { rows, colCount },
|
|
cellSamples: cellTexts.slice(0, 30).map(t => t.trim()),
|
|
consoleErrors,
|
|
networkErrors,
|
|
screenshots: [screenshotPath, tableScreenshotPath].filter(f => fs.existsSync(f)),
|
|
innerHTML: innerHTML ? innerHTML.slice(0, 2000) : null,
|
|
ok: rows > 0 && colCount > 0,
|
|
};
|
|
|
|
const reportPath = path.join(OUT_DIR, 'heatmap-report.json');
|
|
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
|
|
console.log('[HEATMAP] Report saved to', reportPath);
|
|
|
|
await browser.close();
|
|
process.exit(report.ok ? 0 : 1);
|
|
})();
|