66 lines
4.4 KiB
Python
66 lines
4.4 KiB
Python
"""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, QMainWindow
|
|
from unittest.mock import Mock
|
|
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([])
|
|
sys.path.insert(0, r'C:\kefu\wechat_rpa')
|
|
import wechat_gui_qt as qt
|
|
qt.CONSOLE_HTML=Path(r'C:\wechat_rpa\assets\ui\zhenyang-ai-console.html')
|
|
owner=QMainWindow();owner._push_console_state=Mock()
|
|
view=qt.ConsoleShell(owner);owner.setCentralWidget(view);owner.resize(1440,1000);owner.show()
|
|
page=view.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':'【合成审核提醒内容】仅渲染测试,不发送消息'}}}
|
|
unsupported={'view':'automation','ready':True,'demo':False,'automation':{'transport':'visual','reviewAssistant':{'supported':False,'ready':False,'enabled':False,'reason':'当前版本不支持协议审核提醒'}}}
|
|
js('window.applyState('+json.dumps(unsupported)+');render("automation");')
|
|
assert js('document.querySelector("[data-action=review-assistant-toggle]").disabled')
|
|
assert js('document.querySelector("[data-action=review-assistant-choose]").disabled')
|
|
assert '当前版本不支持' in js('document.body.textContent')
|
|
js('window.applyState('+json.dumps(state)+');render("automation");')
|
|
assert not js('document.querySelector("[data-action=review-assistant-toggle]").disabled')
|
|
js('window.qtBridge={setReviewAssistantEnabled:(payload,cb)=>cb(JSON.stringify({ok:true,message:"synthetic"}))};document.querySelector("[data-action=review-assistant-toggle]").click();')
|
|
js('window.fit(); document.querySelector("details").open=true;')
|
|
metrics=[]
|
|
for ms in (700,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-shell-{len(metrics)}-{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-shell-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)
|