<# .SYNOPSIS ObsiGate — E2E locaux (Playwright) sous Windows/PowerShell. .DESCRIPTION Équivalent PowerShell de `scripts/run-e2e-local.sh`, pour les postes Windows où `bash` n'est pas utilisable (WSL indisponible, git-bash bloqué par une politique de contrôle d'application). Démarre le backend nativement via uvicorn (auth désactivée, fixtures TestVault/TestDir, port 2029 — mêmes conditions que le job CI `e2e`), lance la suite Playwright puis nettoie. .PARAMETER PlaywrightArgs Arguments transmis à `npx playwright test`, ex. `-g "image viewer"`, `--headed`. .EXAMPLE ./scripts/run-e2e-local.ps1 ./scripts/run-e2e-local.ps1 -g "BUG-072" ./scripts/run-e2e-local.ps1 --headed #> [CmdletBinding()] param( [Parameter(ValueFromRemainingArguments = $true)] [string[]]$PlaywrightArgs ) $ErrorActionPreference = "Stop" $Root = Split-Path -Parent $PSScriptRoot Set-Location -LiteralPath $Root $Port = if ($env:E2E_PORT) { $env:E2E_PORT } else { "2029" } $BaseUrl = "http://127.0.0.1:$Port" $ServerLog = "data/e2e-server.log" $ServerErrLog = "data/e2e-server.err.log" function Assert-Command([string]$Name, [string]$Hint) { if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) { throw "[ERR] $Name introuvable. $Hint" } } Assert-Command "uv" "Installez-le : https://docs.astral.sh/uv/" Assert-Command "npx" "Installez Node.js (>= 20)." # ----- Venv Python 3.11 (créé une seule fois) ----- $Python = ".venv-e2e/Scripts/python.exe" if (-not (Test-Path -LiteralPath $Python)) { Write-Host "[INFO] Création du venv .venv-e2e (Python 3.11)..." uv venv .venv-e2e --python 3.11 uv pip install --python $Python -r backend/requirements.txt } # ----- Port déjà occupé ? ----- try { Invoke-WebRequest -Uri "$BaseUrl/api/health" -TimeoutSec 2 -UseBasicParsing | Out-Null Write-Host "[ERR] Quelque chose répond déjà sur $BaseUrl." Write-Host " Arrêtez-le ou choisissez un autre port : `$env:E2E_PORT=2030; ./scripts/run-e2e-local.ps1" exit 1 } catch { # port libre } # ----- Démarrage du serveur (mêmes conditions que le CI e2e) ----- Write-Host "[INFO] Démarrage d'ObsiGate sur $BaseUrl (auth désactivée)..." New-Item -ItemType Directory -Force -Path "data" | Out-Null $env:OBSIGATE_AUTH_ENABLED = "false" $env:VAULT_1_NAME = "TestVault" $env:VAULT_1_PATH = (Resolve-Path -LiteralPath "test_vault").Path $env:DIR_1_NAME = "TestDir" $env:DIR_1_PATH = (Resolve-Path -LiteralPath "test_dir").Path $server = Start-Process -FilePath $Python ` -ArgumentList "-m", "uvicorn", "backend.main:app", "--host", "127.0.0.1", "--port", $Port ` -RedirectStandardOutput $ServerLog -RedirectStandardError $ServerErrLog ` -PassThru -WindowStyle Hidden $exitCode = 1 try { # ----- Attente du health check (30 s max, comme le CI) ----- $ready = $false for ($i = 0; $i -lt 30; $i++) { try { Invoke-WebRequest -Uri "$BaseUrl/api/health" -TimeoutSec 2 -UseBasicParsing | Out-Null $ready = $true break } catch { if ($server.HasExited) { Write-Host "[ERR] Le serveur a quitté prématurément. Log :" Get-Content -LiteralPath $ServerErrLog -Tail 30 -ErrorAction SilentlyContinue exit 1 } Start-Sleep -Seconds 1 } } if (-not $ready) { Write-Host "[ERR] Serveur injoignable sur $BaseUrl. Log :" Get-Content -LiteralPath $ServerErrLog -Tail 30 -ErrorAction SilentlyContinue exit 1 } Write-Host "[OK] Serveur prêt." # ----- Browsers Playwright (no-op s'ils sont déjà installés) ----- npx playwright install chromium # ----- Exécution de la suite (projet CI : chromium-desktop) ----- Write-Host "[INFO] BASE_URL=$BaseUrl npx playwright test --project=chromium-desktop $($PlaywrightArgs -join ' ')" $env:BASE_URL = $BaseUrl & npx playwright test --project=chromium-desktop @PlaywrightArgs $exitCode = $LASTEXITCODE } finally { Write-Host "[INFO] Arrêt du serveur (PID $($server.Id))..." if (-not $server.HasExited) { Stop-Process -Id $server.Id -Force -ErrorAction SilentlyContinue } # uvicorn (via uv) peut lancer un interpréteur enfant : tuer le groupe resté sur le port. Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } } exit $exitCode