percysnapshot()必须在交互完成后调用,因为percy比对的是用户看到的最终渲染效果,而非页面跳转状态;需等待异步数据、字体加载、动画完成等动态过程结束,否则截图将包含骨架屏、空白区或未渲染内容。

为什么percySnapshot()必须在交互完成后调用
很多人把percySnapshot()放在page.goto()之后就立刻执行,结果截图里全是骨架屏、空白区域或字体未加载状态。Percy不是在比对“页面是否跳转成功”,而是在比对“用户看到的最终渲染效果”。如果组件依赖异步数据、Web Font或动画完成才稳定,那快照就得等这些动态过程结束。
实操建议:
- 用
page.waitForSelector()等待关键元素出现(比如.chart-loaded、[data-testid="header-rendered"]) - 对字体敏感的页面,加
page.evaluate(() => document.fonts.ready)确保自定义字体加载完毕 - 避免依赖
waitUntil: 'networkidle'——它只管HTTP请求,不管JS渲染时序 - 如果用React/Vue,可注入
window.__PERCY_READY = true作为自定义就绪信号,再用page.waitForFunction('window.__PERCY_READY')
CI环境里PERCY_TOKEN和PERCY_BRANCH怎么设才不翻车
本地能跑通,CI上percy exec --直接报Unauthorized或Baseline not found,90%是这两个环境变量没对齐。Percy靠PERCY_TOKEN鉴权,靠PERCY_BRANCH决定比对哪个基线——但它不自动读Git分支名,你得手动传。
常见错误现象:
-
PERCY_BRANCH写成main硬编码,导致所有PR都跟main比,而不是跟目标分支比 - GitLab CI里用
$CI_COMMIT_REF_NAME,但没做空值兜底,merge request pipeline里这个变量可能是unknown - GitHub Actions中
secrets.PERDY_TOKEN拼错成PERCY_TOEKN,静默失败
正确做法:
- GitHub Actions:用
${{ github.head_ref || github.base_ref }}动态取分支名 - GitLab CI:用
script: - export PERCY_BRANCH=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-$CI_COMMIT_REF_NAME} - 永远在CI脚本开头加
echo "PERCY_BRANCH=$PERCY_BRANCH"和echo "PERCY_TOKEN=${PERCY_TOKEN:0:4}..."验证
如何让Percy只比对“真正该变”的区域
一个按钮圆角从4px改成6px,Percy报告里却标出整个导航栏都在变——这是典型的选择器范围过大导致的误报。Percy本身不支持局部截图,但percySnapshot()接受width和height参数,配合clip选项可以裁剪DOM节点区域。
使用场景:
- 测试单个组件(如
<button variant="primary"></button>),用page.locator('button').boundingBox()获取坐标后传给clip - 排除滚动条、动态时间戳等干扰区,用
clip: { x: 0, y: 0, width: 1280, height: 720 }限定视口尺寸 - 响应式测试时,别只跑
1280x720,必须覆盖375x667、768x1024等真实设备断点,否则移动端错位永远漏掉
注意:clip是像素坐标,不是CSS选择器;如果元素位置随内容浮动,先scrollIntoView再boundingBox,否则clip可能截到空白
CI流水线里怎么判断“差异是否可接受”
Percy默认把所有像素差异都标为unreviewed,不会自动通过或失败。想让它真正拦截破坏性改动,必须把percy exec嵌入到CI检查环节,并配置--exit-on-parallel或--exit-on-changes开关。
关键参数差异:
-
--exit-on-changes:只要有任何diff(哪怕只是预期中的按钮圆角变更),就让CI失败——适合强管控场景,但需配套基线审批流程 -
--exit-on-unreviewed:只在存在未人工审核的diff时失败,留给设计/产品确认窗口期 - 不加任何
--exit-*参数:Percy只上传不阻断,CI永远绿,等于没拦截
性能影响:
- 每次
percy exec会触发云端渲染+diff计算,平均耗时30–90秒,别把它塞进单元测试job里拖慢整体流水线 - 建议单独起一个
visual-regressionjob,用needs: e2e确保E2E跑完再执行,避免快照捕获中间态
最容易被忽略的一点:Percy的“基线”是按branch + build + viewports三维存储的。如果你在feature分支上跑了两次快照,第二次不会覆盖第一次——它会生成新基线,而后续PR仍比对第一次。所以基线管理不是“一次上传永久有效”,而是持续演进的过程。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











