feat: Enhance end-to-end testing framework with improved server setup and UI validation

This commit is contained in:
2025-10-21 09:04:06 +02:00
parent f020d276bc
commit 9114b584c2
11 changed files with 138 additions and 71 deletions

View File

@@ -1,3 +1,4 @@
import os
import subprocess
import time
from typing import Generator
@@ -5,23 +6,58 @@ from typing import Generator
import pytest
from playwright.sync_api import Browser, Page, Playwright, sync_playwright
import httpx
# Use a different port for the test server to avoid conflicts
TEST_PORT = 8001
BASE_URL = f"http://localhost:{TEST_PORT}"
@pytest.fixture(scope="function")
@pytest.fixture(scope="session", autouse=True)
def live_server() -> Generator[str, None, None]:
"""Launch a live test server in a separate process."""
process = subprocess.Popen(
["uvicorn", "main:app", f"--port={TEST_PORT}"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
[
"uvicorn",
"main:app",
"--host",
"127.0.0.1",
f"--port={TEST_PORT}",
],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
env=os.environ.copy(),
)
time.sleep(2) # Give the server a moment to start
yield BASE_URL
process.terminate()
process.wait()
deadline = time.perf_counter() + 30
last_error: Exception | None = None
while time.perf_counter() < deadline:
if process.poll() is not None:
raise RuntimeError("uvicorn server exited before becoming ready")
try:
response = httpx.get(BASE_URL, timeout=1.0)
if response.status_code < 500:
break
except Exception as exc: # noqa: BLE001
last_error = exc
time.sleep(0.5)
else:
process.terminate()
process.wait(timeout=5)
raise TimeoutError(
"Timed out waiting for uvicorn test server to start"
) from last_error
try:
yield BASE_URL
finally:
if process.poll() is None:
process.terminate()
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()
process.wait(timeout=5)
@pytest.fixture(scope="session")
@@ -45,5 +81,7 @@ def browser(
def page(browser: Browser, live_server: str) -> Generator[Page, None, None]:
"""Provide a new page for each test."""
page = browser.new_page(base_url=live_server)
page.goto("/")
page.wait_for_load_state("networkidle")
yield page
page.close()