diff --git a/scripts/verify-public-deploy.mjs b/scripts/verify-public-deploy.mjs index 0404e10..f46c6b3 100644 --- a/scripts/verify-public-deploy.mjs +++ b/scripts/verify-public-deploy.mjs @@ -149,11 +149,40 @@ try { } if (releaseManifest.releaseDashboard) { const dashboard = await readTextAsset(targetUrl, releaseManifest.releaseDashboard); + const dashboardText = visibleText(dashboard); assert(dashboard.includes('Heros Web Release QA'), `Expected deployed release dashboard title: ${dashboard.slice(0, 200)}`); assert(dashboard.includes(releaseManifest.shortCommit ?? releaseManifest.commit), `Expected deployed release dashboard commit: ${dashboard.slice(0, 400)}`); assert(dashboard.includes('Repeated Battle Outcomes'), `Expected deployed release dashboard battle outcomes section: ${dashboard.slice(0, 800)}`); assert(dashboard.includes('Process Failures'), `Expected deployed release dashboard process failure metric: ${dashboard.slice(0, 800)}`); + assert(dashboard.includes('Objective Misses'), `Expected deployed release dashboard objective miss metric: ${dashboard.slice(0, 800)}`); + assert(dashboard.includes('Repeated Objective Misses'), `Expected deployed release dashboard objective miss section: ${dashboard.slice(0, 1200)}`); assert(dashboard.includes('Repeat Runs'), `Expected deployed release dashboard repeat runs section: ${dashboard.slice(0, 800)}`); + if (typeof deployedQaRepeatReport?.summary?.totalMissedObjectives === 'number') { + assert( + dashboardText.includes(`Objective Misses ${deployedQaRepeatReport.summary.totalMissedObjectives}`), + `Expected deployed release dashboard objective miss total ${deployedQaRepeatReport.summary.totalMissedObjectives}: ${dashboard.slice(0, 1200)}` + ); + } + for (const miss of deployedQaRepeatReport?.missedObjectives ?? []) { + const latest = miss.examples?.at(-1); + assert( + dashboardText.includes(`${miss.battleNo}`) && dashboardText.includes(miss.objectiveId), + `Expected deployed release dashboard missed objective ${miss.battleNo}/${miss.objectiveId}: ${dashboard.slice(0, 1600)}` + ); + if (latest?.failureReason || miss.failureReason) { + const reason = latest?.failureReason ?? miss.failureReason; + assert( + dashboardText.includes(reason), + `Expected deployed release dashboard missed objective reason "${reason}": ${dashboard.slice(0, 1600)}` + ); + } + } + if (deployedQaRepeatReport && (deployedQaRepeatReport.missedObjectives ?? []).length === 0) { + assert( + dashboard.includes('No missed objectives recorded.'), + `Expected deployed release dashboard empty objective miss state: ${dashboard.slice(0, 1600)}` + ); + } for (const run of deployedQaRepeatReport?.runs ?? []) { const runReportAsset = distAssetPath(run.path); assert(dashboard.includes(runReportAsset), `Expected deployed release dashboard to link repeat run report ${runReportAsset}: ${dashboard.slice(0, 1200)}`); @@ -214,6 +243,10 @@ function distAssetPath(filePath) { return String(filePath).replaceAll('\\', '/').replace(/^dist\//, '').replace(/^\/+/, ''); } +function visibleText(html) { + return String(html).replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim(); +} + function assert(condition, message) { if (!condition) { throw new Error(message);