Files
ios-location-track/tests/setup_window_selftest.py

120 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""自动验证「环境准备」窗口的检测 → 确认 → 放行 流程(不需要人工点按钮)。
验证点:
1. 所有项最终都能检测完(不会卡在「检测中…」)
2. 全部就绪时,「进入程序」按钮变为可用
3. 调用 _on_confirm 后 proceeded=True(main() 才会继续启动服务)
4. 关闭窗口(_on_close)时 proceeded=False(main() 应当退出)
"""
from __future__ import annotations
import sys
import time
import traceback
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
import tkinter as tk # noqa: E402
from core.setup_window import SetupWindow # noqa: E402
FAILURES: list[str] = []
CALLBACK_ERRORS: list[str] = []
def check(name: str, ok: bool, detail: str = "") -> None:
print(f" [{'PASS' if ok else 'FAIL'}] {name}" + (f" — {detail}" if detail else ""))
if not ok:
FAILURES.append(name)
def pump(root: tk.Tk, seconds: float) -> None:
"""手动驱动 tkinter 事件循环(不进入 mainloop,便于断言)。"""
deadline = time.monotonic() + seconds
while time.monotonic() < deadline:
try:
root.update()
except tk.TclError as exc:
print(f" [pump] TclError 中断:{exc}")
return
time.sleep(0.02)
def main() -> int:
root = tk.Tk()
def _on_cb_error(exc_type, exc_value, exc_tb) -> None: # Tk 回调里的异常
text = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
CALLBACK_ERRORS.append(text)
print(f" [回调异常] {exc_value}")
root.report_callback_exception = _on_cb_error
win = SetupWindow(root, title="自检窗口")
# Apple 驱动检测要做 27015 协议往返,留足时间
pump(root, 25.0)
print(" 各项状态:")
for item in win.items:
st = win.state[item.key]
print(f" {item.key:16s} required={item.required} ok={st.get('ok')} "
f"busy={st.get('busy')} detail={str(st.get('detail'))[:46]}")
try:
exists = bool(root.winfo_exists())
except tk.TclError as exc:
exists = False
print(f" 窗口已不可用:{exc}")
print(f" 窗口存在:{exists} proceeded={win.proceeded}")
check("窗口在检测期间没有被意外销毁", exists)
check("Tk 回调没有抛异常", not CALLBACK_ERRORS,
f"{len(CALLBACK_ERRORS)} 个" if CALLBACK_ERRORS else "")
stuck = [i.key for i in win.items
if win.state[i.key].get("ok") is None and not win.state[i.key].get("busy")]
check("没有卡在「检测中…」的项", not stuck, str(stuck))
required = [i for i in win.items if i.required]
pending = [i.key for i in required if win.state[i.key].get("ok") is not True]
check("必需项全部就绪(本机环境)", not pending, str(pending))
try:
enabled = bool(win.confirm_button.instate(["!disabled"]))
detail = f"state={win.confirm_button.state()}"
except tk.TclError as exc:
enabled, detail = False, f"控件已失效:{exc}"
check("「进入程序」按钮可用", enabled, detail)
# 模拟点击「进入程序」
win._on_confirm()
check("点击后 proceeded=True", win.proceeded is True, f"proceeded={win.proceeded}")
try:
root.destroy()
except Exception:
pass
# 再测「关闭窗口」分支
root2 = tk.Tk()
win2 = SetupWindow(root2, title="自检窗口2")
pump(root2, 1.0)
win2._on_close()
check("关闭窗口时 proceeded=False", win2.proceeded is False,
f"proceeded={win2.proceeded}")
try:
root2.destroy()
except Exception:
pass
print()
if FAILURES:
print(f"失败 {len(FAILURES)} 项:{FAILURES}")
return 1
print("全部通过")
return 0
if __name__ == "__main__":
sys.exit(main())