Files
aurora-admin/tools/run-regression.mjs
T

79 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* run-regression.mjs — headless 回归 runner(CI / 本地均可)
*
* 前置:仓库根目录起 dev-server(node site/dev-server.js)
* 依赖:npm i playwright(或全局已装)
* 运行:node tools/run-regression.mjs
* 产出:tests/report.json(首页「测试通过率」数据源)+ tests/report-junit.xml
*/
import { writeFileSync } from 'fs';
const BASE = process.env.REG_BASE || 'http://127.0.0.1:3311';
const CONC = 6;
const { chromium } = await import('playwright');
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
const data = await (await fetch(`${BASE}/site/data.json`)).json();
const slugs = data.components.map(c => c.slug);
const results = [];
async function runOne(browser, slug) {
const p = await browser.newPage({ viewport: { width: 1200, height: 800 } });
try {
await p.goto(`${BASE}/tests/${slug}.html`, { waitUntil: 'load', timeout: 15000 });
const btn = p.locator('#run-asserts');
if (await btn.count()) await btn.click();
await p.waitForTimeout(200);
const r = await p.evaluate(() => {
const num = s => parseInt(String(s || '0').replace(/\D/g, '')) || 0;
const t = id => { const n = document.getElementById(id); return n ? n.textContent : '0'; };
const failures = [...document.querySelectorAll('#result-list .t-row')]
.filter(li => li.querySelector('.t-pill')?.classList.contains('fail'))
.map(li => li.querySelector('.id')?.textContent || '?')
.slice(0, 8);
return { total: num(t('sum-total')), pass: num(t('sum-pass')), fail: num(t('sum-fail')), skip: num(t('sum-skip')), failures };
});
results.push({ slug, ...r });
} catch (e) {
results.push({ slug, total: 0, pass: 0, fail: 1, skip: 0, failures: ['page-error'] });
} finally {
await p.close();
}
}
for (let i = 0; i < slugs.length; i += CONC) {
await Promise.all(slugs.slice(i, i + CONC).map(s => runOne(browser, s)));
}
await browser.close();
const totalAssert = results.reduce((s, r) => s + r.total, 0);
const passAssert = results.reduce((s, r) => s + r.pass, 0);
const failAssert = results.reduce((s, r) => s + r.fail, 0);
const skipAssert = results.reduce((s, r) => s + r.skip, 0);
const pagesAllPass = results.filter(r => r.fail === 0 && r.total > 0).length;
const report = {
generated: new Date().toISOString().slice(0, 19).replace('T', ' '),
version: data.meta.version,
pages: results.length,
pagesAllPass,
passRate: totalAssert ? Math.round(passAssert / totalAssert * 1000) / 10 : 0,
assertions: { total: totalAssert, pass: passAssert, fail: failAssert, skip: skipAssert },
failedPages: results.filter(r => r.fail > 0).map(r => ({ slug: r.slug, fail: r.fail, failures: r.failures }))
};
writeFileSync('tests/report.json', JSON.stringify(report, null, 2) + '\n');
/* JUnit XML(供 CI 展示) */
const esc = s => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
const cases = results.map(r =>
` <testcase name="tests/${r.slug}" time="0">` +
(r.fail > 0 ? `<failure message="${esc((r.failures || []).join('; '))}">${r.fail} failed</failure>` : '') +
`</testcase>`).join('\n');
writeFileSync('tests/report-junit.xml',
`<?xml version="1.0" encoding="UTF-8"?>\n<testsuite name="aurora-admin tests" tests="${results.length}" failures="${results.filter(r => r.fail > 0).length}">\n${cases}\n</testsuite>\n`);
console.log(`passRate ${report.passRate}% | pages ${results.length} (all-pass ${pagesAllPass}) | assertions ${passAssert}/${totalAssert}`);
console.log('written: tests/report.json, tests/report-junit.xml');