XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
"""Measure real guest Markdown preview via physical QMP input, without injecting DOM/model state."""
import hashlib,json,re,time
from pathlib import Path
from PIL import Image

def run_preview_performance(qmp,read_log,wait_log,screenshot,width,height,scale,pointer):
    results={'Kind':'NativeMarkdownPreviewResponsiveness','Passed':False,'GpuClaimed':False,'AutomaticDomInjection':False,'Samples':[]}
    def move(x,y):
        target=[round(x*scale),round(y*scale)]
        while pointer!=target:
            dx=max(-80,min(80,target[0]-pointer[0]));dy=max(-80,min(80,target[1]-pointer[1]))
            qmp('input-send-event',{'events':[{'type':'rel','data':{'axis':'x','value':dx}},{'type':'rel','data':{'axis':'y','value':dy}}]})
            pointer[0]+=dx;pointer[1]+=dy;time.sleep(.018)
    def button(down):qmp('input-send-event',{'events':[{'type':'btn','data':{'down':down,'button':'left'}}]})
    def click(x,y):move(x,y);button(True);time.sleep(.08);button(False)
    def key(code):qmp('human-monitor-command',{'command-line':'sendkey '+code});time.sleep(.12)
    def capture(name):
        p=Path(screenshot(name));return {'Path':str(p),'Sha256':hashlib.sha256(p.read_bytes()).hexdigest()}
    def wait_changed(after,timeout=90):
        deadline=time.monotonic()+timeout
        while time.monotonic()<deadline:
            matches=list(re.finditer(r'XFE_WEBSITE_DOCUMENT_PROOF_BEGIN\r?\n(.*?)\r?\nXFE_WEBSITE_DOCUMENT_PROOF_END',read_log()[after:],re.S))
            for match in matches:
                try:
                    proof=json.loads(match.group(1))
                    if (proof.get('Heading') or {}).get('Text')=='XFESystem 文档预览':return proof
                except json.JSONDecodeError:pass
            time.sleep(.04)
        raise AssertionError('Actual Markdown preview proof did not arrive')
    try:
        start=len(read_log());click(60,120);wait_log('XFE_DESKTOP_ACTIVE|Files',start,30)
        click(220,258);wait_log('XFE_DESKTOP_ACTIVE|Editor',start,30)
        results['SourceEditor']=capture('PreviewPerformance-Source')
        for index in range(2):
            begin=len(read_log());started=time.monotonic();click(300,137)
            proof=wait_changed(begin);navigation=time.monotonic()-started
            # Measure a real framebuffer containing the expected heading ink.
            viewport=(194,110,800,500)
            rect=(proof.get('Heading') or {}).get('Bounds') or {}
            wait_log('XFE_WINDOW_STATE|'+str(3+index)+'|Browser|',begin,90)
            from TestWebsiteDocument import capture_document
            frame=capture_document(screenshot,'PreviewPerformance-Opened-'+str(index),read_log,proof,scale,require_heading=True)
            first_paint=time.monotonic()-started
            results['Samples'].append({'ClickToActualDocumentSeconds':navigation,'Proof':proof,'Frame':frame,'ClickToFirstVerifiedPaintSeconds':first_paint})
            # System-wide hotkey responsiveness after a preview has opened.
            before=len(read_log());t=time.monotonic();key('meta_l-d');wait_log('XFE_DESKTOP_FLAGS|0|0|Active|0',before,60)
            results['Samples'][-1]['WinDResponseSeconds']=time.monotonic()-t
            key('meta_l-d');time.sleep(.15)
            # Scroll while the real document is present; no synthetic viewport or JS.
            move(700,400);before=len(read_log());scroll_start=time.monotonic()
            for n in range(24):
                qmp('input-send-event',{'events':[{'type':'btn','data':{'down':True,'button':'wheel-down'}},{'type':'btn','data':{'down':False,'button':'wheel-down'}}]});time.sleep(.04)
            time.sleep(1)
            results['Samples'][-1]['ScrollHostSeconds']=time.monotonic()-scroll_start
            results['Samples'][-1]['ScrollFrame']=capture('PreviewPerformance-Scrolled-'+str(index))
            before=len(read_log());t=time.monotonic();key('alt-f4');wait_log('XFE_DESKTOP_ACTIVE|Editor',before,60)
            results['Samples'][-1]['CloseResponseSeconds']=time.monotonic()-t
            time.sleep(.15)
        results['Passed']=True
        return results
    except Exception as error:
        results['Failure']=str(error);raise
    finally:
        folder=Path(screenshot('PreviewPerformance-Final')).parent
        (folder/'PreviewPerformance.json').write_text(json.dumps(results,ensure_ascii=False,indent=2),encoding='utf-8')