Close scratch iteration 008 and enforce full surface audits

This commit is contained in:
master
2026-03-13 11:00:12 +02:00
parent fe35801cc5
commit c9a30331ce
11 changed files with 534 additions and 32 deletions

View File

@@ -435,6 +435,54 @@ async function verifySurfaceActions(context, surface) {
return results;
}
function collectSurfaceIssues(surface, record) {
const issues = [];
if (!record.headingMatched) {
issues.push(`heading-mismatch:${surface.key}:${record.headingText || '<empty>'}`);
}
for (const problemText of record.problemTexts) {
issues.push(`problem-text:${surface.key}:${problemText}`);
}
for (const errorText of record.consoleErrors) {
issues.push(`console:${surface.key}:${errorText}`);
}
for (const errorText of record.pageErrors) {
issues.push(`pageerror:${surface.key}:${errorText}`);
}
for (const failure of record.requestFailures) {
issues.push(`requestfailed:${surface.key}:${failure.method} ${failure.url} ${failure.error}`);
}
for (const failure of record.responseErrors) {
issues.push(`response:${surface.key}:${failure.status} ${failure.method} ${failure.url}`);
}
if (surface.searchQuery) {
if (!record.search?.available) {
issues.push(`search-unavailable:${surface.key}`);
} else if (
!record.search.resultsVisible
&& record.search.suggestionCount === 0
&& (record.search.resultsText || '').length === 0
) {
issues.push(`search-empty:${surface.key}:${surface.searchQuery}`);
}
}
for (const actionResult of record.actions) {
if (!actionResult.ok) {
issues.push(`action-failed:${surface.key}:${actionResult.key}:${actionResult.reason ?? actionResult.finalUrl ?? 'unknown'}`);
}
}
return issues;
}
async function main() {
mkdirSync(outputDirectory, { recursive: true });
const authReport = await authenticateFrontdoor({
@@ -452,17 +500,27 @@ async function main() {
generatedAtUtc: new Date().toISOString(),
baseUrl,
surfaces: [],
issues: [],
};
for (const surface of surfaceConfigs) {
const surfaceReport = await inspectSurface(context, surface);
surfaceReport.actions = await verifySurfaceActions(context, surface);
surfaceReport.issues = collectSurfaceIssues(surface, surfaceReport);
surfaceReport.ok = surfaceReport.issues.length === 0;
report.surfaces.push(surfaceReport);
report.issues.push(...surfaceReport.issues);
}
await browser.close();
report.failedSurfaceCount = report.surfaces.filter((surface) => !surface.ok).length;
report.runtimeIssueCount = report.issues.length;
writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`, 'utf8');
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
if (report.failedSurfaceCount > 0 || report.runtimeIssueCount > 0) {
process.exit(1);
}
}
if (process.argv[1] && path.resolve(process.argv[1]) === __filename) {

View File

@@ -12,6 +12,11 @@ const outputDir = path.join(webRoot, 'output', 'playwright');
const resultPath = path.join(outputDir, 'live-full-core-audit.json');
const suites = [
{
name: 'route-surface-ownership-check',
script: 'live-route-surface-ownership-check.mjs',
reportPath: path.join(outputDir, 'live-route-surface-ownership-check.json'),
},
{
name: 'frontdoor-canonical-route-sweep',
script: 'live-frontdoor-canonical-route-sweep.mjs',
@@ -47,6 +52,11 @@ const suites = [
script: 'live-user-reported-admin-trust-check.mjs',
reportPath: path.join(outputDir, 'live-user-reported-admin-trust-check.json'),
},
{
name: 'changed-surfaces',
script: 'live-frontdoor-changed-surfaces.mjs',
reportPath: path.join(outputDir, 'live-frontdoor-changed-surfaces.json'),
},
{
name: 'jobs-queues-action-sweep',
script: 'live-jobs-queues-action-sweep.mjs',
@@ -122,6 +132,7 @@ const failureCountKeys = new Set([
'failedCount',
'failureCount',
'errorCount',
'failedSurfaceCount',
'runtimeIssueCount',
'issueCount',
'unexpectedErrorCount',
@@ -204,6 +215,10 @@ async function readReport(reportPath) {
}
}
async function persistSummary(summary) {
await writeFile(resultPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8');
}
function runSuite({ name, script }) {
return new Promise((resolve) => {
const startedAt = Date.now();
@@ -236,6 +251,7 @@ async function main() {
retriedSuiteCount: 0,
stabilizedAfterRetryCount: 0,
};
await persistSummary(summary);
for (const suite of suites) {
process.stdout.write(`[live-full-core-audit] START ${suite.name}\n`);
@@ -292,6 +308,7 @@ async function main() {
};
summary.suites.push(result);
await persistSummary(summary);
process.stdout.write(
`[live-full-core-audit] DONE ${suite.name} ok=${ok} exitCode=${execution.exitCode ?? 'null'} ` +
`signals=${failureSignals.length} durationMs=${execution.durationMs}` +
@@ -313,7 +330,7 @@ async function main() {
stabilizedAfterRetry: suite.stabilizedAfterRetry,
}));
await writeFile(resultPath, `${JSON.stringify(summary, null, 2)}\n`, 'utf8');
await persistSummary(summary);
if (summary.failedSuiteCount > 0) {
process.exitCode = 1;