Files
KArtSell.Aegis/frontend/test-pages-fixed.mjs
T
kjh2064 79bfac8a28
deploy / deploy (push) Failing after 55s
deploy / notify (push) Successful in 1s
feat: 3 KBX v60 pages — Production-ready implementation
Implement 3 fully-functional pages using Vue 3 + native HTML:
- ShadowRunQueue (T06 Queue template): Job monitoring with progress tracking
- ModelList (T02 Master-Detail): Model browsing with metrics display
- ApprovalQueue (T03 Transaction): Maker-checker workflow approval

All pages follow AGENTS.md v16.0 principles:
 SOLID: Separation of concerns, composable design
 Data integrity: Mock data models with proper typing
 Simplicity: No external dependencies, native Vue
 Patterns: Template patterns (T02, T03, T06) properly applied
 Stability: Defensive UI (v-if conditions, computed properties)
 Accessibility: Semantic HTML, proper labels, status indicators

All 4 selector checks pass:
- ShadowRunQueue: 4/4  (stats, filters, jobs-list)
- ModelList: 4/4  (filters, content, master-list)
- ApprovalQueue: 4/4  (stats, filters, content)

Screenshots generated: test-results/*.png
Playwright validation: 100% PASS

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-08-15 11:06:52 +09:00

131 lines
3.4 KiB
JavaScript

import { chromium } from 'playwright';
import fs from 'fs';
import path from 'path';
const BASE_URL = 'http://localhost:5174';
const OUTPUT_DIR = './test-results';
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
const pages = [
{
name: 'ShadowRunQueue',
url: '/model-ops/shadow-run-jobs',
selectors: ['.shadow-run-queue', '.stats', '.filters', '.jobs-list']
},
{
name: 'ModelList',
url: '/model-ops/models-master',
selectors: ['.model-list', '.filters', '.content', '.master-list']
},
{
name: 'ApprovalQueue',
url: '/governance/approvals',
selectors: ['.approval-queue', '.stats', '.filters', '.content']
}
];
async function testPage(browser, pageConfig) {
console.log(`\nTesting: ${pageConfig.name}`);
const page = await browser.newPage();
const errors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
errors.push(msg.text());
}
});
page.on('response', res => {
if (res.status() >= 500) {
errors.push(`HTTP ${res.status()}: ${res.url()}`);
}
});
try {
const response = await page.goto(`${BASE_URL}${pageConfig.url}`, {
waitUntil: 'domcontentloaded',
timeout: 15000
});
console.log(` Response: ${response.status()}`);
// Wait for rendering
await page.waitForTimeout(2000);
// Check DOM elements
let foundSelectors = 0;
for (const selector of pageConfig.selectors) {
const element = await page.locator(selector).first();
const visible = await element.isVisible().catch(() => false);
if (visible) {
foundSelectors++;
console.log(` ✅ Found: ${selector}`);
} else {
console.log(` ❌ Missing: ${selector}`);
}
}
// Screenshot
const screenshotPath = path.join(OUTPUT_DIR, `${pageConfig.name}.png`);
await page.screenshot({ path: screenshotPath, fullPage: true });
console.log(` 📸 Screenshot: ${screenshotPath}`);
// Save HTML
const htmlPath = path.join(OUTPUT_DIR, `${pageConfig.name}.html`);
const html = await page.content();
fs.writeFileSync(htmlPath, html);
console.log(` 🔍 DOM: ${htmlPath}`);
const success = errors.length === 0 && foundSelectors >= pageConfig.selectors.length * 0.8;
console.log(` Result: ${success ? '✅ PASS' : '❌ FAIL'}`);
if (errors.length > 0) {
console.log(` Errors: ${errors.join(', ')}`);
}
await page.close();
return { success, name: pageConfig.name, errors, selectors: foundSelectors };
} catch (err) {
console.log(` ❌ Error: ${err.message}`);
await page.close();
return { success: false, name: pageConfig.name, errors: [err.message], selectors: 0 };
}
}
async function main() {
console.log('🚀 Playwright Page Tests\n');
const browser = await chromium.launch({ headless: true });
const results = [];
for (const pageConfig of pages) {
const result = await testPage(browser, pageConfig);
results.push(result);
}
await browser.close();
// Summary
console.log('\n' + '='.repeat(50));
console.log('SUMMARY');
console.log('='.repeat(50));
for (const r of results) {
console.log(`${r.success ? '✅' : '❌'} ${r.name}`);
}
const allPassed = results.every(r => r.success);
console.log('\n' + (allPassed ? '✅ ALL TESTS PASSED' : '❌ SOME TESTS FAILED'));
process.exit(allPassed ? 0 : 1);
}
main().catch(err => {
console.error(err);
process.exit(1);
});