feat: Enhance end-to-end testing framework with improved server setup and UI validation
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user