""" Playwright E2E test fixtures. Starts the FastAPI app on a random port with test SQLite, no Oracle. """ import os import sys import tempfile import pytest import subprocess import time import socket def _free_port(): with socket.socket() as s: s.bind(('', 0)) return s.getsockname()[1] @pytest.fixture(scope="session") def app_url(): """Start the FastAPI app as a subprocess and return its URL.""" port = _free_port() tmpdir = tempfile.mkdtemp() sqlite_path = os.path.join(tmpdir, "e2e_test.db") env = os.environ.copy() env.update({ "FORCE_THIN_MODE": "true", "SQLITE_DB_PATH": sqlite_path, "ORACLE_DSN": "dummy", "ORACLE_USER": "dummy", "ORACLE_PASSWORD": "dummy", "JSON_OUTPUT_DIR": tmpdir, }) api_dir = os.path.join(os.path.dirname(__file__), "..", "..") proc = subprocess.Popen( [sys.executable, "-m", "uvicorn", "app.main:app", "--host", "127.0.0.1", "--port", str(port)], cwd=api_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) # Wait for startup (up to 15 seconds) url = f"http://127.0.0.1:{port}" for _ in range(30): try: import urllib.request urllib.request.urlopen(f"{url}/health", timeout=1) break except Exception: time.sleep(0.5) else: proc.kill() stdout, stderr = proc.communicate() raise RuntimeError( f"App failed to start on port {port}.\n" f"STDOUT: {stdout.decode()[-2000:]}\n" f"STDERR: {stderr.decode()[-2000:]}" ) yield url proc.terminate() try: proc.wait(timeout=5) except subprocess.TimeoutExpired: proc.kill() @pytest.fixture(scope="session") def seed_test_data(app_url): """ Seed SQLite with test data via API calls. Oracle is unavailable in E2E tests — only SQLite-backed pages are fully functional. This fixture exists as a hook for future seeding; for now E2E tests validate UI structure on empty-state pages. """ return app_url