chore(09-02): add Playwright dev deps and e2e package scaffolding

- Add pytest-playwright and playwright to requirements-dev.txt
- Create tests/e2e/__init__.py package marker
- Create tests/e2e/conftest.py with session-scoped live_server fixture
This commit is contained in:
2026-04-13 10:55:49 +02:00
parent 9902e2a5b8
commit 4e9bd9b1ab
3 changed files with 72 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
"""E2E test fixtures: live uvicorn server for Playwright."""
from __future__ import annotations
import os
import socket
import threading
import time
import httpx
import pytest
import uvicorn
def _free_port() -> int:
with socket.socket() as s:
s.bind(("127.0.0.1", 0))
return s.getsockname()[1]
@pytest.fixture(scope="session")
def live_server(tmp_path_factory):
"""Start the FastAPI app on a random port in a background thread."""
# Isolated data dir for E2E session
data_dir = tmp_path_factory.mktemp("imptune_e2e_data")
# Patch config module so the app uses the temp dir
import imptune.config as cfg
cfg.DATA_DIR = str(data_dir)
cfg.DB_PATH = str(data_dir / "imptune.db")
cfg.DRIVERS_DIR = str(data_dir / "drivers")
cfg.ICONS_DIR = str(data_dir / "icons")
os.makedirs(cfg.DRIVERS_DIR, exist_ok=True)
os.makedirs(cfg.ICONS_DIR, exist_ok=True)
# Also set env var so lifespan handler picks up correct dirs
os.environ["DATA_DIR"] = str(data_dir)
# Initialize DB against the tmp dir
from imptune.db.database import init_db
init_db()
from imptune.main import app
port = _free_port()
config = uvicorn.Config(app, host="127.0.0.1", port=port, log_level="error")
server = uvicorn.Server(config)
thread = threading.Thread(target=server.run, daemon=True)
thread.start()
base_url = f"http://127.0.0.1:{port}"
# Readiness poll via /health (up to 5 s)
deadline = time.time() + 5.0
while time.time() < deadline:
try:
r = httpx.get(f"{base_url}/health", timeout=0.5)
if r.status_code == 200:
break
except Exception:
pass
time.sleep(0.1)
else:
raise RuntimeError("live_server did not become ready within 5 s")
yield base_url
server.should_exit = True
thread.join(timeout=2.0)