面向前端/测试工程师的通用技法文。所有结论均来自一次真实上线体检的实测,不含"应该""通常"式推测。
一、这篇解决什么问题
上线前给网页做"体检",最容易翻车的地方是:脚本断言全绿,肉眼一看却破版。本文给出一套「几何断言 + 整页截图」双轨取证法,并重点拆解一个反复骗过自动化检查的陷阱——假无溢出。
二、核心陷阱:健康信号 ≠ 无问题
判断横向溢出,最常用的一条断言是:
document.documentElement.scrollWidth <= document.documentElement.clientWidth
返回 true 往往被直接解读为"没有横向溢出"。但它是可伪造的:只要根容器或任一祖先设了 overflow-x: hidden,超宽内容会被就地裁掉,scrollWidth 不再增长,断言照样返回 true——而用户看到的是文字右半边凭空消失。
一次真实窄屏取证的对照:
| 证据 | 结果 |
|---|---|
几何断言 scrollWidth==clientWidth | overflow: false(看似正常) |
| 同页整张截图 | 副标题"……都收在这里"渲染成"……都收在",末字被裁 |
结论:几何断言只能证明"没触发横向滚动条",不能证明"内容完整可见"。凡涉及响应式,断言与截图冲突时以截图为准。
三、可复现最小步骤
步骤 1:注入几何断言脚本,导出结构化结果
做法:抓取目标页 HTML → 本地把相对资源路径改指线上域(保证样式/字体加载一致)→ 在 </body> 前插入一段 <script>,计算 scrollWidth/clientWidth 溢出、遍历所有 a/button 的 getBoundingClientRect() 找触控过小项、统计 h1 数量与无 alt 图片 → 用无头浏览器 --dump-dom 抓取注入脚本写进 DOM 的 AUDIT::{json} 行。
判定标准:
- 通过:能解析出一行合法的
AUDIT::{...}JSON。 - 不通过:抓不到该行(脚本抛异常或渲染时序未到)→ 加
--virtual-time-budget=3000重试;仍无则脚本本身有 bug,先修脚本再取证。
步骤 2:多视口整页截图,肉眼复核
做法:--headless=new --window-size=<W>,<H> --screenshot=<绝对路径>.png,至少取窄(移动)与宽(桌面)两档。
判定标准:
- 通过:PNG 文件存在且字节数高于合理下限(空白/失败页往往 < 20KB)。
- 不通过:文件未生成 → 首先检查
--screenshot是否用了绝对路径(无头模式下相对路径常因进程工作目录权限而静默失败)。
步骤 3:断言与截图交叉比对
做法:把步骤 1 的 overflow 结果与步骤 2 截图逐区域比对。
判定标准:
- 通过:断言
overflow:false且截图无任何文字/元素被视口边缘裁切。 - 不通过:断言
false但截图存在裁切 → 判定为假无溢出,回查设了overflow-x:hidden的容器并修正。
四、实测踩坑(这些会让"取证"本身失真)
- 视口被最小宽度钳制:某无头浏览器在 Windows 下
--window-size=390实测渲染视口约 492px,设 1440 实测 1414(差值≈滚动条宽)。→ 窄屏取证要意识到存在下限;精确到 360/390 建议真机或 DevTools 设备模式复核,但 492px 已足以触发移动端断点并复现裁切。 --dump-dom不一定按--window-size布局:旧 headless 模式下 dump-dom 抓到的innerWidth可能与设定值不符(实测出现 vw=496)。→ 几何数据与截图必须在同一模式下产出,不可混用。- 截图相对路径静默失败:无头模式相对路径可能写到进程自身目录或失败且不报错。→ 一律用绝对路径。
- 对比度脚本误判透明背景:算文字对比度时若把
rgba(0,0,0,0)当成有效黑底,深色文字会算出虚假的低对比度(实测曾得 1.21 的假值)。→ 沿祖先链取背景色时必须跳过alpha=0的层。
五、一句话纪律
自动化断言负责"批量、可回归",截图负责"兜住断言看不见的"。两者缺一,体检报告就是半盲的。