Files
kefu/wechat_rpa/tmp/qt_engine_card_smoke.py
T
2026-08-27 14:04:28 +08:00

148 lines
5.4 KiB
Python
Raw 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.
# -*- coding: utf-8 -*-
"""「检测引擎」卡片冒烟测试:offscreen 实例化 DashboardPage
验证初始状态、信号契约、radio 置灰联动;并轻量验证
MainWindow 的设置加载校验与合并保存逻辑。
"""
from __future__ import annotations
import json
import os
import sys
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
sys.argv = [sys.argv[0], "--qt-smoke-test"]
from PySide6.QtWidgets import QApplication
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import wechat_gui_qt as gui
FAILED = []
def check(name: str, cond: bool, detail: str = "") -> None:
tag = "PASS" if cond else "FAIL"
print(f"[{tag}] {name}" + (f" ({detail})" if detail else ""))
if not cond:
FAILED.append(name)
app = QApplication.instance() or QApplication(sys.argv)
# ---------- 1. DashboardPage 初始状态 ----------
page = gui.DashboardPage(engine_settings={
"engine_a_enabled": True,
"enable_engine_b": False,
"engine_b_data_source": "db",
})
check("引擎A默认勾选", page.engine_a_check.isChecked() is True)
check("引擎B默认勾选(传入False)", page.engine_b_check.isChecked() is False)
check("数据源=db 时仅DB单选", page.engine_b_db_only.isChecked() is True
and page.engine_b_parallel.isChecked() is False)
check("引擎B关闭→数据源置灰", page.engine_b_parallel.isEnabled() is False
and page.engine_b_db_only.isEnabled() is False
and page.engine_b_json_only.isEnabled() is False)
# ---------- 2. 信号契约 ----------
captured: list[dict] = []
page.settingsChanged.connect(captured.append)
# 2a. 打开引擎 B(radio 应恢复可用)
page.engine_b_check.setChecked(True)
check("引擎B打开→数据源恢复可用", page.engine_b_parallel.isEnabled() is True)
check("信号已发射(打开B)", len(captured) == 1, str(captured[-1]) if captured else "none")
# 2b. 切换数据源 → json
page.engine_b_json_only.setChecked(True)
check("信号含 engine_b_data_source=json",
captured and captured[-1].get("engine_b_data_source") == "json",
str(captured[-1]) if captured else "none")
# 2c. 关引擎 A
page.engine_a_check.setChecked(False)
check("信号含 engine_a_enabled=False",
captured and captured[-1].get("engine_a_enabled") is False,
str(captured[-1]) if captured else "none")
check("信号含 enable_engine_b=True",
captured and captured[-1].get("enable_engine_b") is True,
str(captured[-1]) if captured else "none")
# 2d. 键集合完整(不多不少)
last = captured[-1] if captured else {}
expect_keys = {"engine_a_enabled", "enable_engine_b", "engine_b_data_source"}
check("信号键集合完整", set(last.keys()) == expect_keys, str(sorted(last.keys())))
# 2e. parallel 模式
page.engine_b_parallel.setChecked(True)
check("parallel 模式信号", captured[-1].get("engine_b_data_source") == "parallel",
str(captured[-1]))
# ---------- 3. 独立实例默认 parallel ----------
page2 = gui.DashboardPage(engine_settings={})
check("空配置默认 parallel", page2.engine_b_parallel.isChecked() is True)
check("空配置默认双开", page2.engine_a_check.isChecked() is True
and page2.engine_b_check.isChecked() is True)
# ---------- 4. MainWindow 设置加载校验(轻量,不建 WebEngine----------
mw = gui.MainWindow.__new__(gui.MainWindow)
# 指向临时设置文件,避免污染真实配置
import tempfile
from pathlib import Path
tmp_settings = Path(tempfile.mkdtemp()) / "app_settings.json"
tmp_settings.write_text(
'{"engine_a_enabled": false, "enable_engine_b": true, '
'"engine_b_data_source": "weird", "poll_interval": 1.5}',
encoding="utf-8",
)
orig_file = gui.APP_SETTINGS_FILE
gui.APP_SETTINGS_FILE = tmp_settings
try:
loaded = mw._load_runtime_settings()
finally:
gui.APP_SETTINGS_FILE = orig_file
check("加载: engine_a_enabled 转 bool False", loaded.get("engine_a_enabled") is False,
str(loaded.get("engine_a_enabled")))
check("加载: 非法数据源回落 parallel",
loaded.get("engine_b_data_source") == "parallel",
str(loaded.get("engine_b_data_source")))
check("加载: enable_engine_b 保留 True", loaded.get("enable_engine_b") is True)
# ---------- 5. _on_dashboard_engine_settings 合并保存 ----------
saved: dict = {}
class FakePage:
def mark_saved(self, ok, msg): # noqa: N802
pass
def values(self):
return {}
mw.runtime_settings = {"engine_a_enabled": True, "enable_engine_b": True,
"engine_b_data_source": "parallel", "poll_interval": 2.0}
mw.settings_page = FakePage()
logs: list = []
mw.append_log = lambda msg, level="": logs.append((msg, level)) # noqa: E731
mw._sync_auto_launch = lambda enabled: None # noqa: E731
gui.APP_SETTINGS_FILE = tmp_settings
try:
mw._on_dashboard_engine_settings({
"engine_a_enabled": False,
"engine_b_data_source": "db",
})
saved = dict(mw.runtime_settings)
finally:
gui.APP_SETTINGS_FILE = orig_file
check("合并: engine_a_enabled=False 生效", saved.get("engine_a_enabled") is False)
check("合并: engine_b_data_source=db 生效", saved.get("engine_b_data_source") == "db")
check("合并: 未涉及的键保留", saved.get("enable_engine_b") is True
and saved.get("poll_interval") == 2.0)
check("合并: 已持久化到文件",
json.loads(tmp_settings.read_text(encoding="utf-8")).get("engine_a_enabled") is False)
print()
if FAILED:
print(f"RESULT: FAIL ({len(FAILED)}) -> {FAILED}")
sys.exit(1)
print("RESULT: ALL PASS")