# -*- coding: utf-8 -*- """收尾三个测试问题。 1. test_image_modes.py 主线程直接调 Tk(winfo_screenwidth / update)会报 "main thread is not in main loop"。所有 Tk 访问都要走 ui_call。 2. test_selfcheck.py 被控端现在跑静默模式,日志写在 data\\silent.log,不再是 运行日志.txt。 3. test_pair_once_flow.py feature_list 拿不到内容,先打印真实回复再看。 """ from __future__ import annotations import sys from pathlib import Path TESTS = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\_tests") # ---------------- 1. test_image_modes ---------------- IMAGE = TESTS / "test_image_modes.py" GEO_OLD = '''def wait_geometry(win, root, timeout: float = 4.0): """轮询直到窗口几何可用(同时泵事件)。""" deadline = time.time() + timeout while time.time() < deadline: try: root.update() except tk.TclError: return None rect = geometry_of(win) if rect: return rect time.sleep(0.04) return None''' GEO_NEW = '''def ui_read(agent, fn, timeout: float = 4.0): """所有 Tk 调用都要走界面线程,否则报 main thread is not in main loop。""" try: return agent.ui_call(fn, timeout=timeout) except Exception: # noqa: BLE001 return None def wait_geometry(win, agent, timeout: float = 4.0): """轮询直到窗口几何可用。""" if win is None: return None deadline = time.time() + timeout while time.time() < deadline: rect = ui_read(agent, lambda: _read_geometry(win), timeout=3.0) if rect: return rect time.sleep(0.05) return None def _read_geometry(win): try: if not win.winfo_exists(): return None win.update_idletasks() left = win.winfo_rootx() top = win.winfo_rooty() width = win.winfo_width() height = win.winfo_height() if width <= 1 or height <= 1: return None return (left, top, width, height) except tk.TclError: return None''' SCREEN_OLD = ''' screen_w = agent.root.winfo_screenwidth() screen_h = agent.root.winfo_screenheight()''' SCREEN_NEW = ''' screen_w, screen_h = agent.screen_size() # 不直接碰 Tk''' ROOT_OLD = ''' actions = Actions(agent, store) root = agent.root''' ROOT_NEW = ''' actions = Actions(agent, store)''' # 所有 wait_geometry(win, root) -> wait_geometry(win, agent) CALL_OLD = "wait_geometry(actions._image_window, root)" CALL_NEW = "wait_geometry(actions._image_window, agent)" def patch_image() -> bool: text = IMAGE.read_text(encoding="utf-8") ok = True for old, new, tag in ((GEO_OLD, GEO_NEW, "wait_geometry 走界面线程"), (SCREEN_OLD, SCREEN_NEW, "屏幕尺寸不碰 Tk"), (ROOT_OLD, ROOT_NEW, "去掉 root 变量")): if old not in text: print(f" [跳过] image / {tag} —— 锚点没找到") ok = False continue text = text.replace(old, new, 1) print(f" image / {tag}: OK") count = text.count(CALL_OLD) text = text.replace(CALL_OLD, CALL_NEW) print(f" image / wait_geometry 调用点改了 {count} 处") IMAGE.write_text(text, encoding="utf-8") return ok # ---------------- 2. test_selfcheck ---------------- SELF = TESTS / "test_selfcheck.py" LOG_OLD = ''' log_path = data_dir / "运行日志.txt" log_text = log_path.read_text(encoding="utf-8") if log_path.is_file() else ""''' LOG_NEW = ''' # 被控端现在跑静默模式,日志在 silent.log;旧版是 运行日志.txt log_text = "" for name in ("silent.log", "运行日志.txt"): log_path = data_dir / name if log_path.is_file(): try: log_text += log_path.read_text(encoding="utf-8", errors="replace") except OSError: pass''' def patch_selfcheck() -> bool: text = SELF.read_text(encoding="utf-8") if LOG_OLD not in text: print(" [跳过] selfcheck / 日志路径 —— 锚点没找到") return False SELF.write_text(text.replace(LOG_OLD, LOG_NEW, 1), encoding="utf-8") print(" selfcheck / 日志路径: OK") return True # ---------------- 3. test_pair_once_flow 加调试 ---------------- FLOW = TESTS / "test_pair_once_flow.py" FLOW_OLD = ''' reply = talk.call({"cmd": "feature_list"}, timeout=25) features = reply.get("features") or [] check("已配对设备能拿到功能列表", reply.get("ok") is True and len(features) > 100, f"{len(features)} 个")''' FLOW_NEW = ''' reply = talk.call({"cmd": "feature_list"}, timeout=25) features = reply.get("features") or [] if not features or reply.get("ok") is not True: print(f" (feature_list 原始回复: {str(reply)[:300]})") check("已配对设备能拿到功能列表", reply.get("ok") is True and len(features) > 100, f"{len(features)} 个, ok={reply.get('ok')}, " f"err={reply.get('error')}")''' def patch_flow() -> bool: text = FLOW.read_text(encoding="utf-8") if FLOW_OLD not in text: print(" [跳过] flow / 调试输出 —— 锚点没找到") return False FLOW.write_text(text.replace(FLOW_OLD, FLOW_NEW, 1), encoding="utf-8") print(" flow / 调试输出: OK") return True def main() -> int: ok = patch_image() print() ok = patch_selfcheck() and ok print() ok = patch_flow() and ok import ast for path in (IMAGE, SELF, FLOW): try: ast.parse(path.read_text(encoding="utf-8")) except SyntaxError as exc: print(f" {path.name}: 语法错误 {exc}") ok = False print(" 语法检查完成") return 0 if ok else 1 if __name__ == "__main__": sys.exit(main())