import json, os, sys sys.stdout.reconfigure(encoding='utf-8') from pathlib import Path os.environ['QT_QPA_PLATFORM'] = 'offscreen' os.environ['QTWEBENGINE_CHROMIUM_FLAGS'] = '--disable-gpu --disable-gpu-compositing' os.environ['QT_OPENGL'] = 'software' from PySide6.QtCore import QTimer, QUrl, Qt from PySide6.QtWidgets import QApplication QApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts) from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtWebEngineCore import QWebEnginePage class DebugPage(QWebEnginePage): def javaScriptConsoleMessage(self, level, message, line, source): print(f'JS: {message} at {line}', flush=True) app = QApplication([]) view = QWebEngineView() view.setPage(DebugPage(view)) view.resize(1440, 1000) view.show() cases = [ {"loading": False, "accounts": [], "error": "", "manualSetupRequired": False, "cloudBackup": {"status": status, "message": message}} for status, message in [("waiting", "等待云端上传"), ("running", "正在上传"), ("completed", "新增 23 条消息"), ("failed", "失败 "), ("disabled", "云端上传已关闭")] ] index = 0 def inspect(result): global index result = json.loads(result) if isinstance(result, str) and result else {} expected = cases[index] manual = bool(expected['manualSetupRequired'] and not expected['loading']) valid = result.get('manualCount') == (3 if manual else 0) and result.get('refreshDisabled') == expected['loading'] valid = valid and result.get('cloudStatus') == expected['cloudBackup']['status'] and result.get('cloudText', '').strip() == expected['cloudBackup']['message'] and result.get('injectedImages') == 0 if expected['error']: valid = valid and result.get('unready') and not result.get('ready') print(f"Database UI case {index + 1}: {'PASS' if valid else 'FAIL'} {result}", flush=True) if not valid: app.exit(2) return index += 1 if index == len(cases): app.exit(0) else: render() def render(): payload = {'ready': True, 'demo': False, 'view': 'wechatdb', 'wechatDb': cases[index]} view.page().runJavaScript('window.applyState(' + json.dumps(payload) + ');') probe = """JSON.stringify({ cloudStatus: document.querySelector('[data-cloud-backup-status]')?.dataset.cloudBackupStatus, cloudText: document.querySelector('[data-cloud-backup-status]')?.textContent, injectedImages: document.querySelectorAll('[data-cloud-backup-status] img').length, manualCount: document.querySelectorAll('[data-action="wechat-db-directory"], [data-action="wechat-db-acquire"], [data-action="wechat-db-import"]').length, refreshDisabled: document.querySelector('[data-action="wechat-db-refresh"]').disabled, unready: document.body.innerText.includes('未就绪'), ready: document.body.innerText.includes('已读取') })""" QTimer.singleShot(300, lambda: view.page().runJavaScript(probe, inspect)) def loaded(ok): if not ok: app.exit(3) return view.page().runJavaScript('window.showConsoleView("wechatdb");') render() view.loadFinished.connect(loaded) view.load(QUrl.fromLocalFile(str(Path.cwd() / 'assets/ui/zhenyang-ai-console.html'))) QTimer.singleShot(25000, lambda: app.exit(4)) raise SystemExit(app.exec())