111 lines
4.5 KiB
Python
111 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Firefox AT-SPI baseline on a private X server, bus, and browser profile."""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
PAGE = Path(__file__).with_name("firefox-baseline.html")
|
|
|
|
|
|
def run_inside():
|
|
linked = os.environ.get("CTHULHU_FIREFOX_LINKED") == "1"
|
|
page = Path(__file__).with_name("browser-linked-headings.html") if linked else PAGE
|
|
browser = os.environ.get("CTHULHU_FIREFOX") or shutil.which("firefox")
|
|
if not browser:
|
|
raise RuntimeError("Firefox executable not found")
|
|
with tempfile.TemporaryDirectory(prefix="cthulhu-firefox-profile-") as profile:
|
|
Path(profile, "user.js").write_text(
|
|
'user_pref("datareporting.policy.firstRunURL", "");\n'
|
|
'user_pref("browser.startup.homepage_override.mstone", "ignore");\n',
|
|
encoding="utf-8",
|
|
)
|
|
with tempfile.TemporaryFile() as log:
|
|
environment = dict(os.environ, MOZ_ACCESSIBILITY_ENABLED="1")
|
|
process = subprocess.Popen(
|
|
[browser, "--no-remote", "--profile", profile, "--new-window", page.resolve().as_uri()],
|
|
env=environment, stdout=log, stderr=log,
|
|
)
|
|
try:
|
|
deadline = time.monotonic() + 25
|
|
while time.monotonic() < deadline:
|
|
if process.poll() is not None:
|
|
log.seek(0)
|
|
raise RuntimeError("Firefox exited before the probe: " + log.read().decode(errors="replace"))
|
|
result = subprocess.run(
|
|
["xdotool", "search", "--onlyvisible", "--name", "Cthulhu Linked Headings Probe" if linked else "Cthulhu Firefox Baseline"],
|
|
capture_output=True, text=True,
|
|
)
|
|
if result.stdout.strip():
|
|
window = result.stdout.splitlines()[0]
|
|
subprocess.run(["xdotool", "windowfocus", window], check=True)
|
|
break
|
|
time.sleep(0.1)
|
|
else:
|
|
raise RuntimeError("Firefox fixture window missing")
|
|
environment["CTHULHU_NATIVE_FIREFOX"] = "1"
|
|
environment.setdefault("GOCACHE", "/tmp/cthulhu-cache")
|
|
if linked:
|
|
environment["CTHULHU_NATIVE_LINKED_HEADINGS"] = "1"
|
|
subprocess.run(
|
|
["go", "test", "./internal/app", "-run", "^TestNativeLinkedHeadings$",
|
|
"-count=1", "-v", "-timeout=45s"],
|
|
cwd=ROOT, env=environment, check=True, timeout=50,
|
|
)
|
|
return
|
|
subprocess.run(
|
|
["go", "test", "./internal/atspi", "-run", "^TestNativeFirefoxBaseline$",
|
|
"-count=1", "-v", "-timeout=45s"],
|
|
cwd=ROOT, env=environment, check=True, timeout=55,
|
|
)
|
|
subprocess.run(
|
|
["go", "test", "./internal/app", "-run", "^TestNativeBrowserTabs$",
|
|
"-count=1", "-v", "-timeout=30s"],
|
|
cwd=ROOT, env=environment, check=True, timeout=35,
|
|
)
|
|
finally:
|
|
process.terminate()
|
|
try:
|
|
process.wait(timeout=5)
|
|
except subprocess.TimeoutExpired:
|
|
process.kill()
|
|
process.wait(timeout=5)
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) == 2 and sys.argv[1] == "--inside":
|
|
run_inside()
|
|
return
|
|
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=90,
|
|
)
|
|
finally:
|
|
server.terminate()
|
|
server.wait(timeout=3)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|