"""Read-only production asset rendering; synthetic state and blocked networking.""" import os os.environ['QT_QPA_PLATFORM'] = 'offscreen' import json, sys from pathlib import Path from PySide6.QtCore import QEventLoop, QTimer, QUrl from PySide6.QtWidgets import QApplication from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtWebEngineCore import QWebEnginePage, QWebEngineUrlRequestInterceptor DEST = Path(__file__).parent class DenyNetwork(QWebEngineUrlRequestInterceptor): def interceptRequest(self, info): if info.requestUrl().scheme() in ('http','https','ws','wss'): info.block(True) class Page(QWebEnginePage): def javaScriptConsoleMessage(self, level, message, line, source): print('JS:', str(message), flush=True) app=QApplication([]) view=QWebEngineView(); page=Page(view); view.setPage(page) blocker=DenyNetwork(page); page.profile().setUrlRequestInterceptor(blocker) view.resize(1440,1000);view.show() def wait(ms): loop=QEventLoop();QTimer.singleShot(ms,loop.quit);loop.exec() def js(code): values=[];loop=QEventLoop() def done(value): values.append(value);loop.quit() page.runJavaScript(code,done);QTimer.singleShot(10000,loop.quit);loop.exec() if not values: raise RuntimeError('JS callback timeout') return values[0] loop=QEventLoop();loaded=[] view.loadFinished.connect(lambda ok:(loaded.append(ok),loop.quit())) view.load(QUrl.fromLocalFile(r'C:\wechat_rpa\assets\ui\zhenyang-ai-console.html')) QTimer.singleShot(15000,loop.quit);loop.exec() assert loaded==[True],loaded state={'view':'automation','ready':True,'demo':False,'automation':{'transport':'protocol','reviewAssistant':{ 'supported':True,'ready':True,'enabled':False,'busy':False,'accountId':'168800000000001','accountName':'合成账号', 'recipient':{'id':'S:168800000000001_10001','name':'合成医疗助理','label':'企业微信客户 · 联系编号10001','kind':'企业微信客户','peerId':'10001'}, 'notification':{'message':'等待人工直接回复客户'},'preview':'【合成审核提醒内容】仅渲染测试,不发送消息'}}} js('window.applyState('+json.dumps(state)+');render("automation");fit();') metrics=[] for ms in (50,700,2000): wait(ms) dom=json.loads(js('JSON.stringify({visibility:document.visibilityState,view:STATE.view,mainText:document.querySelector("#main").textContent.length,mainRect:document.querySelector("#main").getBoundingClientRect().toJSON(),screenRect:document.querySelector(".screen").getBoundingClientRect().toJSON(),opacity:getComputedStyle(document.querySelector(".screen")).opacity,transform:getComputedStyle(document.querySelector("#stage")).transform,window:[innerWidth,innerHeight],toggleRect:document.querySelector("[data-action=review-assistant-toggle]").getBoundingClientRect().toJSON()})')) shot=view.grab();path=DEST/f'assistant-settings-independent-{ms}.png';assert shot.save(str(path)) image=shot.toImage();pixels=set(image.pixelColor(x,y).name() for x in range(240,1350,9) for y in range(30,970,9)) dom.update(wait_ms=ms,pixel_colors_main=len(pixels),path=str(path));metrics.append(dom) (DEST/'assistant-render-metrics.json').write_text(json.dumps(metrics,ensure_ascii=False,indent=2),encoding='utf-8') print(json.dumps(metrics,ensure_ascii=False,indent=2),flush=True) view.close();app.processEvents() os._exit(0)