用无头 Chrome 验收页面:我踩过的 6 个截图坑

改完 UI 不能只靠肉眼。用无头 Chrome 加 CDP 截图验收时,开发浮标、固定头部、懒加载图片、图片优化缓存都会让截图说谎。

  • #Chrome
  • #调试
  • #自动化
本页目录

改完 UI,肉眼验收不可靠。同一个页面,1440 和 390 是两个东西,浅色和暗色又是两个。用无头 Chrome 截图能把这几件事固定下来,但截图本身也会说谎。

这篇记录我用 CDP 截图验收时踩过的 6 个坑。

为什么不直接用浏览器

无头 Chrome 可以固定视口、模拟深浅色、按元素裁剪,还能在脚本里重复跑。缺点是要自己处理页面里的浮层和懒加载。

我用的是 Node 内置的 WebSocket 连 Chrome DevTools Protocol,没有装 Playwright。核心就三件事:导航、设视口、截图。

坑 1:开发浮标

Next dev 会在左下角放一个圆形的开发浮标。元素截图时会把它一起截进去,看起来像页面多了一个黑点。

截图前注入一段样式:

const st = document.createElement("style");
st.textContent = "nextjs-portal{display:none !important}";
document.head.appendChild(st);

坑 2:固定头部

站点的 Header 是 fixed。截「作品区」这种比视口高的元素时,Header 会出现在元素区域的中间,像一条多余的横条。

截图前把 header 也隐藏:

header { display: none !important; }

只影响截图,不影响真实页面。

坑 3:懒加载图片

Next Image 默认懒加载。整页截图时,视口外的图片还没加载,截图里就是空白。390 宽的页脚二维码我截了两次都是空的。

解决方式:先把页面从头滚到底,让图片进入视口;再把 loading 设成 eager,等 decode 完成,最多等 2.5 秒。不要无限等,decode 可能永远不 resolve。

坑 4:图片优化缓存

Next 的图片优化按 URL 缓存。替换 public 下的同名 PNG 后,浏览器和 dev server 可能还在给旧图。截图看起来没变化,不是布局没生效,是图没换。

三个办法:换文件名、删 .next 后重新构建、或者用生产构建验收。最稳的是重新构建。

坑 5:元素裁剪的坐标

截某个区块,不能只给元素宽高。要拿 getBoundingClientRect 加上 scrollX / scrollY,再配合 captureBeyondViewport。元素比视口高时,clip 的坐标系是整页,不是视口。

坑 6:深浅色不是浏览器设置

本机 Chrome 可能存了主题偏好。截图前用 Emulation.setEmulatedMedia 指定 prefers-color-scheme,再用一个干净的 user-data-dir,避免旧偏好干扰。

截图之外

截图只能证明「看起来对」。文字有没有进 HTML、字体有没有回退、锚点 id 有没有生成,这些要看 DOM 和 computed style。

我现在的验收顺序是:构建通过、lint 通过、截图看三档宽度、再抽查关键 DOM。截图是证据,但不是全部证据。

成本

一个 CDP 脚本不到 100 行,比装一套 Playwright 轻。它不能替代人眼,但能把「1440 好看、390 贴边」这种问题在提交前抓出来。

本文同步发布于公众号「傲慢鱼偏见」,欢迎关注。