Files
juzi/h5/test/pigmentation-case-browser.mjs

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();}