# AetherForge - full test suite runner param( [switch]$SkipE2E, [switch]$SkipBuild, [switch]$Verbose ) $ErrorActionPreference = "Stop" $Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) if (-not (Test-Path (Join-Path $Root "server\go.mod"))) { $Root = Split-Path -Parent $MyInvocation.MyCommand.Path if (-not (Test-Path (Join-Path $Root "server\go.mod"))) { $Root = (Get-Location).Path } } $Results = @() $Failed = 0 function Write-Phase([string]$Name) { Write-Host "" Write-Host "==============================================================" -ForegroundColor Cyan Write-Host " $Name" -ForegroundColor Cyan Write-Host "==============================================================" -ForegroundColor Cyan } function Invoke-Phase([string]$Name, [scriptblock]$Block) { Write-Phase $Name try { & $Block if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw "exit code $LASTEXITCODE" } $script:Results += [pscustomobject]@{ Phase = $Name; Status = "PASS" } Write-Host " >> PASS" -ForegroundColor Green } catch { $script:Failed++ $msg = $_.Exception.Message $script:Results += [pscustomobject]@{ Phase = $Name; Status = "FAIL"; Detail = $msg } Write-Host " >> FAIL: $msg" -ForegroundColor Red if ($Verbose) { Write-Host $_ } } } Write-Host "" Write-Host " AetherForge Full Test Suite" -ForegroundColor Yellow Write-Host " Root: $Root" Invoke-Phase "1/8 Go server tests" { Push-Location (Join-Path $Root "server") go test ./... -count=1 Pop-Location } Invoke-Phase "2/8 Go agent tests" { Push-Location (Join-Path $Root "agent") go test ./... -count=1 Pop-Location } Invoke-Phase "3/8 Fusion module build" { Push-Location (Join-Path $Root "fusion") go build . Pop-Location } Invoke-Phase "4/8 Frontend unit tests (Vitest)" { Push-Location (Join-Path $Root "server\web") if (-not (Test-Path "node_modules")) { npm install --silent } npm test Pop-Location } if (-not $SkipBuild) { Invoke-Phase "5/8 Frontend production build" { Push-Location (Join-Path $Root "server\web") npm run build Pop-Location } Invoke-Phase "6/8 Server binary compile" { Push-Location (Join-Path $Root "server") go build -o (Join-Path $Root "bin\miner-server.exe") . Pop-Location } Invoke-Phase "7/8 Agent binary compile" { Push-Location (Join-Path $Root "agent") go build -o (Join-Path $Root "bin\install-worker.exe") . Pop-Location } Invoke-Phase "7b Agent cross-compile (linux/darwin)" { Push-Location (Join-Path $Root "agent") $env:CGO_ENABLED = "0" $env:GOOS = "linux"; $env:GOARCH = "amd64" go build -o (Join-Path $Root "bin\install-worker-linux-amd64") -ldflags "-s -w" . $env:GOOS = "linux"; $env:GOARCH = "arm64" go build -o (Join-Path $Root "bin\install-worker-linux-arm64") -ldflags "-s -w" . $env:GOOS = "darwin"; $env:GOARCH = "arm64" go build -o (Join-Path $Root "bin\install-worker-darwin-arm64") -ldflags "-s -w" . $env:GOOS = "darwin"; $env:GOARCH = "amd64" go build -o (Join-Path $Root "bin\install-worker-darwin-amd64") -ldflags "-s -w" . Remove-Item Env:GOOS, Env:GOARCH -ErrorAction SilentlyContinue Pop-Location } } else { Write-Phase "5-7/8 Build phases (skipped)" } if (-not $SkipE2E) { Invoke-Phase "8/8 E2E smoke (Playwright)" { $DataDir = Join-Path $env:TEMP ("aether-e2e-" + [guid]::NewGuid().ToString("n")) New-Item -ItemType Directory -Force -Path $DataDir | Out-Null $WebRoot = Join-Path $Root "server\webroot" Copy-Item (Join-Path $Root "server\web\dist\*") $WebRoot -Recurse -Force -ErrorAction SilentlyContinue $ServerExe = Join-Path $Root "bin\miner-server.exe" if (-not (Test-Path $ServerExe)) { Push-Location (Join-Path $Root "server") go build -o $ServerExe . Pop-Location } $proc = Start-Process -FilePath $ServerExe -ArgumentList "-port","18989","-data",$DataDir -WorkingDirectory $Root -PassThru -WindowStyle Hidden try { $ready = $false for ($i = 0; $i -lt 30; $i++) { try { $r = Invoke-RestMethod "http://127.0.0.1:18989/api/v1/health" -TimeoutSec 2 if ($r.status -eq "ok") { $ready = $true; break } } catch {} Start-Sleep -Seconds 1 } if (-not $ready) { throw "E2E server did not become healthy on :18989" } Push-Location (Join-Path $Root "server\web") $env:AETHERFORGE_URL = "http://127.0.0.1:18989" npx playwright install chromium 2>$null | Out-Null npx playwright test --config playwright.config.ts Pop-Location } finally { if ($proc -and -not $proc.HasExited) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue } Remove-Item $DataDir -Recurse -Force -ErrorAction SilentlyContinue } } } else { Write-Phase "8/8 E2E (skipped)" } Write-Host "" Write-Host "==============================================================" -ForegroundColor Cyan Write-Host " SUMMARY" -ForegroundColor Cyan Write-Host "==============================================================" -ForegroundColor Cyan $Results | Format-Table -AutoSize if ($Failed -gt 0) { Write-Host " $Failed phase(s) FAILED" -ForegroundColor Red exit 1 } Write-Host " All phases PASSED" -ForegroundColor Green exit 0