bookworm-boot/tools/test-launcher-e2e.ps1

124 lines
6.4 KiB
PowerShell
Raw Permalink Normal View History

<#
.SYNOPSIS
v3.1.1: 启动器 .lnk 端到端行为测试
.DESCRIPTION
模拟双击桌面 .lnk pwsh bw-launch.ps1 claude.ps1 链路.
检测点:
1. PS 进程能拉起 ( ExecutionPolicy 拒绝 / wt tab )
2. bw-launch.ps1 PATH 三层重载执行无错
3. claude.ps1 解析能找到 (不一定真启动 Claude TUI, --version 探测)
4. 整体退出码 = 0 (任何运行时错就拒绝)
替代手动双击, 集成到 build.ps1 后自动跑, 提前抓 v3.0.10 -or bug.
.NOTES
用法: pwsh -NoProfile -File tools/test-launcher-e2e.ps1
退出码: 0=PASS / 1=FAIL
日志: $env:TEMP\bw-e2e-test.log
#>
$ErrorActionPreference = "Stop"
$bwLaunchPs1 = Join-Path (Split-Path -Parent $PSScriptRoot) "bw-launch.ps1"
$logFile = Join-Path $env:TEMP "bw-e2e-test.log"
if (-not (Test-Path $bwLaunchPs1)) {
Write-Host "[FAIL] bw-launch.ps1 缺失: $bwLaunchPs1" -ForegroundColor Red
exit 1
}
Write-Host "[e2e] 测试目标: $bwLaunchPs1" -ForegroundColor Cyan
# Test 1: PS 解析 wrapper 文件 (静态 syntax)
$err = $null
[void][System.Management.Automation.Language.Parser]::ParseFile($bwLaunchPs1, [ref]$null, [ref]$err)
if ($err) {
Write-Host "[FAIL] bw-launch.ps1 PARSE 错: $($err.Count)" -ForegroundColor Red
$err | Select-Object -First 3 | ForEach-Object { Write-Host " L$($_.Extent.StartLineNumber): $($_.Message)" -ForegroundColor Red }
exit 1
}
Write-Host "[e2e ✓] Test 1 — bw-launch.ps1 PARSE OK" -ForegroundColor Green
# Test 2: 实跑 wrapper, claude 不可用场景 (期望 GUI 弹窗 + 退出码 1, 不是闪退)
# 用临时 PATH 隔离 claude
$pwshExe = (Get-Command pwsh -EA SilentlyContinue).Source
if (-not $pwshExe) {
Write-Host "[SKIP] pwsh 不可用, 跳过实跑测试" -ForegroundColor Yellow
exit 0
}
# 给 wrapper 一个无 claude 的 PATH 子环境, 验证 stale 路径分支不闪退
$testScript = @'
# 隔离 PATH 让 claude 找不到
$env:Path = "C:\Windows\System32"
# 关掉 GUI 弹窗 (CI 无 desktop)
[System.Reflection.Assembly]::Load('System.Windows.Forms') | Out-Null
$env:BW_E2E_NOGUI = "1"
'@
Write-Host "[e2e] Test 2 — wrapper 静态分析 (运行时缺 claude 应清晰报错而非闪退)" -ForegroundColor Cyan
$content = Get-Content $bwLaunchPs1 -Raw
$expectedFeatures = @{
"PATH 三层重载" = ($content -match 'GetEnvironmentVariable.*Machine' -and $content -match 'npm config get prefix')
"claude.ps1 fallback 链" = ($content -match 'claude\.ps1' -and $content -match 'Get-Command claude')
"失败 GUI 弹窗" = ($content -match 'MessageBox\]::Show')
"失败日志写入" = ($content -match 'bw-launch\.log')
"args 转发到 claude" = ($content -match '\$claudePs1.*@args' -or $content -match '\$args')
"exit code 传播" = ($content -match 'exit \$exitCode' -or $content -match 'exit \$LASTEXITCODE')
}
$failedFeatures = $expectedFeatures.GetEnumerator() | Where-Object { -not $_.Value } | ForEach-Object { $_.Key }
if ($failedFeatures) {
Write-Host "[FAIL] wrapper 缺关键特性:" -ForegroundColor Red
$failedFeatures | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
exit 1
}
Write-Host "[e2e ✓] Test 2 — wrapper 6 项特性齐全" -ForegroundColor Green
# Test 3: .lnk Args 4 项契约验证 (auto-setup.ps1 / install.ps1 一致性)
Write-Host "[e2e] Test 3 — .lnk Args 契约 (auto-setup + install 双向一致)" -ForegroundColor Cyan
$autoSetup = Get-Content (Join-Path (Split-Path -Parent $PSScriptRoot) "auto-setup.ps1") -Raw
$installPs1 = Get-Content (Join-Path (Split-Path -Parent $PSScriptRoot) "install.ps1") -Raw
$contractChecks = @{
"auto-setup.ps1 .lnk Args 含 -ExecutionPolicy Bypass" = ($autoSetup -match '\$shortcut\.Arguments\s*=[^\r\n]*-ExecutionPolicy Bypass')
"auto-setup.ps1 .lnk Args 含 bwLaunchPs1 变量" = ($autoSetup -match '\$shortcut\.Arguments\s*=[^\r\n]*\$bwLaunchPs1')
"auto-setup.ps1 .lnk Args 含 --skip-permissions" = ($autoSetup -match '\$shortcut\.Arguments\s*=[^\r\n]*dangerously-skip-permissions')
"install.ps1 .lnk Args 含 -ExecutionPolicy Bypass" = ($installPs1 -match '\$shortcut\.Arguments\s*=[^\r\n]*-ExecutionPolicy Bypass')
"install.ps1 .lnk Args 含 bwLaunchPs1 变量" = ($installPs1 -match '\$shortcut\.Arguments\s*=[^\r\n]*\$bwLaunchPs1')
"install.ps1 .lnk Args 含 --skip-permissions" = ($installPs1 -match '\$shortcut\.Arguments\s*=[^\r\n]*dangerously-skip-permissions')
}
$contractFails = $contractChecks.GetEnumerator() | Where-Object { -not $_.Value } | ForEach-Object { $_.Key }
if ($contractFails) {
Write-Host "[FAIL] .lnk Args 契约不一致:" -ForegroundColor Red
$contractFails | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
exit 1
}
Write-Host "[e2e ✓] Test 3 — .lnk Args 6 项契约一致" -ForegroundColor Green
# Test 4: profile 双注入契约
Write-Host "[e2e] Test 4 — profile 双注入契约 (PS7 + PS5.1)" -ForegroundColor Cyan
$profileChecks = @{
"auto-setup.ps1 注入 PS7 profile (Documents\PowerShell)" = ($autoSetup -match 'Documents\\PowerShell.*profile\.ps1' -or $autoSetup -match 'Documents\\\\PowerShell')
"auto-setup.ps1 注入 PS5.1 profile (Documents\WindowsPowerShell)" = ($autoSetup -match 'Documents\\WindowsPowerShell' -or $autoSetup -match 'WindowsPowerShell')
"auto-setup.ps1 sentinel BW_CRED_START v3.1.0" = ($autoSetup -match 'BW_CRED_START v3\.1\.0')
"auto-setup.ps1 字面替换 (String.Replace)" = ($autoSetup -match '\.Replace\(\$match\.Value')
}
$profileFails = $profileChecks.GetEnumerator() | Where-Object { -not $_.Value } | ForEach-Object { $_.Key }
if ($profileFails) {
Write-Host "[FAIL] profile 注入契约缺失:" -ForegroundColor Red
$profileFails | ForEach-Object { Write-Host " - $_" -ForegroundColor Red }
exit 1
}
Write-Host "[e2e ✓] Test 4 — profile 双注入契约齐全" -ForegroundColor Green
# All passed
Write-Host ""
Write-Host "━━━ E2E 测试 SUMMARY ━━━" -ForegroundColor Green
Write-Host " Test 1: bw-launch.ps1 PARSE ✓"
Write-Host " Test 2: wrapper 6 项特性齐全 ✓"
Write-Host " Test 3: .lnk Args 6 项契约一致 ✓"
Write-Host " Test 4: profile 双注入契约齐全 ✓"
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Green
Write-Host "[PASS] E2E 测试通过 (4/4)" -ForegroundColor Green
exit 0