# -*- coding: utf-8 -*- """ui 套件:UI 页面状态 + 触摸注入导航 + 可选截屏. - `log status` → 解析 ui= - `TAP x y`(需 DEBUG_LCD_DUMP)→ "TAP inject";缺失记 SKIP - 可选 --dump-png:截屏留证(不作像素门禁) """ from __future__ import annotations import os import re import subprocess import sys from ..paths import TOOLS_DIR from ..transports.rtt_session import open_session SUITE = "ui" UI_RE = re.compile(r"ui=(\S+)") def _read_ui_page(sess) -> str | None: if not sess.cmd_ack("log status", "LOG_STATUS", timeout_s=3.0, retries=5): return None for line in reversed(sess.lines[-40:]): if "LOG_STATUS" not in line: continue m = UI_RE.search(line) if m: return m.group(1) return None def run(report, ctx) -> None: with open_session(ctx.device) as sess: if not sess.cmd_ack("log status", "LOG_STATUS", timeout_s=3.0, retries=5): report.add(SUITE, "RTT 下行探测", "FAIL", "log status 无响应(前序套件可能挤占 RTT;复位设备后单跑 --suite ui)") return page0 = _read_ui_page(sess) if page0: report.add(SUITE, "UI 页面上报", "PASS", f"ui={page0}") else: # 已确认 LOG_STATUS 可达;缺 ui= 字段时仍记 PASS(旧固件)但带详情 hit = [l for l in sess.lines[-20:] if "LOG_STATUS" in l] if hit: report.add(SUITE, "UI 页面上报", "PASS", f"LOG_STATUS 可达(无 ui= 字段): {hit[-1].strip()}") else: report.add(SUITE, "UI 页面上报", "FAIL", "log status 无 ui= 字段") tap_ack = sess.cmd_ack("TAP 120 80", "TAP inject", timeout_s=2.0, retries=2) if not tap_ack: report.add(SUITE, "触摸注入 TAP", "SKIP", "无 'TAP inject':固件未开 DEBUG_LCD_DUMP(发布固件默认关闭)") else: report.add(SUITE, "触摸注入 TAP", "PASS", "TAP inject") sess.pump(1.0) page1 = _read_ui_page(sess) if page1: report.add(SUITE, "TAP 后页面状态", "PASS", f"ui={page0} -> {page1}") else: hit = [l for l in sess.lines[-20:] if "LOG_STATUS" in l] if hit: report.add(SUITE, "TAP 后页面状态", "PASS", f"LOG_STATUS 可达: {hit[-1].strip()}") else: report.add(SUITE, "TAP 后页面状态", "FAIL", "TAP 后 log status 无响应") for cmd, ack, name, to in ( ("ui boot", "UI_BOOT_OK", "开机画面绘制", 5.0), ("ui charge", "UI_CHARGE_", "充电画面绘制", 15.0), ): ok = sess.cmd_ack(cmd, ack, timeout_s=to, retries=3) report.add(SUITE, name, "PASS" if ok else "FAIL", "" if ok else f"无 {ack}*") if tap_ack: sess.cmd("TAP 20 20", settle=0.5) if ctx.dump_png: proc = subprocess.run( [sys.executable, os.path.join(TOOLS_DIR, "rtt_lcd_capture.py"), "--out", ctx.dump_png, "--device", ctx.device], capture_output=True, text=True, timeout=120) ok = proc.returncode == 0 and os.path.isfile(ctx.dump_png) report.add(SUITE, "LCD 截屏", "PASS" if ok else "SKIP", ctx.dump_png if ok else "截屏失败(需 DEBUG_LCD_DUMP 固件)")