Files
telegram-shop/tests/scripts/console-error-monitor-standalone.js
NW 8d85776135 feat: add AI-powered visual regression testing infrastructure
- Add docker-compose.web-testing.yml with vlmkit service
- Add 5 test scripts: capture, compare, pipeline, console-monitor, link-checker
- Add vrt.config.json with 3 viewports + maskSelectors
- Add package.json with @mizchi/vlmkit and Node >=24
- Add tests/README.md with VRT documentation
- Update .gitignore for test artifacts

Based on APAW issue #144 / milestone #106
2026-06-30 21:09:30 +01:00

128 lines
3.7 KiB
JavaScript

const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
const TARGET_URL = process.env.TARGET_URL;
const PAGES = (process.env.PAGES || '/').split(',').map(p => p.trim());
const REPORTS_DIR = process.env.REPORTS_DIR || './reports';
async function monitorPage(context, pagePath) {
const page = await context.newPage();
const fullUrl = `${TARGET_URL}${pagePath}`;
const consoleErrors = [];
const networkErrors = [];
page.on('console', msg => {
if (msg.type() === 'error') {
consoleErrors.push({
type: 'console_error',
text: msg.text(),
location: msg.location(),
timestamp: new Date().toISOString(),
});
}
});
page.on('pageerror', err => {
consoleErrors.push({
type: 'page_error',
text: err.message,
stack: err.stack,
timestamp: new Date().toISOString(),
});
});
page.on('requestfailed', req => {
networkErrors.push({
type: 'network_failure',
url: req.url(),
method: req.method(),
failure: req.failure()?.errorText || 'unknown',
resourceType: req.resourceType(),
timestamp: new Date().toISOString(),
});
});
page.on('response', res => {
if (res.status() >= 400) {
networkErrors.push({
type: 'http_error',
url: res.url(),
status: res.status(),
statusText: res.statusText(),
method: res.request().method(),
resourceType: res.request().resourceType(),
timestamp: new Date().toISOString(),
});
}
});
try {
await page.goto(fullUrl, { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(1000);
} finally {
await page.close();
}
return { pagePath, consoleErrors, networkErrors };
}
async function main() {
if (!TARGET_URL) {
console.error('TARGET_URL environment variable is required');
process.exit(1);
}
const browser = await chromium.launch({ headless: true });
const context = await browser.newContext();
const results = [];
try {
for (const pagePath of PAGES) {
try {
const result = await monitorPage(context, pagePath);
results.push(result);
console.log(`Checked ${pagePath}: ${result.consoleErrors.length} console errors, ${result.networkErrors.length} network errors`);
} catch (err) {
results.push({ pagePath, error: err.message, consoleErrors: [], networkErrors: [] });
console.error(`Failed ${pagePath}: ${err.message}`);
}
}
} finally {
await browser.close();
}
const totalConsoleErrors = results.reduce((sum, r) => sum + r.consoleErrors.length, 0);
const totalNetworkErrors = results.reduce((sum, r) => sum + r.networkErrors.length, 0);
const pagesWithErrors = results.filter(r => r.consoleErrors.length > 0 || r.networkErrors.length > 0).length;
const report = {
timestamp: new Date().toISOString(),
targetUrl: TARGET_URL,
pages: PAGES,
summary: {
totalPages: results.length,
pagesWithErrors,
totalConsoleErrors,
totalNetworkErrors,
hasErrors: totalConsoleErrors > 0 || totalNetworkErrors > 0,
},
results,
};
fs.mkdirSync(REPORTS_DIR, { recursive: true });
const reportPath = path.join(REPORTS_DIR, 'console-error-report.json');
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2));
console.log(`Report saved to ${reportPath}`);
if (totalConsoleErrors > 0 || totalNetworkErrors > 0) {
console.error(`Found ${totalConsoleErrors} console errors and ${totalNetworkErrors} network errors across ${pagesWithErrors} page(s)`);
process.exit(1);
}
}
main().catch(err => {
console.error('Fatal error:', err);
process.exit(1);
});