/** * 窄屏实测验收:390px 与 320px 下量真实盒子、真实命中。 * * 每一条都对应一个曾经真实存在的问题(见 docs/PLAN.md §7.10.1): * 抽屉盖住底部导航、工具按钮只有 16px 高、看不见却按得动的「归档」、 * 对话树缩进把卡片压成竖条、对话树没有返回出口。 * * 用法:ADMIN_PW=<密码> node client/electron/test/manual/narrow-verify.mjs */ import { openApp, overflowX, tapTargets, hitTest, scrollHealth, SMALL } from './narrow-probe-helper.mjs'; import { inflateSync } from 'node:zlib'; /** * 取屏幕上某个 CSS 坐标的像素颜色。 * * # 为什么非要有“读像素”这个能力 * * 「圆角到底有没有生效」是**只有像素能回答**的问题。 * * 用户(2026-09-14):「我这边看还是方角」。当时所有别的检查都是绿的: * - `getComputedStyle(pane).borderRadius` === `14px`(外壳那条规则确实加上了); * - 角上 2px 处“谁在画”也指着那块面板本身(elementFromPoint 沿祖先链找底色)。 * 但实际渲染出来是方的 —— 因为那个 14px 加在一个**没有底色、也裁不住东西**的层上, * 白底内层用自己的直角把它原地盖掉了。 * * 实测两个数字就能分辨(390x844 日历页左上角): * 方角:(255,255,255) 圆角:(249,250,251)=页面底色 * 所以这里截 1×1 再解 PNG —— 只用到 `zlib`,不引图像库。 */ async function pixelAt(page, x, y) { const buf = await page.screenshot({ clip: { x, y, width: 1, height: 1 } }); let p = 8; const idat = []; while (p < buf.length) { const len = buf.readUInt32BE(p); const type = buf.toString('ascii', p + 4, p + 8); if (type === 'IDAT') idat.push(buf.subarray(p + 8, p + 8 + len)); p += 12 + len; } const raw = inflateSync(Buffer.concat(idat)); return [raw[1], raw[2], raw[3]]; // [filter, R, G, B, …] } const { browser, ctx, page, issues } = await openApp(); const failed = []; async function check(name, fn) { try { const r = await fn(); console.log(` ${r.ok ? '通过' : '失败'} ${name}${r.note ? ' — ' + r.note : ''}`); if (!r.ok) failed.push(name); } catch (e) { console.log(` 错误 ${name} — ${e.message.slice(0, 90)}`); failed.push(name); } } /** * 打开收件箱里的第一封邮件。 * * 邮件行是 `