Make production acceptance checks retain evidence and clean test records

This commit is contained in:
2026-10-28 15:42:10 +08:00
parent bfb646fcc9
commit 833a345b85
2 changed files with 19 additions and 3 deletions
+3 -3
View File
@@ -17,7 +17,7 @@ const assert=require('node:assert/strict');
const metrics=[];
for(let i=1;i<=27;i++){
const id='ref-'+String(i).padStart(2,'0');await page.goto(base+'/studio/layouts/'+id,{waitUntil:'networkidle'});await page.locator('article.native-layout').screenshot({path:dir+'/'+id+'.png'});
const m=await page.locator('article.native-layout').evaluate(el=>({id:el.dataset.layoutId,elements:el.querySelectorAll('[data-element]').length,width:el.clientWidth,height:el.clientHeight,overflow:[...el.querySelectorAll('.native-copy')].filter(e=>e.scrollHeight>e.clientHeight+2||e.scrollWidth>e.clientWidth+2).map(e=>e.closest('[data-element]').dataset.element)}));metrics.push(m);
const m=await page.locator('article.native-layout').evaluate(el=>({id:el.dataset.layoutId,elements:el.querySelectorAll('[data-element]').length,width:el.clientWidth,height:el.clientHeight,overflow:[...el.querySelectorAll('.native-copy')].filter(e=>e.scrollHeight>e.clientHeight+2||e.scrollWidth>e.clientWidth+2).map(e=>e.closest('[data-element]').dataset.element)}));metrics.push(m);await writeFile(dir+'/metrics.json',JSON.stringify({metrics,images,errors},null,2));
}
await page.goto(base+'/studio',{waitUntil:'networkidle'});assert.equal(await page.locator('.library-item').count(),27);await page.screenshot({path:dir+'/catalog-desktop.png',fullPage:true});
const verify=JSON.parse(await readFile('/tmp/studio-library/verification.json','utf8'));
@@ -27,8 +27,8 @@ const assert=require('node:assert/strict');
for(const slug of ['learning-skills-template','layout-selection']){await page.goto(base+'/studio/ideas/'+slug,{waitUntil:'networkidle'});await page.screenshot({path:dir+'/tool-'+slug+'.png',fullPage:true})}
await page.setViewportSize({width:390,height:844});await page.goto(base+'/studio',{waitUntil:'networkidle'});assert.ok(await page.evaluate(()=>document.documentElement.scrollWidth<=innerWidth));await page.screenshot({path:dir+'/catalog-mobile.png',fullPage:true});
await page.goto(base+verify.results[0].url,{waitUntil:'networkidle'});await page.screenshot({path:dir+'/standard-mobile.png',fullPage:true});
await page.goto(base+'/categories?category='+encodeURIComponent('文档入口'),{waitUntil:'networkidle'});await page.screenshot({path:dir+'/document-entries.png',fullPage:true});
assert.equal(images.filter(r=>new URL(r.path,base).pathname.startsWith('/api/media/')).length,0,'Display must never fetch originals');assert.equal(errors.length,0,JSON.stringify(errors));
await page.goto(base+'/categories?category='+encodeURIComponent('文档入口'),{waitUntil:'domcontentloaded',timeout:60000});await page.getByRole('heading',{name:'分类',exact:true}).waitFor({state:'visible'});await page.screenshot({path:dir+'/document-entries.png',fullPage:true});
assert.equal(images.filter(r=>new URL(r.path,base).pathname.startsWith('/api/media/')).length,0,'Display must never fetch originals');assert.equal(errors.length,0,JSON.stringify(errors));for(const image of images){assert.equal(new URL(image.path,base).pathname,'/api/preview');assert.equal(image.status,200);assert.equal(image.type,'image/webp');assert.ok(image.bytes>0&&image.bytes<=220000)}
await writeFile(dir+'/metrics.json',JSON.stringify({metrics,images,errors},null,2));await browser.close();
console.log(JSON.stringify({pages:27,errors:errors.length,displayImages:images.length,originalImageRequests:0,overflow:metrics.filter(m=>m.overflow.length)}));
})().catch(e=>{console.error(e.message);process.exit(1)});