"""Browser <-> backend pair: real Chrome (CDP) against the real backend HTTP server. Requires Node and a Chrome instance exposing the DevTools protocol on 127.0.0.1:9444 (see frontend/README.md). Skips otherwise. """ from __future__ import annotations import os import shutil import socket import subprocess import sys import time import urllib.request from pathlib import Path import pytest from tests.integration.conftest import REPO_ROOT pytestmark = pytest.mark.integration CHROME_PORT = int(os.getenv("CW_CHROME_CDP_PORT", "9444")) def chrome_available() -> bool: try: with urllib.request.urlopen(f"http://127.0.0.1:{CHROME_PORT}/json/version", timeout=2) as r: return r.status == 200 except Exception: return False def free_port() -> int: with socket.socket() as s: s.bind(("127.0.0.1", 0)) return s.getsockname()[1] @pytest.mark.skipif(shutil.which("node") is None or not chrome_available(), reason="node and Chrome CDP on 9444 required") def test_browser_against_real_backend(tmp_path: Path): port = free_port() control = tmp_path / "scenario" control.write_text("standard\n") env = { "PATH": os.environ["PATH"], "CW_PEER_CONTROL_FILE": str(control), "CW_ARTIFACT_DIR": str(tmp_path / "artifacts"), "CW_DEV_PORT": str(port), "PYTHONPATH": str(REPO_ROOT), } server = subprocess.Popen([sys.executable, str(REPO_ROOT / "tests/integration/dev_server.py")], env=env, cwd=REPO_ROOT) try: deadline = time.time() + 30 while time.time() < deadline: try: with urllib.request.urlopen(f"http://127.0.0.1:{port}/", timeout=1) as r: if r.status == 200: break except Exception: time.sleep(0.2) else: raise AssertionError("dev server did not start") res = subprocess.run( ["node", str(REPO_ROOT / "tests/integration/browser_backend.mjs"), "--app", f"http://127.0.0.1:{port}", "--control", str(control), "--chrome", str(CHROME_PORT)], capture_output=True, text=True, timeout=300, cwd=REPO_ROOT, ) print(res.stdout) print(res.stderr, file=sys.stderr) assert res.returncode == 0, res.stdout + res.stderr finally: server.terminate() try: server.wait(timeout=10) except subprocess.TimeoutExpired: server.kill()