You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行Cypress测试前确保所有图片加载完成?(Nextjs+Percy)

问题

我有一个使用Percy(集成Cypress)进行可视化测试的Next.js项目,项目从CMS获取图片。如何确保页面所有图片加载完成后再执行快照或元素检查?

我见过两段相关代码,但都有问题:

  1. 检查损坏图片的示例代码:
const brokenImages = []
cy.get('img')
  .each(($el, k) => {
    if ($el.prop('naturalWidth') === 0) {
      const id = $el.attr('id')
      const alt = $el.attr('alt')
      const info = `${id ? '#' + id : ''} ${alt ? alt : ''}`
      brokenImages.push(info)
      cy.log(`Broken image ${k + 1}: ${info}`)
    }
  })
  .then(() => {
    // report all broken images at once
    // enable the condition to see the thrown error
    if (false && brokenImages.length) {
      throw new Error(
        `Found ${
          brokenImages.length
        } broken images\n${brokenImages.join(', ')}`,
      )
    }
  })
  1. 检查单张图片naturalWidth的示例代码(但在Next.js中无效):
cy.get('#loads')
  .should('be.visible')
  .and('have.prop', 'naturalWidth')
  .should('be.greaterThan', 0)

难道我只能设置固定等待时长,寄希望于图片加载完成吗?

解决方案

1. 拦截CMS图片请求,等待全部响应完成

既然图片来自CMS,直接拦截所有图片请求,确认它们都成功返回后再执行快照:

// 根据CMS图片实际路径调整匹配规则
cy.intercept('GET', '**/cms-images/**/*').as('cmsImages')

cy.visit('/target-page')

// 等待所有匹配的图片请求完成,超时时间按需调整
cy.wait('@cmsImages', { timeout: 10000, multiple: true })

// 执行Percy快照
cy.percySnapshot('Target Page')

注意:必须匹配CMS返回图片的真实URL路径,确保覆盖所有从CMS加载的资源。

2. 自定义命令检查所有图片加载状态

针对Next.js的懒加载特性(比如next/image组件),自定义命令确保每张图片都加载完成:

// 注册自定义命令
Cypress.Commands.add('waitForAllImages', () => {
  cy.get('img').each(($img) => {
    // 懒加载图片需要滚动到视图内才会触发加载
    cy.wrap($img).scrollIntoView()
    // 断言图片已加载(naturalWidth>0表示图片有效且已加载)
    cy.wrap($img).should(($el) => {
      expect($el[0].naturalWidth).to.be.greaterThan(0)
    })
  })
})

// 使用示例
cy.visit('/target-page')
cy.waitForAllImages()
cy.percySnapshot('Target Page')

3. 利用Percy快照的内置等待配置

Percy支持等待网络空闲后再快照,适合图片加载完成后无后续请求的场景:

cy.percySnapshot('Target Page', {
  waitForNetworkIdle: true,
  networkIdleTimeout: 5000 // 无网络请求5秒后触发快照
})

4. 拒绝固定等待时长

cy.wait(3000)这类固定等待完全依赖环境速度,极不稳定。如果有个别特殊图片无法通过上述方法覆盖,单独针对该图片做检查:

cy.get('#special-cms-image')
  .scrollIntoView()
  .should(($el) => {
    expect($el[0].naturalWidth).to.be.greaterThan(0)
  })

内容的提问来源于stack exchange,提问作者grabury

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 07:03:26