Cthulhu is no longer a fork. Now it is a screen reader written in Golang.
This commit is contained in:
1 parent
a998fe67de
commit
069fc674dc
708 files changed
+112482
-532
No files matched your search
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check a fresh, physical arrows-first Steam Big Picture run of Cthulhu."""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def check_log(path: Path) -> None:
|
||||
records = [json.loads(line) for line in path.read_text().splitlines() if line.strip()]
|
||||
starts = [index for index, record in enumerate(records)
|
||||
if record.get("message") == "starting Cthulhu"]
|
||||
if not starts:
|
||||
raise ValueError("no Cthulhu startup in log")
|
||||
records = records[starts[-1]:]
|
||||
|
||||
steam_pid = None
|
||||
steam_document = False
|
||||
first_link = None
|
||||
first_caret = None
|
||||
tab_focus = False
|
||||
home = power = confirm = cancel = False
|
||||
links_before_arrow = set()
|
||||
for record in records:
|
||||
message = record.get("message")
|
||||
if message == "X11 foreground ownership changed":
|
||||
pid = record.get("pid") or 0
|
||||
if first_link is not None and pid and pid != steam_pid and not cancel:
|
||||
raise ValueError("foreground left Steam before the dialog check finished")
|
||||
if first_link is None and pid:
|
||||
steam_pid = pid
|
||||
continue
|
||||
if message == "suspended for XTerm focus handoff" and first_link is not None and not cancel:
|
||||
raise ValueError("focus switched away from Steam before the dialog check finished")
|
||||
if (message == "delivering accessible presentation" and
|
||||
record.get("role") == "document web" and
|
||||
record.get("utterance", "").startswith("Steam Big Picture Mode")):
|
||||
steam_document = True
|
||||
if message == "document caret navigation completed" and record.get("moved") is True:
|
||||
if first_link is not None and first_caret is None:
|
||||
first_caret = record.get("time")
|
||||
continue
|
||||
if message != "delivering accessible presentation" or record.get("cause") != "object:state-changed:focused":
|
||||
continue
|
||||
role = record.get("role")
|
||||
utterance = record.get("utterance", "")
|
||||
if role == "link" and utterance and steam_document:
|
||||
if first_link is None:
|
||||
first_link = record.get("time")
|
||||
links_before_arrow.add(utterance)
|
||||
elif first_caret is None:
|
||||
links_before_arrow.add(utterance)
|
||||
else:
|
||||
tab_focus = True
|
||||
if first_caret is None:
|
||||
continue
|
||||
if role == "menu item" and utterance == "Home, menu item":
|
||||
home = True
|
||||
elif role == "menu item" and utterance == "Power, menu item":
|
||||
power = home
|
||||
elif role == "button" and utterance == "Confirm, button":
|
||||
confirm = power
|
||||
elif role == "button" and utterance == "Cancel, button":
|
||||
cancel = confirm
|
||||
if cancel:
|
||||
break
|
||||
|
||||
if not steam_document or first_link is None:
|
||||
raise ValueError("Steam never exposed its document and an initial focused link")
|
||||
if len(links_before_arrow) != 1:
|
||||
raise ValueError("focus moved between links before the first browse arrow; test arrows first")
|
||||
if first_caret is None:
|
||||
raise ValueError("no successful browse arrow after Steam became ready")
|
||||
if not tab_focus:
|
||||
raise ValueError("no focused link after the first arrow and Tab")
|
||||
if not home or not power:
|
||||
raise ValueError("Escape did not expose Home and Power")
|
||||
if not confirm or not cancel:
|
||||
raise ValueError("Power did not expose both Confirm and Cancel buttons")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("log", type=Path, help="fresh Cthulhu debug log")
|
||||
arguments = parser.parse_args()
|
||||
try:
|
||||
check_log(arguments.log)
|
||||
except (OSError, ValueError, json.JSONDecodeError) as error:
|
||||
parser.exit(1, f"Steam Big Picture check failed: {error}\n")
|
||||
print("Steam Big Picture arrows-first focus, menu, and dialog check passed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user