116 lines
5.9 KiB
PowerShell
116 lines
5.9 KiB
PowerShell
param(
|
|
[ValidateSet('Debug', 'Release')]
|
|
[string]$Configuration = 'Debug',
|
|
[ValidateSet('x64', 'Win32')]
|
|
[string]$Platform = 'x64',
|
|
[ValidateSet('All', 'wide-text', 'dpi-coordinate', 'ime-position')]
|
|
[string]$Mode = 'All',
|
|
[ValidateSet('inherit', 'unaware', 'system', 'per-monitor', 'per-monitor-v2')]
|
|
[string]$DpiAwareness = 'inherit',
|
|
[ValidateSet('unspecified', 'MicrosoftPinyin', 'Sogou')]
|
|
[string]$ImeName = 'unspecified'
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$root = Split-Path -Parent $PSScriptRoot
|
|
$msbuild = if ($env:STELLARX_MSBUILD) { $env:STELLARX_MSBUILD } else { 'D:\vs2022\MSBuild\Current\Bin\MSBuild.exe' }
|
|
$project = Join-Path $root 'tests\EasyX.VisualProbe.vcxproj'
|
|
$probe = Join-Path $root "build\$Platform\$Configuration\EasyX.VisualProbe.exe"
|
|
if (-not (Test-Path -LiteralPath $msbuild)) { throw "MSBuild not found: $msbuild" }
|
|
|
|
$pathKeyCount = @(
|
|
[Environment]::GetEnvironmentVariables([EnvironmentVariableTarget]::Process).Keys |
|
|
Where-Object { [string]$_ -ieq 'Path' }
|
|
).Count
|
|
if ($pathKeyCount -gt 1) {
|
|
$buildCommand = 'set "PATH=" & "' + $msbuild + '" "' + $project +
|
|
'" /m /t:Build /p:Configuration=' + $Configuration + ' /p:Platform=' + $Platform + ' /v:minimal'
|
|
& $env:ComSpec /d /c $buildCommand
|
|
}
|
|
else {
|
|
& $msbuild $project /m /t:Build /p:Configuration=$Configuration /p:Platform=$Platform /v:minimal
|
|
}
|
|
if ($LASTEXITCODE -ne 0) { throw 'Visual probe build failed' }
|
|
if (-not (Test-Path -LiteralPath $probe)) { throw "Visual probe executable not found: $probe" }
|
|
|
|
$sessionId = [guid]::NewGuid().ToString()
|
|
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss-fff'
|
|
$sessionRoot = Join-Path $root "TestResults\VisualProbe\$stamp-$sessionId"
|
|
New-Item -ItemType Directory -Force -Path $sessionRoot | Out-Null
|
|
$modes = if ($Mode -eq 'All') { @('wide-text', 'dpi-coordinate') } else { @($Mode) }
|
|
$summaries = New-Object System.Collections.Generic.List[object]
|
|
$probeFailed = $false
|
|
|
|
foreach ($probeMode in $modes) {
|
|
$startedAtUtc = [DateTime]::UtcNow.ToString('o')
|
|
$runDirectory = Join-Path $sessionRoot $probeMode
|
|
New-Item -ItemType Directory -Force -Path $runDirectory | Out-Null
|
|
if ($probeMode -eq 'ime-position') {
|
|
$manualEvidence = Join-Path $runDirectory 'manual-evidence'
|
|
New-Item -ItemType Directory -Force -Path $manualEvidence | Out-Null
|
|
Write-Host "Manual IME position probe: $ImeName"
|
|
Write-Host ' 1. Select the requested IME and click the EasyX window.'
|
|
Write-Host ' 2. Press F1, type ceshi, inspect the candidate position, then press Escape.'
|
|
Write-Host ' 3. Repeat with F2 and F3. Use only the fixed non-sensitive input ceshi.'
|
|
Write-Host ' 4. At F3, commit once with Space; switch back to F1, type ceshi, and verify the old F3 position is not reused.'
|
|
Write-Host ' 5. To close 0C-3, save tightly cropped screenshots with anchor-id prefixes under:'
|
|
Write-Host " $manualEvidence"
|
|
Write-Host ' 6. Close the EasyX window when all three anchors and the post-commit F1 regression have been exercised.'
|
|
}
|
|
Write-Host "Running visual probe mode: $probeMode"
|
|
& $probe --mode $probeMode --output $runDirectory --dpi-awareness $DpiAwareness --ime-name $ImeName
|
|
$exitCode = $LASTEXITCODE
|
|
$rawPath = Join-Path $runDirectory 'raw-result.json'
|
|
if (-not (Test-Path -LiteralPath $rawPath)) {
|
|
throw "Visual probe did not produce raw-result.json (exit $exitCode): $runDirectory"
|
|
}
|
|
$summary = & (Join-Path $PSScriptRoot 'analyze-visual-probe.ps1') `
|
|
-Path $runDirectory -SessionId $sessionId -StartedAtUtc $startedAtUtc -ProbeExitCode $exitCode
|
|
$summaries.Add($summary)
|
|
if ($exitCode -ne 0 -or $summary.automatedStatus -ne 'pass') { $probeFailed = $true }
|
|
}
|
|
|
|
if ($summaries.Count -eq 2) {
|
|
$drawing = $summaries | Where-Object mode -eq 'wide-text' | Select-Object -First 1
|
|
$coordinate = $summaries | Where-Object mode -eq 'dpi-coordinate' | Select-Object -First 1
|
|
$combinedInput = "$($drawing.manifestSha256):$($coordinate.manifestSha256)"
|
|
$sha = [Security.Cryptography.SHA256]::Create()
|
|
try {
|
|
$combinedBytes = [Text.Encoding]::UTF8.GetBytes($combinedInput)
|
|
$combinedHash = ([BitConverter]::ToString($sha.ComputeHash($combinedBytes))).Replace('-', '')
|
|
}
|
|
finally {
|
|
$sha.Dispose()
|
|
}
|
|
$baseline = [pscustomobject][ordered]@{
|
|
visualProbeBaselineSchemaVersion = 1
|
|
sessionId = $sessionId
|
|
createdAtUtc = [DateTime]::UtcNow.ToString('o')
|
|
drawingBaselineManifest = 'wide-text/manifest-v1.json'
|
|
coordinateBaselineManifest = 'dpi-coordinate/manifest-v1.json'
|
|
drawingBaselineSha256 = $drawing.manifestSha256
|
|
coordinateBaselineSha256 = $coordinate.manifestSha256
|
|
combinedBaselineId = "sha256:$combinedHash"
|
|
dpiAwareness = $coordinate.windowAwareness
|
|
dpiForWindow = $coordinate.dpiForWindow
|
|
imeIdentity = $null
|
|
hkl = $null
|
|
automatedStatus = if ($probeFailed) { 'fail' } else { 'pass' }
|
|
manualStatus = 'not_reviewed'
|
|
}
|
|
$baselinePath = Join-Path $sessionRoot 'baseline-set-v1.json'
|
|
$utf8Bom = New-Object System.Text.UTF8Encoding($true)
|
|
[IO.File]::WriteAllText($baselinePath,
|
|
($baseline | ConvertTo-Json -Depth 20) + [Environment]::NewLine, $utf8Bom)
|
|
$baselineHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $baselinePath).Hash
|
|
$utf8NoBom = New-Object System.Text.UTF8Encoding($false)
|
|
[IO.File]::WriteAllText($baselinePath + '.sha256',
|
|
"$baselineHash *baseline-set-v1.json`r`n", $utf8NoBom)
|
|
Write-Host "Combined baseline: $baselinePath"
|
|
Write-Host "Combined baseline ID: $($baseline.combinedBaselineId)"
|
|
}
|
|
|
|
$summaries | Format-Table mode, automatedStatus, manualStatus, testCaseCount, evidenceCount, dpiForWindow
|
|
Write-Host "Result directory: $sessionRoot"
|
|
if ($probeFailed) { throw "One or more visual probe modes did not pass; evidence was preserved in $sessionRoot" }
|