/** * PB-26-210: Release browser-gate validation. * * Pure functions that verify a gate result has no silent failures. * A release cannot report success with zero tests, unexpected skips, * flaky retries, or missing required projects. */ export interface ProjectResult { name: string; totalTests: number; passed: number; skipped: number; flaky: number; } export interface GateResult { projects: ProjectResult[]; } export const REQUIRED_BROWSER_PROJECTS = ["chrome-release", "firefox-release"] as const; /** * Validate a gate result. Returns a list of error strings — empty means pass. * The release gate fails (non-zero) on any error. */ export function validateGateResult( result: GateResult, requiredProjects: readonly string[] = REQUIRED_BROWSER_PROJECTS, ): string[] { const errors: string[] = []; const totalTests = result.projects.reduce((sum, p) => sum + p.totalTests, 0); if (totalTests === 0) { errors.push("zero tests discovered across all projects"); } for (const name of requiredProjects) { const project = result.projects.find((p) => p.name === name); if (!project) { errors.push(`required project "${name}" is missing`); continue; } if (project.totalTests === 0) { errors.push(`project "${name}" has zero tests`); } if (project.skipped > 0) { errors.push(`project "${name}" has ${project.skipped} skipped test(s)`); } if (project.flaky > 0) { errors.push(`project "${name}" has ${project.flaky} flaky retry/retr(y)ies`); } } return errors; }