param( [string]$BaseUrl = "http://127.0.0.1:5095", [string]$Spec = "tests/e2e/smoke.spec.js" ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $repoRoot = Split-Path -Parent $scriptDir $appUrl = [Uri]$BaseUrl $healthUrl = "$BaseUrl/api/health" $tempDbPath = Join-Path $env:TEMP ("rpgroller-playwright-{0}.db" -f [Guid]::NewGuid().ToString("N")) $process = $null Push-Location $repoRoot try { $env:ConnectionStrings__RpgRoller = "Data Source=$tempDbPath" $env:PLAYWRIGHT_BASE_URL = $BaseUrl $process = Start-Process dotnet -ArgumentList @( "run", "--project", "RpgRoller/RpgRoller.csproj", "--verbosity" "minimal" "--urls", $BaseUrl ) -WorkingDirectory $repoRoot -PassThru -NoNewWindow $response = $null for ($i = 0; $i -lt 60; $i++) { try { $response = Invoke-WebRequest -Uri $healthUrl -UseBasicParsing -TimeoutSec 2 if ($response.StatusCode -eq 200) { break } } catch { Start-Sleep -Milliseconds 500 } Start-Sleep -Milliseconds 500 } if (-not $response -or $response.StatusCode -ne 200) { throw "Application failed to start on $BaseUrl." } npm exec playwright test $Spec -- --reporter=line if ($LASTEXITCODE -ne 0) { throw "Playwright exited with code $LASTEXITCODE." } } finally { if ($process -and -not $process.HasExited) { Stop-Process -Id $process.Id -Force } Remove-Item Env:\ConnectionStrings__RpgRoller -ErrorAction SilentlyContinue Remove-Item Env:\PLAYWRIGHT_BASE_URL -ErrorAction SilentlyContinue Pop-Location }