chore: establish YCode replication baseline and TODO

This commit is contained in:
xiaohan.yuan committed 2026-10-17 02:43:49 +08:00
commit 6dc59f89ba
1118 files changed
+196002

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
// Local YCode fixture behavior/rendering QA. Does not inspect WorkBuddy.
if (!process.versions.electron) {
const env={...process.env}; delete env.ELECTRON_RUN_AS_NODE
const result=require('node:child_process').spawnSync(require('electron'),[__filename],{env,windowsHide:true,stdio:'inherit',timeout:60000})
process.exit(result.status??1)
}
const {app,BrowserWindow}=require('electron')
const fs=require('node:fs/promises'),path=require('node:path'),assert=require('node:assert/strict')
app.setPath('userData',path.resolve('.tmp/preview-qa-user-data'))
app.disableHardwareAcceleration()
let win
const errors=[]
const read=code=>win.webContents.executeJavaScript(code)
async function waitFor(code){for(let n=0;n<120;n++){if(await read(code))return;await new Promise(r=>setTimeout(r,40))}throw new Error('Condition failed: '+code)}
async function clickText(selector,text){await read(`Array.from(document.querySelectorAll(${JSON.stringify(selector)})).find(n=>n.textContent===${JSON.stringify(text)}).click()`)}
async function settled(){await read('document.fonts.ready.then(()=>Promise.all(document.getAnimations().filter(a=>Number.isFinite(a.effect.getTiming().iterations)).map(a=>a.finished.catch(()=>{})))).then(()=>new Promise(r=>requestAnimationFrame(()=>requestAnimationFrame(r))))')}
async function shot(name){await settled();await new Promise(r=>{win.webContents.once('paint',r);win.webContents.invalidate()});await fs.writeFile(path.resolve('.tmp/'+name),(await win.webContents.capturePage()).toPNG())}
app.whenReady().then(async()=>{
win=new BrowserWindow({show:false,useContentSize:true,width:1336,height:901,webPreferences:{offscreen:true,contextIsolation:true}})
win.webContents.on('console-message',(_event,level,message)=>{if(level===3)errors.push(message)})
await win.loadURL('http://127.0.0.1:8789/?fixture=artifact-source')
await waitFor("document.querySelectorAll('.msg__artifact').length>=5")
await clickText('.msg__artifact','异步 Markdown')
await waitFor("document.querySelector('.markdown-viewer')?.textContent.includes('异步加载成功')")
assert.equal(await read('document.documentElement.dataset.fixtureReadText'),'notes/readme.md')
await clickText('.msg__artifact','慢速 Markdown')
await clickText('.msg__artifact','缓存 Markdown')
await waitFor("document.querySelector('.markdown-viewer')?.textContent.includes('缓存内容')")
await new Promise(r=>setTimeout(r,350))
assert.ok(await read("!document.querySelector('.markdown-viewer').textContent.includes('过期读取')"))
await clickText('.msg__artifact','HTML 预览')
await waitFor("document.querySelector('.artifact-html-frame')?.srcdoc.includes('HTML 预览成功')")
const html=await read(`(()=>{const e=document.querySelector('.artifact-html-frame'),h=document.querySelector('.artifact-media-preview__header');return{sandbox:e.getAttribute('sandbox'),height:h.getBoundingClientRect().height,frameWidth:e.getBoundingClientRect().width,frameHeight:e.getBoundingClientRect().height,padding:getComputedStyle(document.querySelector('.resource-preview__body')).padding}})()`)
assert.equal(html.height,48)
assert.equal(html.padding,'0px')
assert.ok(html.frameWidth>300)
assert.ok(html.frameHeight>300)
assert.ok(html.sandbox.includes('allow-scripts'))
assert.ok(!html.sandbox.includes('allow-same-origin'))
const frame = win.webContents.mainFrame.framesInSubtree.find(frame=>frame!==win.webContents.mainFrame)
assert.ok(frame,'HTML preview must have a child frame')
for(let n=0;n<80;n++){if(await frame.executeJavaScript("document.body?.textContent.includes('HTML 预览成功')"))break;await new Promise(r=>setTimeout(r,40))}
html.renderedText=await frame.executeJavaScript('document.body.textContent')
assert.match(html.renderedText,/HTML 预览成功/)
await read("document.querySelector('.artifact-media-preview__button').click()")
await waitFor("!!document.documentElement.dataset.fixtureDownload")
assert.equal(JSON.parse(await read('document.documentElement.dataset.fixtureDownload')).filename,'preview.html')
await shot('conversation-artifact-html-2026-10-15.png')
await clickText('.msg__artifact','读取失败')
await waitFor("document.querySelector('.custom-artifact-error[role=alert]')?.textContent.includes('加载失败')")
await win.loadURL('http://127.0.0.1:8789/?fixture=dialogue-media')
await waitFor("document.querySelectorAll('img.cr-image-block').length===2")
await read("document.querySelector('img.cr-image-block').click()")
await waitFor("document.querySelector('.wb-image-preview__image')?.naturalWidth>0")
await read("document.querySelector('.wb-image-preview [aria-label=放大]').click()")
assert.equal(await read("document.querySelector('.wb-image-preview__scale').textContent"),'125%')
await read("document.querySelector('.wb-image-preview [aria-label=向左旋转]').click()")
assert.ok(await read("document.querySelector('.wb-image-preview__image-wrap').style.transform.includes('rotate(-90deg)')"))
await read("document.querySelector('.wb-image-preview [aria-label=镜像]').click()")
assert.ok(await read("document.querySelector('.wb-image-preview__image-wrap').style.transform.includes('scaleX(-1)')"))
await read("document.querySelector('.wb-image-preview [aria-label=下一张]').click()")
await waitFor("document.querySelector('.wb-image-preview__count')?.textContent==='2/2'")
assert.equal(await read("document.querySelector('.wb-image-preview__scale').textContent"),'100%')
await read("document.querySelector('.wb-image-preview [aria-label=下载图片]').click()")
await waitFor("!!document.documentElement.dataset.fixtureImageDownload")
await settled()
const image=await read(`(()=>{const s=document.querySelector('.wb-image-preview__stage'),t=document.querySelector('.wb-image-preview__toolbar'),c=document.querySelector('.wb-image-preview__close-area');return{stage:{width:s.getBoundingClientRect().width,height:s.getBoundingClientRect().height},toolbarBottom:getComputedStyle(t).bottom,closeTop:getComputedStyle(c).top,closeRight:getComputedStyle(c).right,desktop:document.body.dataset.electronDesktop,platform:document.body.dataset.platform}})()`)
assert.deepEqual(image.stage,{width:1256,height:701})
assert.equal(image.toolbarBottom,'40px')
assert.equal(image.desktop,'true')
assert.equal(image.closeTop,'40px')
assert.equal(image.closeRight,'148px')
await shot('conversation-image-preview-2026-10-15.png')
win.webContents.sendInputEvent({type:'keyDown',keyCode:'Escape'})
win.webContents.sendInputEvent({type:'keyUp',keyCode:'Escape'})
await waitFor("!document.querySelector('.wb-image-preview')")
const report={scope:'YCode offline fixtures only; original application parity unverified',html,image,markdownRead:true,staleReadIgnored:true,readErrorVisible:true,imageZoomRotateFlipGalleryDownloadEscape:true,consoleErrors:errors}
assert.deepEqual(errors,[])
await fs.writeFile(path.resolve('.tmp/conversation-preview-qa.json'),JSON.stringify(report,null,2))
console.log(JSON.stringify(report))
app.quit()
}).catch(error=>{console.error(error);app.exit(1)})