ui-diff 是做什么的?
在编辑前捕获页面,编辑后再次捕获,并读取发生了什么变化。比较过程在本地运行:像素像文本 diff 一样对齐,每个变化区域都会被映射到导致它的 DOM 变更上。仅在发生可见变化时模型才需要为图片付费。即使如此,图片也只包含裁剪后的变更元素,在 token 预算内(默认 400;两次完整页面截图通常需要 2,000–5,000 token)。
scripts/ 位于此文件旁边。下面,$UI_DIFF 代表 node <此技能的目录>/scripts/ui-diff.mjs。
设置(每台机器只需一次)
- 将
agent-browser放入 PATH(npm i -g agent-browser,然后agent-browser install安装 Chromium;在 Linux 上使用agent-browser install --with-deps)。 - 安装图片库:在
<此技能的目录>/scripts下运行npm install。 - 可选:证明机器已就绪:
node <此技能的目录>/scripts/selftest/selftest.mjs。当所有场景通过时,退出码为 0。
步骤
- 第一次编辑前的基线:
$UI_DIFF baseline <url> --name <slug>。每个页面或状态使用一个 slug,例如home或checkout-mobile。基线会加载页面两次,以了解哪些部分会自行闪烁。 - 进行修改。
- 检查:
$UI_DIFF check <url> --name <slug>。退出码 0 表示没有视觉变化,1 表示发现变化,2 表示出错。 - 首先阅读文本报告,然后再决定是否查看图片:
- 如果列出的每个 DOM 变更都是你预期的,且报告显示
0 unexplained:文本就是证据,因此请保持图片未打开。 - 如果报告列出了未解释的区域(
U1.…),或者你需要判断某个元素的外观:打开报告打印的审查图片路径。在工作结束时打开一次,因为任务中途读取的图片会在之后的每一轮中重新计费。
- 如果列出的每个 DOM 变更都是你预期的,且报告显示
- 迭代:针对同一个基线重新运行
check。仅当你接受当前状态作为新的参考时,才重新建立基线。
当报告正好列出你预期的变更,并且每个未解释区域要么已理解要么已修复时,此步骤完成。
阅读报告
- DOM 变更是原因:元素标签,然后是
属性 before -> after(颜色以十六进制表示)或文本 "old" -> "new"。相同的变更会被分组(x3)。仅做计数而不影响像素的变更会被列出。 - layout 列出了后果:元素移动了 (dx, dy)、调整了大小的元素,以及发生内容位移的像素行。这些都是尺寸或间距变更的预期效果,因此不会生成图片。
- pixel regions 将每个变化区域归入以下四类之一:
- by DOM changes 和 by layout only 是已解释的。
- volatile 表示页面在两次相同捕获之间也在该区域发生了变化。
- unexplained 表示像素发生了变化,但 DOM 中没有任何内容能解释它,例如 canvas、图片或伪元素。未解释的区域始终包含在图片中:它们是回归隐藏的地方。
- SUBTLE 标记了太微弱以至于看不到的变化,例如设计标记微调。相信文本中的十六进制值而不是图片。
- 间距变化(margin、padding、gap)仅相对于相邻元素显示在裁剪图中。文本会给出精确值。
噪音和选项
⚠ page kept changing between shots表示存在动态内容(动画、轮播、计时器)。通过--hide "<css selectors>"将之隐藏,或者使用--selector <css>将检查范围限定到你修改的元素。- 同意横幅和聊天小部件应置于
--hide中。隐藏的元素始终会在报告中列出。 - 项目默认值存放在工作目录下的
.ui-diff.json中,例如{ "hide": "#cookie-banner", "width": 1440 }。命令行参数会覆盖它。 position:fixed元素锚定在它们在页面上的位置,因此它们会保留在比较中。- 捕获内容存放在工作目录下的
.ui-diff/中。该文件夹在 git 中被自动忽略。 - 运行
$UI_DIFF而不带任何参数,可打印所有标志。