diff --git a/config/scripts/run-terminal-scale-perf-report-gate.mjs b/config/scripts/run-terminal-scale-perf-report-gate.mjs index 92d19504af1..801e810dbe3 100644 --- a/config/scripts/run-terminal-scale-perf-report-gate.mjs +++ b/config/scripts/run-terminal-scale-perf-report-gate.mjs @@ -1,6 +1,7 @@ import { spawnSync } from 'node:child_process' -import { closeSync, mkdirSync, openSync } from 'node:fs' -import { dirname } from 'node:path' +import { closeSync, copyFileSync, mkdirSync, mkdtempSync, openSync, rmSync } from 'node:fs' +import { tmpdir } from 'node:os' +import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' const DEFAULT_REPORT_PATH = 'test-results/terminal-scale-perf-report.json' @@ -63,23 +64,32 @@ export function runTerminalScalePerfReportGate({ spawnSyncImpl = spawnSync } = {}) { const { passthroughArgs, reportPath } = parseReportGateArgs(argv, env) - mkdirSync(dirname(reportPath), { recursive: true }) + const tempDir = mkdtempSync(join(tmpdir(), 'orca-terminal-scale-perf-')) + const tempReportPath = join(tempDir, 'report.json') - const reportFd = openSync(reportPath, 'w') - let scaleResult + let scaleExitCode try { - scaleResult = runNodeScript( - 'config/scripts/run-terminal-scale-perf-e2e.mjs', - ['--', '--reporter=json', ...passthroughArgs], - ['inherit', reportFd, 'inherit'], - spawnSyncImpl, - env - ) + const reportFd = openSync(tempReportPath, 'w') + let scaleResult + try { + scaleResult = runNodeScript( + 'config/scripts/run-terminal-scale-perf-e2e.mjs', + ['--', '--reporter=json', ...passthroughArgs], + ['inherit', reportFd, 'inherit'], + spawnSyncImpl, + env + ) + } finally { + closeSync(reportFd) + } + + scaleExitCode = exitCode(scaleResult) + mkdirSync(dirname(reportPath), { recursive: true }) + copyFileSync(tempReportPath, reportPath) } finally { - closeSync(reportFd) + rmSync(tempDir, { force: true, recursive: true }) } - const scaleExitCode = exitCode(scaleResult) if (scaleExitCode !== 0) { console.error(`Terminal scale perf report saved to ${reportPath}`) return scaleExitCode diff --git a/config/scripts/run-terminal-scale-perf-report-gate.test.mjs b/config/scripts/run-terminal-scale-perf-report-gate.test.mjs index b171acd1649..929e2d5b9ba 100644 --- a/config/scripts/run-terminal-scale-perf-report-gate.test.mjs +++ b/config/scripts/run-terminal-scale-perf-report-gate.test.mjs @@ -1,6 +1,6 @@ +import { dirname, join } from 'node:path' import { mkdtempSync, readFileSync, rmSync, writeSync } from 'node:fs' import { tmpdir } from 'node:os' -import { join } from 'node:path' import { afterEach, describe, expect, it, vi } from 'vitest' import { parseReportGateArgs, @@ -15,11 +15,12 @@ function tempReportPath() { return join(dir, 'report.json') } -function makeSpawnSync({ scaleStatus = 0 } = {}) { +function makeSpawnSync({ onScaleRun, scaleStatus = 0 } = {}) { const calls = [] const spawnSyncImpl = vi.fn((command, args, options) => { calls.push({ args, command, options }) if (args[0] === 'config/scripts/run-terminal-scale-perf-e2e.mjs') { + onScaleRun?.() writeSync(options.stdio[1], '{"suites":[]}') return { signal: null, status: scaleStatus } } @@ -106,6 +107,23 @@ describe('run-terminal-scale-perf-report-gate', () => { expect(calls[1].args).toEqual(['config/scripts/summarize-terminal-perf-report.mjs', reportPath]) }) + it('preserves the report when Playwright clears the target report directory', () => { + const reportPath = tempReportPath() + const { spawnSyncImpl } = makeSpawnSync({ + onScaleRun: () => { + rmSync(dirname(reportPath), { force: true, recursive: true }) + } + }) + + const status = runTerminalScalePerfReportGate({ + argv: ['--report', reportPath], + spawnSyncImpl + }) + + expect(status).toBe(0) + expect(readFileSync(reportPath, 'utf8')).toBe('{"suites":[]}') + }) + it('stops before summarize and budget checks when the scale run fails', () => { const reportPath = tempReportPath() const { calls, spawnSyncImpl } = makeSpawnSync({ scaleStatus: 7 })