chore: initialize from frontend template 4dc033c

This commit is contained in:
DongHyeonka
2026-08-13 18:23:26 +09:00
commit 40107eec84
897 changed files with 234824 additions and 0 deletions
@@ -0,0 +1,89 @@
import { readFile } from "node:fs/promises";
const evidencePath =
"artifacts/tests/browser-capabilities/results.xml";
const xml = await readFile(evidencePath, "utf8");
const failures: string[] = [];
const rootAttributes =
/<testsuites\b([^>]*)>/u.exec(xml)?.[1] ?? "";
const root = attributes(rootAttributes);
for (const field of ["failures", "errors", "skipped"] as const) {
if (root[field] !== "0") {
failures.push(`root ${field} must be zero`);
}
}
if (!positiveInteger(root.tests)) {
failures.push("root tests must be positive");
}
const casesByEngine = new Map<string, Set<string>>();
for (const match of xml.matchAll(
/<testsuite\b([^>]*)>([\s\S]*?)<\/testsuite>/gu,
)) {
const suite = attributes(match[1] ?? "");
const engine = suite.hostname;
if (!engine) continue;
const cases =
casesByEngine.get(engine) ?? new Set<string>();
for (const testCase of (match[2] ?? "").matchAll(
/<testcase\b([^>]*)>/gu,
)) {
const data = attributes(testCase[1] ?? "");
if (data.classname && data.name) {
cases.add(`${data.classname}::${data.name}`);
}
}
casesByEngine.set(engine, cases);
}
const expectedEngines = ["chromium", "firefox", "webkit"] as const;
const baseline = casesByEngine.get(expectedEngines[0]);
for (const engine of expectedEngines) {
const cases = casesByEngine.get(engine);
if (!cases || cases.size === 0) {
failures.push(`${engine} has no executed browser-capability cases`);
continue;
}
if (
baseline &&
(cases.size !== baseline.size ||
[...baseline].some((testCase) => !cases.has(testCase)))
) {
failures.push(`${engine} case set differs from chromium`);
}
}
for (const engine of casesByEngine.keys()) {
if (!expectedEngines.includes(engine as (typeof expectedEngines)[number])) {
failures.push(`unexpected browser project ${engine}`);
}
}
if (/<skipped\b/u.test(xml) || /<failure\b/u.test(xml)) {
failures.push("browser-capability evidence contains skipped/failure nodes");
}
if (failures.length > 0) {
process.stderr.write(
`Browser capability evidence failed:\n- ${failures.join("\n- ")}\n`,
);
process.exit(1);
}
process.stdout.write(
`Browser capability evidence: PASS (${baseline?.size ?? 0} cases x ${expectedEngines.length} engines, zero skipped)\n`,
);
function attributes(source: string): Record<string, string> {
return Object.fromEntries(
[...source.matchAll(/([A-Za-z][A-Za-z0-9_-]*)="([^"]*)"/gu)].map(
(match) => [match[1] ?? "", match[2] ?? ""],
),
);
}
function positiveInteger(value: string | undefined): boolean {
return (
typeof value === "string" &&
/^\d+$/u.test(value) &&
Number(value) > 0
);
}