Files
herdr/scripts/windows_input/Probe.ps1
T
b88e8116e9 test: add local windows input gauntlet (#4298)
* test: add local windows input gauntlet

refs #4251

* test: add local windows input gauntlet

Harden elevation and channel identity checks, distinguish known host limitations, and surface incomplete cleanup.

refs #4251

* test(windows): harden input gauntlet execution

refs #4251

* test(windows): make input gauntlet self-contained

refs #4251

* test(windows): bound input gauntlet failure paths

refs #4251

* test(windows): extend input qualification gauntlet

refs #4251

* test(windows): complete input qualification matrix

refs #4251

---------

Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Co-authored-by: Jonathan Liebig <jonathan.liebig@gmail.com>
2026-09-18 01:13:13 +02:00

71 lines
3.5 KiB
PowerShell

#Requires -Version 7.0
param([Parameter(Mandatory)][string] $PlanPath)
. "$PSScriptRoot/Common.ps1"
$plan = Read-GauntletJson $PlanPath
Add-Type -Path "$PSScriptRoot/Native.cs"
$probe = $null
try {
$probe = [HerdrInputGauntlet.ConsoleProbe]::new($plan.mode)
[HerdrInputGauntlet.ConsoleProbe]::Print("`r`nHerdr input gauntlet observer $($plan.nonce)`r`n")
if ($plan.mode -eq 'kitty') {
$deadline = [DateTime]::UtcNow.AddSeconds(2)
while (-not $probe.Hex().Contains('1b5b3f3175') -and [DateTime]::UtcNow -lt $deadline) { Start-Sleep -Milliseconds 50 }
}
Write-GauntletJson (Join-Path $plan.work 'ready.json') @{
nonce = $plan.nonce; pid = $PID; mode = $plan.mode; geometry = [HerdrInputGauntlet.ConsoleProbe]::Geometry()
negotiation_hex = $probe.Hex(); kitty_acknowledged = $probe.Hex().Contains('1b5b3f3175')
}
# Negotiation replies are setup evidence, not input for the first case.
$probe.Clear()
$closedCount = 0
$last = ''
while ((Test-GauntletLease $plan.root) -and -not (Test-Path (Join-Path $plan.work 'probe-stop'))) {
$request = Read-GauntletJson (Join-Path $plan.work 'request.json')
if ($null -ne $request -and $request.id -ne $last) {
if ($request.nonce -ne $plan.nonce) { throw 'Unexpected observer nonce' }
$last = $request.id
$quietReached = $false
if ($request.action -eq 'mouse-on') {
[HerdrInputGauntlet.ConsoleProbe]::Print("`e[?1003h`e[?1006h")
Start-Sleep -Milliseconds 200
}
if ($request.action -eq 'mouse-off') {
[HerdrInputGauntlet.ConsoleProbe]::Print("`e[?1003l`e[?1006l")
Start-Sleep -Milliseconds 100
}
if ($request.action -eq 'set-mode') {
$probe.SetKeyboardMode([string]$request.value)
Start-Sleep -Milliseconds 200
}
if ($request.action -eq 'begin' -and -not $probe.ClearIfCount($closedCount)) { throw 'Unexpected input arrived between captures' }
if ($request.action -eq 'end') {
# Capture trailing duplicates/releases as well as the first expected bytes.
$deadline = [DateTime]::UtcNow.AddSeconds(3)
$quiet = [DateTime]::UtcNow
$count = $probe.Count()
do {
Start-Sleep -Milliseconds 50
$newCount = $probe.Count()
if ($newCount -ne $count) { $quiet = [DateTime]::UtcNow; $count = $newCount }
} while (([DateTime]::UtcNow - $quiet).TotalMilliseconds -lt 350 -and [DateTime]::UtcNow -lt $deadline)
$quietReached = ([DateTime]::UtcNow - $quiet).TotalMilliseconds -ge 350
$closedCount = $probe.Count()
}
Write-GauntletJson (Join-Path $plan.work 'reply.json') @{
id = $request.id; nonce = $plan.nonce; action = $request.action
hex = $probe.Hex(); records = @($probe.Records()); error = $probe.Error; quiet_reached = $quietReached
geometry = [HerdrInputGauntlet.ConsoleProbe]::Geometry()
}
}
Start-Sleep -Milliseconds 25
}
} catch {
Write-GauntletJson (Join-Path $plan.work 'probe-error.json') @{ error = $_.ToString(); nonce = $plan.nonce }
throw
} finally {
if ($null -ne $probe) {
$probe.Dispose()
Write-GauntletJson (Join-Path $plan.work 'probe-exit.json') @{ nonce = $plan.nonce; cleanup_errors = @($probe.CleanupErrors) }
}
}