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

Cypress中获取文档尺寸返回NaN的问题排查求助

问题根源:Cypress异步命令的同步处理错误

你的问题核心在于没有正确处理Cypress的异步特性。cy.document()是一个异步命令,它的回调函数会在浏览器完成文档获取后才执行,但你的getViewport函数却在这个异步操作完成前就直接返回了空的viewport对象,导致后续代码拿到的是未赋值的空对象,自然会出现NaN和空值的问题。

修复步骤

1. 重构getViewport函数,返回异步命令链

让函数返回Cypress的命令链,而不是同步返回空对象,这样后续代码才能正确等待异步操作完成后拿到真实的视口数据:

function getViewport() {
  // 直接返回cy.document的命令链,在then中构建并返回viewport对象
  return cy.document().then((doc) => {
    const width = Cypress.$(doc).outerWidth()
    const height = Cypress.$(doc).outerHeight()
    return {
      bottom: height,
      height: height,
      left: 0,
      right: width,
      top: 0,
      width: width,
      x: 0,
      y: 0
    }
  })
}

2. 调整getRect函数以支持异步获取

因为getViewport现在返回的是异步命令链,getRect也需要改为返回异步结果,不能同步赋值:

export const getRect = (obj) => {
  if (obj == 'viewport') {
    // 返回getViewport的异步链
    return getViewport()
  } else {
    // 假设getElement也是异步的,如果不是需要调整为返回命令链
    return getElement(obj).then(rect => {
      if (Cypress.config('parseLayoutToInt')) {
        return parseAllToInt(rect)
      }
      return rect
    })
  }
}

3. 修改自定义命令isInside,正确处理异步依赖

在自定义命令中,需要通过.then()来依次获取两个矩形数据,再进行断言:

Cypress.Commands.add('isInside', { prevSubject: true }, (subject, element, expected) => {
  // 先获取subtrahend(subject的rect),再获取minuend(element的rect)
  return getRect(subject).then(subtrahend => {
    return getRect(element).then(minuend => {
      const diff = getRectDiff(minuend, subtrahend, expected)
      expect(diff).to.deep.equal(expected)
    })
  })
})

额外说明

Cypress的所有命令都是异步的,遵循命令队列的执行机制,不要尝试用同步的方式去获取异步命令的结果,必须通过.then()链或者async/await(需要在Cypress支持的环境下)来处理异步操作。如果强行同步获取,只会拿到初始的空值或未定义值,导致断言失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:33:00