61 lines
4.7 KiB
JavaScript
61 lines
4.7 KiB
JavaScript
const {chromium}=require('playwright');
|
|
const assert=require('node:assert/strict');
|
|
const fs=require('node:fs/promises');
|
|
const path=require('node:path');
|
|
const out=path.resolve(__dirname,'../test-results');
|
|
(async()=>{
|
|
const browser=await chromium.launch({headless:true,...(process.env.PLAYWRIGHT_CHANNEL?{channel:process.env.PLAYWRIGHT_CHANNEL}:{})});
|
|
const page=await browser.newPage({viewport:{width:1440,height:1000}});
|
|
const errors=[];page.on('pageerror',e=>errors.push(e.message));
|
|
const report={status:'failed'};
|
|
await fs.mkdir(out,{recursive:true});
|
|
const state=()=>page.evaluate(async()=>{
|
|
const {app}=await import('./app.js');const r=app.renderer;
|
|
r.draw();const gl=r.gl,b=new Uint8Array(r.canvas.width*r.canvas.height*4);
|
|
gl.readPixels(0,0,r.canvas.width,r.canvas.height,gl.RGBA,gl.UNSIGNED_BYTE,b);
|
|
let red=0,hash=0;for(let i=0;i<b.length;i+=4){if(b[i]>220&&b[i+1]<80&&b[i+2]<120)red++;hash=(hash+b[i]*3+b[i+1]*5+b[i+2]*7)>>>0;}
|
|
return {phase:r.auditPhase,enabled:r.auditEnabled,timer:r.auditTimer!==null,red,hash,
|
|
targetCount:r.auditPickIds.size,targets:r.facilities.filter(f=>r.auditPickIds.has(f.pickId)).map(f=>f.id)};
|
|
});
|
|
try{
|
|
await page.clock.install({time:new Date('2026-10-28T00:00:00Z')});
|
|
await page.goto(process.env.VIEWER_URL||'http://127.0.0.1:8081/',{waitUntil:'networkidle'});
|
|
await page.waitForFunction(()=>document.querySelector('#loading').hidden);
|
|
await page.clock.pauseAt(new Date('2026-10-28T00:01:00Z'));
|
|
const before=await state();assert.equal(before.enabled,false);
|
|
const data=await (await page.request.get(new URL('data/network.json',page.url()).href)).json();
|
|
const ids=new Set(data.issues.filter(i=>['length_mismatch','adverse_slope'].includes(i.code)).flatMap(i=>i.ids));
|
|
const expected=data.links.filter(l=>l.type==='conduit'&&l.renderable&&ids.has(l.id)).map(l=>l.id).sort();
|
|
assert.deepEqual(before.targets.sort(),expected);
|
|
await page.locator('#audit-highlight').check({force:true});
|
|
const on=await state();assert.equal(on.phase,1);assert.ok(on.red>before.red+20);
|
|
await page.screenshot({path:path.join(out,'audit-red.png'),fullPage:true});
|
|
await page.clock.runFor(1000);
|
|
const normal=await state();assert.equal(normal.red,before.red);assert.equal(normal.hash,before.hash);
|
|
await page.clock.runFor(1000);assert.equal((await state()).phase,1);
|
|
await page.locator('#audit-highlight').uncheck({force:true});const stopped=await state();
|
|
assert.equal(stopped.timer,false);assert.equal(stopped.hash,before.hash);
|
|
await page.locator('#audit-highlight').check({force:true});await page.locator('#audit-steady').check({force:true});
|
|
const fixed=await state();assert.equal(fixed.timer,false);assert.equal(fixed.phase,1);
|
|
await page.clock.runFor(1150);assert.equal((await state()).phase,1);
|
|
await page.locator('#show-conduit').uncheck({force:true});assert.equal((await state()).red,0);await page.locator('#show-conduit').check({force:true});
|
|
const target=expected[0];await page.locator('#search').fill(target);await page.locator('#search-results button').first().click({force:true});
|
|
assert.ok((await page.locator('#details').textContent()).includes('점검 필요 · 오류 확정 아님'));
|
|
await page.locator('#audit-unplaced').click({force:true});
|
|
for(const id of ['OUT_PUMP','C_OUT_PUMP','UHR1-01411'])assert.ok((await page.locator('#audit-list').textContent()).includes(id));
|
|
await page.locator('#audit-dialog .close-dialog').click({force:true});
|
|
await page.locator('#reset').click({force:true});assert.equal((await state()).enabled,false);
|
|
await page.emulateMedia({reducedMotion:'reduce'});await page.locator('#audit-highlight').check({force:true});
|
|
const reduced=await state();assert.equal(reduced.timer,false);assert.equal(reduced.phase,1);
|
|
assert.equal(await page.locator('#audit-steady').isDisabled(),true);
|
|
await page.clock.resume();await page.waitForTimeout(150);
|
|
await page.locator('#audit-highlight').scrollIntoViewIfNeeded();
|
|
await page.screenshot({path:path.join(out,'audit-fixed.png'),fullPage:true});
|
|
assert.deepEqual(errors,[]);Object.assign(report,{status:'passed',target_conduits:expected.length,
|
|
red_pixels_on:on.red,red_pixels_off:normal.red,original_colors_restored:true,
|
|
checks:['target IDs','red pixels','1 second phases','exact original pixel restoration','timer cancellation',
|
|
'steady mode','layer visibility','selection reasons','3 unplaced facilities','reset','reduced motion','no page errors']});
|
|
}catch(e){report.error=e.stack;process.exitCode=1;await page.screenshot({path:path.join(out,'audit-failure.png'),fullPage:true}).catch(()=>{});}
|
|
finally{await fs.writeFile(path.join(out,'audit-highlight-validation.json'),JSON.stringify(report,null,2));console.log(JSON.stringify(report,null,2));await browser.close();}
|
|
})().catch(e=>{console.error(e);process.exitCode=1;});
|