118 lines
4.8 KiB
Python
118 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Run actions and editable internal controls on a private X11/AT-SPI desktop."""
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
|
|
|
|
def run_inside():
|
|
root = Path(__file__).resolve().parents[1]
|
|
environment = dict(os.environ, GOCACHE="/tmp/cthulhu-cache", CTHULHU_NATIVE_X11="1",
|
|
CTHULHU_NATIVE_BROWSER="1")
|
|
probe = subprocess.Popen(["xev", "-name", "Internal UI background", "-event", "keyboard"],
|
|
stdout=subprocess.DEVNULL)
|
|
try:
|
|
deadline = time.monotonic() + 5
|
|
while True:
|
|
found = subprocess.run(["xdotool", "search", "--onlyvisible", "--name", "^Internal UI background$"],
|
|
capture_output=True, text=True)
|
|
if found.returncode == 0:
|
|
background = found.stdout.strip().splitlines()[0]
|
|
environment["CTHULHU_UI_BACKGROUND"] = background
|
|
subprocess.run(["xdotool", "windowfocus", background], check=True)
|
|
break
|
|
if time.monotonic() >= deadline:
|
|
raise RuntimeError("keyboard probe did not open")
|
|
time.sleep(0.02)
|
|
subprocess.run(["go", "test", "./internal/platform/xorg", "-count=1", "-timeout=60s",
|
|
"-run", "^TestNative(InternalUICapturesAndReleases|LearnModeCapturesKeysAndRestoresCommands|CustomBindingsUpdateAndRelease|CommandGrabSuspensionAndRestoration|SecureInputDropsKeysAndRestoresGrabs|BrowseKeyTransitions)$"],
|
|
cwd=root, env=environment, check=True)
|
|
finally:
|
|
probe.terminate()
|
|
probe.wait(timeout=5)
|
|
with tempfile.TemporaryDirectory(prefix="cthulhu-internal-ui-") as temporary:
|
|
marker = Path(temporary) / "state.json"
|
|
environment.update(CTHULHU_UI_MARKER=str(marker), CTHULHU_NATIVE_INTERNAL_UI="1")
|
|
fixture = subprocess.Popen([sys.executable, __file__, "--fixture"], env=environment)
|
|
try:
|
|
deadline = time.monotonic() + 10
|
|
window = ""
|
|
while time.monotonic() < deadline:
|
|
found = subprocess.run(["xdotool", "search", "--onlyvisible", "--name",
|
|
"^Internal UI action probe$"], capture_output=True, text=True)
|
|
if found.returncode == 0:
|
|
window = found.stdout.strip().splitlines()[0]
|
|
break
|
|
time.sleep(0.02)
|
|
if not window:
|
|
raise RuntimeError("GTK fixture did not open")
|
|
subprocess.run(["xdotool", "windowfocus", "--sync", window], check=True)
|
|
subprocess.run(["go", "test", "./internal/app", "-count=1", "-timeout=30s",
|
|
"-run", "^TestNative(InternalUIActionsAndEntry|TentacleClipboardTargetsAndTemporaryImage)$"],
|
|
cwd=root, env=environment, check=True)
|
|
finally:
|
|
fixture.terminate()
|
|
fixture.wait(timeout=5)
|
|
|
|
|
|
def run_fixture():
|
|
import gi
|
|
gi.require_version("Gtk", "3.0")
|
|
from gi.repository import Gtk
|
|
window = Gtk.Window(title="Internal UI action probe")
|
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
button = Gtk.Button(label="Run action")
|
|
entry = Gtk.Entry()
|
|
entry.get_accessible().set_name("Application text")
|
|
box.pack_start(button, False, False, 0)
|
|
box.pack_start(entry, False, False, 0)
|
|
lines = Gtk.TextView()
|
|
lines.get_accessible().set_name("Transfer text lines")
|
|
lines.get_buffer().set_text("First line\nSecond line")
|
|
lines.get_buffer().place_cursor(lines.get_buffer().get_start_iter())
|
|
box.pack_start(lines, False, False, 0)
|
|
password = Gtk.Entry()
|
|
password.set_visibility(False)
|
|
password.set_text("private fixture password")
|
|
password.get_accessible().set_name("Protected transfer text")
|
|
box.pack_start(password, False, False, 0)
|
|
window.add(box)
|
|
state = {"clicks": 0, "text": ""}
|
|
marker = Path(os.environ["CTHULHU_UI_MARKER"])
|
|
|
|
def save():
|
|
replacement = marker.with_suffix(".tmp")
|
|
replacement.write_text(json.dumps(state))
|
|
replacement.replace(marker)
|
|
|
|
def clicked(_button):
|
|
state["clicks"] += 1
|
|
save()
|
|
|
|
def changed(_entry):
|
|
state["text"] = entry.get_text()
|
|
save()
|
|
|
|
button.connect("clicked", clicked)
|
|
entry.connect("changed", changed)
|
|
window.connect("destroy", Gtk.main_quit)
|
|
window.show_all()
|
|
button.grab_focus()
|
|
save()
|
|
Gtk.main()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if "--fixture" in sys.argv:
|
|
run_fixture()
|
|
elif "--inside" in sys.argv:
|
|
run_inside()
|
|
else:
|
|
subprocess.run(["xvfb-run", "-a", "dbus-run-session", "--", sys.executable,
|
|
__file__, "--inside"], check=True,
|
|
env=dict(os.environ, GTK_MODULES="gail:atk-bridge", NO_AT_BRIDGE="0"))
|