#!/usr/bin/env python3 """Run Chromium against an isolated loopback-only portal with synthetic identities.""" from pathlib import Path import os import shutil import subprocess import sys import tempfile from threading import Thread import time from wsgiref.simple_server import make_server, WSGIRequestHandler ROOT=Path(__file__).resolve().parents[1] sys.path[:0]=[str(ROOT/'src'),str(ROOT/'tests')] from test_journey_roles import JourneyFixture chrome=os.environ.get('JOURNEY_CHROME') or shutil.which('chromium') or shutil.which('google-chrome') if not chrome: matches=sorted((Path.home()/'.cache/ms-playwright').glob('chromium-*/chrome-linux64/chrome')) chrome=str(matches[-1]) if matches else None if not chrome or not shutil.which('node'): raise SystemExit('Chromium and Node are required; set JOURNEY_CHROME to the Chromium executable. Browser tests were not run.') fixture=JourneyFixture();fixture.setUp();fixture.member(email='actual.login@example.test') class Quiet(WSGIRequestHandler): def log_message(self,*args):pass server=make_server('127.0.0.1',0,fixture.app,handler_class=Quiet) worker=Thread(target=server.serve_forever,daemon=True);worker.start() try: with tempfile.TemporaryDirectory(prefix='user-engine-browser-') as profile: process=subprocess.Popen([chrome,'--headless','--no-sandbox','--disable-gpu','--remote-debugging-address=127.0.0.1', '--remote-debugging-port=0','--user-data-dir='+profile,'about:blank'],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL) try: port_file=Path(profile)/'DevToolsActivePort' for _ in range(100): if port_file.exists():break if process.poll() is not None:raise RuntimeError('Chromium exited before test connection') time.sleep(.1) if not port_file.exists():raise RuntimeError('Chromium did not expose its test connection') port=port_file.read_text().splitlines()[0] subprocess.run(['node',str(ROOT/'scripts/browser_journeys.mjs'),'http://127.0.0.1:'+port, 'http://127.0.0.1:'+str(server.server_port)],check=True,timeout=55) finally: process.terminate() try:process.wait(timeout=5) except subprocess.TimeoutExpired:process.kill();process.wait() finally: server.shutdown();server.server_close();worker.join(timeout=5)