Files
kefu/deploy/ui-performance-20260916/layout.mjs
T
2026-09-21 10:34:06 +08:00

50 lines
3.4 KiB
JavaScript

import {createRequire} from 'node:module';
import {writeFileSync,mkdirSync} from 'node:fs';
const require=createRequire('C:/kefu/admin-web/package.json');
const {chromium}=require('playwright');
const root='C:/kefu/deploy/ui-performance-20260916';mkdirSync(`${root}/qa`,{recursive:true});
const browser=await chromium.launch({executablePath:'C:/Program Files/Google/Chrome/Application/chrome.exe',headless:true});
const cases=[['1080',1630,888,1],['4k-200',1630,888,2],['6k-300',1630,888,3],['4k-300',1280,680,3],['1080-200',960,500,2],['1080-300',640,330,3],['fractional',1200,700,1.25]];
const pages=['auto','queue','archive','ai','automation','logs','wechatdb','system'];
const results=[],errors=[];
try{
for(const [name,width,height,dpr] of cases){
const context=await browser.newContext({viewport:{width,height},deviceScaleFactor:dpr});
await context.route('**/*',route=>route.request().url().startsWith('file:')?route.continue():route.abort());
const page=await context.newPage();page.on('pageerror',e=>errors.push({name,error:e.message}));
await page.goto(`file:///${root}/payload/assets/ui/zhenyang-ai-console.html`);
await page.waitForTimeout(500);
for(const view of pages){
await page.evaluate(view=>{STATE.ready=true;STATE.demo=false;STATE.view=view;render(view);fit();},view);
await page.waitForTimeout(90);
const result=await page.evaluate(()=>{
const main=document.getElementById('main'),stage=document.getElementById('stage');
const nav=document.querySelector('[data-view="auto"]'),rect=nav.getBoundingClientRect();
return {view:STATE.view,layout:stage.dataset.layout,zoom:Number(stage.style.zoom),dpr:devicePixelRatio,
mainWidth:main.clientWidth,contentWidth:main.scrollWidth,font:getComputedStyle(main).fontSize,
navWidth:rect.width,navHeight:rect.height,mainHeight:main.clientHeight,contentHeight:main.scrollHeight,
overflow:[...main.querySelectorAll('*')].filter(e=>e.getBoundingClientRect().right>main.getBoundingClientRect().right+2&&e.clientWidth>0).slice(0,8).map(e=>({tag:e.tagName,cls:e.className,text:e.textContent.slice(0,45)}))};
});
results.push({name,...result});
if(view==='auto'||(name==='1080-300'&&['ai','system','automation'].includes(view)))await page.screenshot({path:`${root}/qa/${name}-${view}.png`});
if(result.contentWidth>result.mainWidth+2)console.log(JSON.stringify({overflow:name,...result}));
}
if(name==='1080'){
for(const pref of ['200%','300%','自动']){
await page.evaluate(pref=>{STATE.system={...(STATE.system||{}),scale:pref};render('system');fit();},pref);
const value=await page.locator('#stage').evaluate(e=>Number(e.style.zoom));
if(Math.abs(value-({'200%':1.7,'300%':2.55,'自动':.85}[pref]))>.001)throw Error('Manual scaling failed');
}
await page.setViewportSize({width:780,height:400});await page.waitForTimeout(150);
if(await page.locator('#stage').evaluate(e=>Number(e.style.zoom))!==.85)throw Error('Resize changed font density');
const settings=page.locator('[data-view="system"]');await settings.click();
await page.getByRole('heading',{name:'系统设置',exact:true}).waitFor();
}
await context.close();
}
writeFileSync(`${root}/qa/results.json`,JSON.stringify({results,errors},null,2));
const bad=results.filter(r=>r.contentWidth>r.mainWidth+2);
console.log(JSON.stringify({checks:results.length,overflow:bad.length,pageErrors:errors}));
if(bad.length||errors.length)process.exitCode=1;
}finally{await browser.close();}