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 = /]*)>/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>(); for (const match of xml.matchAll( /]*)>([\s\S]*?)<\/testsuite>/gu, )) { const suite = attributes(match[1] ?? ""); const engine = suite.hostname; if (!engine) continue; const cases = casesByEngine.get(engine) ?? new Set(); for (const testCase of (match[2] ?? "").matchAll( /]*)>/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 (/ 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 { 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 ); }