#!/usr/bin/env python3 # Copyright (c) 2026 Storm Dragon # Authors: Storm Dragon, Angus Kola # SPDX-License-Identifier: GPL-3.0-or-later """Exercise Toby's editable read-only combo under a private AT-SPI session.""" import os from pathlib import Path import site import subprocess import sys import tempfile import time from native_test_session import run_private_session def wait_for_window(): deadline = time.monotonic() + 5 while time.monotonic() < deadline: result = subprocess.run( ["xdotool", "search", "--onlyvisible", "--name", "^Toby combo probe$"], capture_output=True, text=True, ) if result.stdout.strip(): return result.stdout.strip().splitlines()[0] time.sleep(0.05) raise RuntimeError("Toby combo fixture window missing") def run_inside(): root = Path(__file__).resolve().parents[1] diagnostics = tempfile.NamedTemporaryFile(prefix="cthulhu-combo-qt-", suffix=".log", delete=False) print("Qt fixture diagnostics:", diagnostics.name, flush=True) fixture = subprocess.Popen( [sys.executable, root / "tests" / "toby_combo_fixture.py"], stderr=diagnostics, stdout=diagnostics, ) try: window = wait_for_window() subprocess.run(["xdotool", "windowfocus", "--sync", window], check=True) from native_x11 import set_active_window set_active_window(int(window)) subprocess.run( ["go", "test", "./internal/atspi", "-run", "^TestNativeTobyComboPopupLifetime$", "-count=1", "-v", "-timeout=45s"], cwd=root, check=True, timeout=60, env=dict(os.environ, CTHULHU_NATIVE_TOBY_COMBO="1", GOCACHE="/tmp/cthulhu-cache"), ) finally: exited = fixture.poll() is not None if not exited: fixture.terminate() fixture.wait(timeout=5) diagnostics.close() if exited: raise RuntimeError(f"Qt fixture exited with status {fixture.returncode}; see {diagnostics.name}") if __name__ == "__main__": if "--inside" in sys.argv: run_inside() else: with tempfile.TemporaryDirectory(prefix="cthulhu-toby-combo-") as temporary: environment = dict( os.environ, HOME=temporary, XDG_CONFIG_HOME=temporary, XDG_CACHE_HOME=temporary, XDG_DATA_HOME=temporary, QT_QPA_PLATFORM="xcb", QT_LINUX_ACCESSIBILITY_ALWAYS_ON="1", NO_AT_BRIDGE="0", PYTHONPATH=site.getusersitepackages(), GOMODCACHE=subprocess.check_output( ["go", "env", "GOMODCACHE"], text=True ).strip(), ) environment.pop("AT_SPI_BUS_ADDRESS", None) run_private_session( ["xvfb-run", "-a", "-s", "-screen 0 1024x768x24", "dbus-run-session", "--", sys.executable, __file__, "--inside"], env=environment, check=True, )