Files
cthulhu/tests/native_alert.py

83 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""Private Xvfb/AT-SPI proof for GTK alert message capture."""
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import time
sys.dont_write_bytecode = True
def inside():
fixture = subprocess.Popen([sys.executable, str(Path(__file__).with_name("gtk_alert.py"))])
try:
deadline = time.monotonic() + 10
window = ""
while time.monotonic() < deadline:
result = subprocess.run(
["xdotool", "search", "--onlyvisible", "--name", "^Cthulhu Alert Probe$"],
capture_output=True, text=True,
)
if result.returncode == 0:
window = result.stdout.splitlines()[0]
break
time.sleep(0.02)
if not window:
raise RuntimeError("GTK alert probe window missing")
environment = dict(os.environ, CTHULHU_ALERT_WINDOW=window)
environment.setdefault("GOCACHE", "/tmp/cthulhu-cache")
subprocess.run(
["go", "test", "./internal/atspi", "-run", "^TestNativeGTKAlertMessage$", "-count=1", "-timeout=20s"],
cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25,
)
environment["CTHULHU_NATIVE_YAD"] = "1"
for name in ("TestNativeYADQuestionMessage", "TestNativeYADListMessage", "TestNativeYADPowerListMessage"):
subprocess.run(
["go", "test", "./internal/atspi", "-run", f"^{name}$", "-count=1", "-timeout=20s"],
cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25,
)
# Keep the radio fixture in the same private X11/AT-SPI session.
environment["CTHULHU_NATIVE_RADIO"] = "1"
subprocess.run(
["go", "test", "./internal/atspi", "-run", "^TestNativeGTKRadioGroupName$", "-count=1", "-timeout=20s"],
cwd=Path(__file__).resolve().parents[1], env=environment, check=True, timeout=25,
)
finally:
fixture.terminate()
fixture.wait(timeout=3)
def main():
if len(sys.argv) == 2 and sys.argv[1] == "--inside":
inside()
return
with tempfile.TemporaryDirectory(prefix="cthulhu-alert-"):
read_fd, write_fd = os.pipe()
server = subprocess.Popen(
["Xvfb", "-displayfd", str(write_fd), "-screen", "0", "800x600x24", "-nolisten", "tcp"],
pass_fds=(write_fd,), stderr=subprocess.DEVNULL,
)
os.close(write_fd)
try:
with os.fdopen(read_fd) as reader:
display = reader.readline().strip()
if not display:
raise RuntimeError("Xvfb failed to start")
environment = dict(os.environ, DISPLAY=":" + display, XDG_SESSION_TYPE="x11")
environment.pop("DBUS_SESSION_BUS_ADDRESS", None)
environment.pop("AT_SPI_BUS_ADDRESS", None)
environment.pop("WAYLAND_DISPLAY", None)
subprocess.run(
["dbus-run-session", "--", sys.executable, str(Path(__file__).resolve()), "--inside"],
env=environment, check=True, timeout=50,
)
finally:
server.terminate()
server.wait(timeout=3)
if __name__ == "__main__":
main()