ci(windows-e2e): ffmpeg screen recording across both GUI phases

Bring back the continuous recording the retired AHK-only driver had,
alongside the 3s frame captures: gdigrab 15fps to proof/<phase>/
recording.mkv, started before the installer/app launches and q-stopped
in the finally block win or lose. mkv stays playable when the process
dies unfinalized; skip gracefully when ffmpeg is not on PATH (it ships
on windows-latest). Lifecycle (start, null-skip, graceful q stop, clean
exit, playable output) verified locally with a lavfi source.
This commit is contained in:
ethernet
2026-08-11 14:37:31 -04:00
parent 71281c27e5
commit 005fc5a6eb
+41 -2
View File
@@ -44,8 +44,8 @@
#
# PROOF: screenshots at every renderer step (Playwright), full-desktop
# screenshots around the installer/AHK phases, a rolling desktop capture
# (every 3s) for the whole run, ahk.log, and the hand-off log. All uploaded
# as CI artifacts.
# (every 3s) plus a continuous ffmpeg screen recording (recording.mkv) for
# both phases, ahk.log, and the hand-off log. All uploaded as CI artifacts.
#
# DEVIATIONS FROM PRODUCTION (each one deliberate and small):
# * the git URL redirect itself -- the staging requirement.
@@ -218,6 +218,41 @@ function Save-DesktopScreenshot([string]$OutFile) {
}
}
function Start-ScreenRecording([string]$OutFile) {
# Continuous ffmpeg screen capture (gdigrab, 15fps). ffmpeg ships on the
# windows-latest runner image; skip gracefully elsewhere. mkv on purpose:
# it stays playable even if the process dies without finalizing.
#
# ffmpeg must be started, fed, and stopped from THIS process: the
# graceful stop is the character 'q' on its LIVE stdin pipe, which only
# System.Diagnostics.Process exposes (Start-Process
# -RedirectStandardInput hands it a file handle already at EOF).
if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) {
Write-Host " (ffmpeg not on PATH; skipping screen recording)"
return $null
}
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = "ffmpeg"
$psi.Arguments = "-y -f gdigrab -framerate 15 -i desktop " +
"-hide_banner -loglevel error " +
"-c:v libx264 -preset ultrafast -pix_fmt yuv420p `"$OutFile`""
$psi.RedirectStandardInput = $true
$psi.UseShellExecute = $false
$proc = [System.Diagnostics.Process]::Start($psi)
Write-Host " screen recording started (pid $($proc.Id)) -> $OutFile"
return $proc
}
function Stop-ScreenRecording($proc) {
if ($proc -and -not $proc.HasExited) {
try {
$proc.StandardInput.Write("q")
$proc.StandardInput.Close()
} catch {}
if (-not $proc.WaitForExit(15000)) { try { $proc.Kill() } catch {} }
}
}
function Start-DesktopRecorder([string]$OutDir) {
# Rolling desktop capture: one PNG every 3s from a detached PowerShell,
# capped at 800 frames (~40 min). Proof that survives any step failure.
@@ -377,6 +412,7 @@ function Invoke-PhaseInstallGui {
New-Item -ItemType Directory -Path $HermesHome -Force | Out-Null
$recorder = Start-DesktopRecorder (Join-Path $proof "desktop-frames")
$recording = Start-ScreenRecording (Join-Path $proof "recording.mkv")
$ahkLog = Join-Path $proof "ahk.log"
try {
Save-DesktopScreenshot (Join-Path $proof "00-before-installer.png")
@@ -415,6 +451,7 @@ function Invoke-PhaseInstallGui {
Assert-True $installer.HasExited "Hermes-Setup.exe exited after Launch"
}
finally {
Stop-ScreenRecording $recording
Stop-DesktopRecorder $recorder (Join-Path $proof "desktop-frames")
# Surface the installer's own log win or lose.
$bootLog = Join-Path $HermesHome "logs\bootstrap-installer.log"
@@ -495,6 +532,7 @@ function Invoke-GuiUpdateDesktopRoute([string]$TargetSha) {
Assert-True $pwResolved "@playwright/test resolvable from installed apps/desktop"
$recorder = Start-DesktopRecorder (Join-Path $proof "desktop-frames")
$recording = Start-ScreenRecording (Join-Path $proof "recording.mkv")
try {
# Launch the installed app and click through Settings -> About ->
# Update now. Exit 0 = the app quit for the updater hand-off.
@@ -603,6 +641,7 @@ function Invoke-GuiUpdateDesktopRoute([string]$TargetSha) {
Save-DesktopScreenshot (Join-Path $proof "99-relaunched-desktop.png")
}
finally {
Stop-ScreenRecording $recording
Stop-DesktopRecorder $recorder (Join-Path $proof "desktop-frames")
$handoffLog = Join-Path $HermesHome "logs\desktop-update-handoff.log"
if (Test-Path -LiteralPath $handoffLog) {