BackstopJS如何等待GIF动画加载完成后再执行截图操作?
你设置delay无效的核心原因:你的场景配置了clickSelector交互,而BackstopJS默认的delay参数是页面初始加载完成后、执行交互动作前的等待时长,所以15秒的等待是在点击元素之前完成的,点击后GIF才开始加载播放,自然没等到结束就触发了截图。
方案1:替换等待参数(最快修复)
把原配置里的delay替换为postInteractionWait,该参数定义的是交互动作执行完成后的等待时长,刚好匹配点击后等待GIF播放的场景,配置如下:
{ "label": "My_search", "cookiePath": "backstop_data/engine_scripts/cookies.json", "url": "https://my.test.com/test/#/search", "referenceUrl": "https://my.stage.test.com/test/#/search", "clickSelector": "#page-wrap > search > div > ul > li:nth-child(2) > a > span", "postInteractionWait": 15000 }
如果GIF时长固定,该方案可以直接解决问题。
方案2:自定义脚本动态等待GIF播放完成(适配动态GIF场景)
如果GIF是动态生成、时长不固定,可以用onReadyScript自定义等待逻辑,彻底避免固定时长不足或冗余的问题:
- 在BackstopJS项目的
backstop_data/engine_scripts目录下新建脚本waitForGifComplete.js,内容如下:
module.exports = async (page, scenario, vp) => { // 可替换为你实际的目标GIF选择器,缩小匹配范围提升效率 const TARGET_GIF_SELECTOR = 'img[src$=".gif"]'; await page.waitForSelector(TARGET_GIF_SELECTOR); // 计算所有目标GIF的最大播放时长 const maxWaitTime = await page.evaluate((selector) => { const gifList = Array.from(document.querySelectorAll(selector)); return Promise.all(gifList.map(gif => { return new Promise((resolve) => { if (gif.complete) return resolve(gif.duration || 15000); gif.onload = () => resolve(gif.duration || 15000); gif.onerror = () => resolve(0); }); })).then(durations => Math.max(...durations)); }, TARGET_GIF_SELECTOR); // 等待最长的GIF播放完成,额外加1秒缓冲 await page.waitForTimeout(maxWaitTime + 1000); };
- 修改场景配置,引入自定义脚本:
{ "label": "My_search", "cookiePath": "backstop_data/engine_scripts/cookies.json", "url": "https://my.test.com/test/#/search", "referenceUrl": "https://my.stage.test.com/test/#/search", "clickSelector": "#page-wrap > search > div > ul > li:nth-child(2) > a > span", "onReadyScript": "waitForGifComplete.js" }
方案3:冻结GIF消除动画波动(最稳定,优先推荐视觉测试场景使用)
如果你的测试不需要校验GIF本身的播放状态,可以直接将页面所有GIF替换为静态帧,彻底避免因GIF播放进度不一致导致的测试误判,自定义脚本内容如下:
module.exports = async (page, scenario, vp) => { await page.evaluate(() => { document.querySelectorAll('img[src$=".gif"]').forEach(gif => { // 绘制GIF当前帧到Canvas,替换原GIF元素实现冻结 const canvas = document.createElement('canvas'); canvas.width = gif.width; canvas.height = gif.height; const ctx = canvas.getContext('2d'); ctx.drawImage(gif, 0, 0); gif.replaceWith(canvas); }); }); };
同样在场景配置中通过onReadyScript引入该脚本即可。
内容的提问来源于stack exchange,提问作者user3624378
相关产品推荐
相关产品推荐

