lilith-platform.live/codebase/@features/landing/frontend-public/audit-simple.mjs
2026-05-15 22:34:34 -07:00

310 lines
11 KiB
JavaScript

import { chromium } from '@playwright/test';
async function audit() {
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext();
const page = await context.newPage();
const results = {
homepage: {},
providers: {},
clients: {},
shop: {},
terms: {},
privacy: {},
seoRoute: {},
favicon: {}
};
// Capture console messages
const consoleMessages = [];
page.on('console', (msg) => {
consoleMessages.push(`[${msg.type()}] ${msg.text()}`);
});
// Capture errors
const pageErrors = [];
page.on('pageerror', (error) => {
pageErrors.push(error.message);
});
console.log('=== AUDIT START ===\n');
// 1. Homepage
console.log('Testing: Homepage (http://www.atlilith.lan/)');
try {
await page.goto('http://www.atlilith.lan/', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-homepage.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
results.homepage = { status: 'OK', title, bodyLength: bodyText.length };
console.log(` ✓ Status: OK | Title: "${title}" | Body length: ${bodyText.length}\n`);
} catch (e) {
results.homepage = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 2. /providers - Check for translation keys
console.log('Testing: /providers (P0 Issue #1 - i18n)');
consoleMessages.length = 0;
pageErrors.length = 0;
try {
await page.goto('http://www.atlilith.lan/providers', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-providers.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
const hasTranslationKeys = bodyText.includes('forWorkers.') ||
bodyText.match(/\w+\.title/) ||
bodyText.match(/\w+\.description/);
const hasI18nError = consoleMessages.some(m => m.includes('i18next::translator: missingKey'));
results.providers = {
status: hasTranslationKeys || hasI18nError ? 'BROKEN' : 'FIXED',
title,
hasTranslationKeys,
hasI18nError,
bodyLength: bodyText.length
};
if (hasTranslationKeys || hasI18nError) {
console.log(` ✗ STILL BROKEN: Translation keys visible or i18n errors`);
console.log(` Title: "${title}"`);
console.log(` Has translation keys: ${hasTranslationKeys}`);
console.log(` Has i18n errors: ${hasI18nError}\n`);
} else {
console.log(` ✓ FIXED: No translation keys detected`);
console.log(` Title: "${title}"\n`);
}
} catch (e) {
results.providers = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 3. /clients - Check for translation keys
console.log('Testing: /clients (P0 Issue #1 - i18n)');
consoleMessages.length = 0;
pageErrors.length = 0;
try {
await page.goto('http://www.atlilith.lan/clients', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-clients.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
const hasTranslationKeys = bodyText.includes('forClients.') ||
bodyText.match(/\w+\.title/) ||
bodyText.match(/\w+\.description/);
results.clients = {
status: hasTranslationKeys ? 'BROKEN' : 'FIXED',
title,
hasTranslationKeys,
bodyLength: bodyText.length
};
if (hasTranslationKeys) {
console.log(` ✗ STILL BROKEN: Translation keys visible`);
console.log(` Title: "${title}"\n`);
} else {
console.log(` ✓ FIXED: No translation keys detected`);
console.log(` Title: "${title}"\n`);
}
} catch (e) {
results.clients = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 4. /shop - Check for translation keys
console.log('Testing: /shop (P0 Issue #1 - i18n)');
try {
await page.goto('http://www.atlilith.lan/shop', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-shop.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
const hasTranslationKeys = bodyText.includes('shop.') ||
bodyText.match(/\w+\.title/) ||
bodyText.match(/\w+\.description/);
results.shop = {
status: hasTranslationKeys ? 'BROKEN' : 'FIXED',
title,
hasTranslationKeys,
bodyLength: bodyText.length
};
if (hasTranslationKeys) {
console.log(` ✗ STILL BROKEN: Translation keys visible`);
console.log(` Title: "${title}"\n`);
} else {
console.log(` ✓ FIXED: No translation keys detected`);
console.log(` Title: "${title}"\n`);
}
} catch (e) {
results.shop = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 5. /company/terms - Check for crash
console.log('Testing: /company/terms (P0 Issue #2 - Page crash)');
pageErrors.length = 0;
try {
await page.goto('http://www.atlilith.lan/company/terms', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-terms.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
const hasCrash = pageErrors.some(e => e.includes('accountItems.map'));
results.terms = {
status: hasCrash ? 'BROKEN' : 'FIXED',
title,
hasCrash,
bodyLength: bodyText.length,
errors: pageErrors
};
if (hasCrash) {
console.log(` ✗ STILL BROKEN: Page crashed with accountItems.map error`);
console.log(` Errors: ${pageErrors.join(', ')}\n`);
} else if (bodyText.length > 100) {
console.log(` ✓ FIXED: Page loaded successfully`);
console.log(` Title: "${title}"`);
console.log(` Body length: ${bodyText.length}\n`);
} else {
console.log(` ⚠ NEW ISSUE: Page loaded but minimal content`);
console.log(` Body length: ${bodyText.length}\n`);
}
} catch (e) {
results.terms = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 6. /company/privacy - Check for crash
console.log('Testing: /company/privacy (P0 Issue #3 - Page crash)');
pageErrors.length = 0;
try {
await page.goto('http://www.atlilith.lan/company/privacy', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-privacy.png', fullPage: false });
const title = await page.title();
const bodyText = (await page.locator('body').textContent()) || '';
const hasCrash = pageErrors.some(e => e.includes('locationItems.map'));
results.privacy = {
status: hasCrash ? 'BROKEN' : 'FIXED',
title,
hasCrash,
bodyLength: bodyText.length,
errors: pageErrors
};
if (hasCrash) {
console.log(` ✗ STILL BROKEN: Page crashed with locationItems.map error`);
console.log(` Errors: ${pageErrors.join(', ')}\n`);
} else if (bodyText.length > 100) {
console.log(` ✓ FIXED: Page loaded successfully`);
console.log(` Title: "${title}"`);
console.log(` Body length: ${bodyText.length}\n`);
} else {
console.log(` ⚠ NEW ISSUE: Page loaded but minimal content`);
console.log(` Body length: ${bodyText.length}\n`);
}
} catch (e) {
results.privacy = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 7. /_/en/ - SEO route (P1 Issue #6)
console.log('Testing: /_/en/ (P1 Issue #6 - SEO route)');
try {
const response = await page.goto('http://www.atlilith.lan/_/en/', { waitUntil: 'networkidle', timeout: 30000 });
await page.screenshot({ path: '/tmp/audit-seo.png', fullPage: false });
const status = response?.status();
const bodyText = (await page.locator('body').textContent()) || '';
results.seoRoute = {
status: status === 502 ? 'BROKEN' : 'FIXED',
httpStatus: status,
bodyLength: bodyText.length
};
if (status === 502) {
console.log(` ✗ STILL BROKEN: Returns 502 Bad Gateway\n`);
} else if (status === 200) {
console.log(` ✓ FIXED: Returns 200 with content`);
console.log(` Body length: ${bodyText.length}\n`);
} else {
console.log(` ⚠ NEW ISSUE: Unexpected status ${status}\n`);
}
} catch (e) {
results.seoRoute = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 8. Check page title on /providers (P1 Issue #7)
console.log('Testing: Page titles (P1 Issue #7)');
try {
await page.goto('http://www.atlilith.lan/providers', { waitUntil: 'networkidle', timeout: 30000 });
const title = await page.title();
const hasTitleKeys = title.includes('.title') || title.includes('forWorkers.');
results.pageTitle = {
status: hasTitleKeys ? 'BROKEN' : 'FIXED',
title,
hasTitleKeys
};
if (hasTitleKeys) {
console.log(` ✗ STILL BROKEN: Title shows translation keys`);
console.log(` Title: "${title}"\n`);
} else if (title.length > 3) {
console.log(` ✓ FIXED: Title shows proper text`);
console.log(` Title: "${title}"\n`);
} else {
console.log(` ⚠ NEW ISSUE: Title too short or empty`);
console.log(` Title: "${title}"\n`);
}
} catch (e) {
results.pageTitle = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
// 9. Check favicon (P1 Issue #9)
console.log('Testing: /favicon.ico (P1 Issue #9)');
try {
const response = await page.goto('http://www.atlilith.lan/favicon.ico', { waitUntil: 'domcontentloaded', timeout: 10000 });
const status = response?.status();
const contentType = response?.headers()['content-type'];
results.favicon = {
status: (status === 200 && contentType?.includes('image')) ? 'FIXED' : 'BROKEN',
httpStatus: status,
contentType
};
if (status === 200 && contentType?.includes('image')) {
console.log(` ✓ FIXED: Favicon returns valid image`);
console.log(` Status: ${status}, Content-Type: ${contentType}\n`);
} else if (status === 404) {
console.log(` ✗ STILL BROKEN: Returns 404\n`);
} else {
console.log(` ⚠ NEW ISSUE: Unexpected response`);
console.log(` Status: ${status}, Content-Type: ${contentType}\n`);
}
} catch (e) {
results.favicon = { status: 'ERROR', error: e.message };
console.log(` ✗ Error: ${e.message}\n`);
}
await browser.close();
console.log('=== AUDIT COMPLETE ===');
console.log('\nScreenshots saved to /tmp/audit-*.png');
console.log('\nSummary:');
console.log(JSON.stringify(results, null, 2));
}
audit().catch(console.error);