45 lines
3.6 KiB
JavaScript
45 lines
3.6 KiB
JavaScript
// Explicit private case; render only, no backend mutations or paid API calls.
|
|
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';import path from 'node:path';
|
|
import {execSync} from 'node:child_process';
|
|
import {fileURLToPath,pathToFileURL} from 'node:url';
|
|
import {createRequire} from 'node:module';
|
|
const require=createRequire(import.meta.url),SS=require('../js/skin-score');
|
|
const dir=process.env.H5_PIGMENTATION_CASE_DIR;assert(dir,'set private case directory');
|
|
const raw=JSON.parse(fs.readFileSync(path.join(dir,'raw.json')));
|
|
const photo='data:image/jpeg;base64,'+fs.readFileSync(path.join(dir,'front.jpg')).toString('base64');
|
|
const vm=SS.buildViewModel(raw.result,{left:raw.left_side_result,right:raw.right_side_result},{realAge:24,skinType:'混合偏油肌肤'});
|
|
assert.equal(raw.result.brown_spot.count,81);assert.equal(raw.result.freckle.value,0);
|
|
const audit=vm.cats.tone.vars.tone_scoring;
|
|
assert(Math.abs(audit.color_score-(audit.pigment_adjusted_score*.8+audit.dark_circle_score*.2))<1e-9);
|
|
const {chromium}=await import(pathToFileURL(execSync('npm root -g',{encoding:'utf8'}).trim()+'/playwright/index.mjs').href);
|
|
const browser=await chromium.launch();
|
|
try {
|
|
const page=await browser.newPage({viewport:{width:375,height:812},isMobile:true,hasTouch:true});const errors=[];
|
|
page.on('pageerror',e=>errors.push(e.message));
|
|
await page.route('**/api/**',r=>{assert.equal(r.request().method(),'GET');return r.fulfill({json:{ok:true,user:{kind:'browser'}}});});
|
|
const source=fs.readFileSync(fileURLToPath(new URL('../js/app.js',import.meta.url)),'utf8');
|
|
await page.route('**/js/app.js*',r=>r.fulfill({contentType:'text/javascript',body:source.replace(/\}\)\(\);\s*$/,`
|
|
window.__renderCase=function(x){renderReport(x.vm,x.photo,null,x.raw);showScreen('s-report');};
|
|
})();`)}));
|
|
await page.goto(process.env.H5_BASE_URL||'http://127.0.0.1:8080/');
|
|
await page.evaluate(x=>window.__renderCase(x),{vm,photo,raw});
|
|
await page.locator('#viz-tone').scrollIntoViewIfNeeded();
|
|
await page.waitForFunction(()=>{const i=document.querySelector('#viz-tone');return i.naturalWidth&&!i.hidden&&i.dataset.overlayAlpha==='0.3';});
|
|
assert.equal(await page.locator('#tone-detections').count(),0,'detection status overlay removed');
|
|
assert.equal(await page.locator('#tone-map-note').count(),0,'technical caption removed');
|
|
assert(vm.cats.tone.vars.spot_flag.includes('褐色斑81处'));
|
|
const dcDescriptions=['无明显黑眼圈','仅存在轻度黑眼圈','存在中度黑眼圈','可见明显黑眼圈'];
|
|
assert((await page.locator('#tx-tone').textContent()).includes(dcDescriptions[raw.result.dark_circle_severity.value]));
|
|
assert(!(await page.locator('#tx-tone').textContent()).includes('占肤色项20%'));
|
|
await page.locator('#viz-tone').locator('xpath=ancestor::div[contains(@class,"card-detail")][1]').screenshot({path:path.join(dir,'pigmentation-81-color.png')});
|
|
// Display-only example, explicitly synthetic; real downloaded case is unchanged.
|
|
const example=structuredClone(vm);example.skinAgeRaw=40;example.realAge=25;example.skinAgeDisplay=40;
|
|
await page.evaluate(x=>window.__renderCase(x),{vm:example,photo,raw});
|
|
assert.equal(await page.locator('#stat-age b').textContent(),'30');
|
|
assert.equal(await page.locator('#stat-age-note').textContent(),'比实际年龄大5岁');
|
|
assert.equal(example.skinAgeRaw,40);
|
|
assert.deepEqual(errors,[]);
|
|
console.log(JSON.stringify({case:'R20261014-155810-LFB8',brownSpots:81,freckle:0,audit,toneP:vm.cats.tone.P,toneS:vm.cats.tone.S,vita:vm.dims.vita.S,total:vm.total,tests:'PASS; render only; original case unchanged'}));
|
|
}finally{await browser.close();}
|