"""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')
"""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')