【问题标题】:Cypress visit and wait timeouts ignored赛普拉斯访问和等待超时被忽略
【发布时间】:2018-09-09 20:13:29
【问题描述】:

我创建了一个测试,在其中设置了一个路由,尝试访问一个向路由发出 API 请求的页面,然后等待路由响应:

cy
    .server()
    .route('GET', '/api/testing')
    .as('testing');
cy.visit('/index.html', { timeout: 60000 });
cy.wait('@testing', { timeout: 60000 });

这只会等待赛普拉斯全局默认 responseTimeout 30 秒,然后 API 请求失败。

这是 Cypress 在控制台中记录的错误消息:

Cypress 尝试向此 url 发出 http 请求时出错: https://localhost:4200/api/testing

错误是:

ESOCKETTIMEDOUT

堆栈跟踪是:

错误:ESOCKETTIMEDOUT
在客户端请求。 (...\node_modules\cypress\dist\Cypress\resources\app\packages\server\node_modules\request\request.js:778:19)
在 Object.onceWrapper (events.js:314:30)
在 emitNone (events.js:105:13)
在 ClientRequest.emit (events.js:207:7)
在 TLSSocket.emitTimeout (_http_client.js:722:34)
在 Object.onceWrapper (events.js:314:30)
在 emitNone (events.js:105:13)
在 TLSSocket.emit (events.js:207:7)
在 TLSSocket.Socket._onTimeout (net.js:402:8) 在 ontimeout (timers.js:469:11)
在 tryOnTimeout (timers.js:304:5)
在 Timer.listOnTimeout (timers.js:264:5)

responseTimeout 添加到赛普拉斯的全局配置会增加超时,但为什么visitwait 的超时没有发生?

【问题讨论】:

  • 我想你已经在 cypress.json 中设置了一个 baseUrl?因为cy.visit('/index.html') 本身可能不会导航到主页。
  • 超时对我来说没问题 - 如果我输入一个虚假的 route(),它会等待完整的 60 秒然后失败。单击失败的命令会在控制台中显示Error: CypressError: Timed out retrying: cy.wait() timed out waiting 60000ms for the 1st request to the route: 'testing'. No request ever occurred
  • 正确,正在使用 baseUrl。尝试虚假路线它也在等我。但是当使用合法路由并暂停服务器响应时,在服务器代码中使用调试器时,它只等待responseTimeout
  • 干杯,这澄清了一些事情。我想知道如何在不停止被测整个应用程序的情况下停止特定路线(因为所讨论的路线看起来与应用程序相关)。对不起,如果我错过了一些明显的东西。
  • 服务器应用是在 Visual Studio 中运行的 .Net Core。在 index.html 页面上由 JavaScript 调用的 API 控制器中设置了一个断点。所以整个页面都提供给浏览器,JavaScript 执行,将请求发送回服务器上的 API 控制器,到达断点,我再也没有继续,所以发生了超时。这有帮助吗?感谢您花时间考虑这个问题。

标签: timeout e2e-testing cypress


【解决方案1】:

查看本页代码示例commands - wait - Alias

// Wait for the route aliased as 'getAccount' to respond
// without changing or stubbing its response
cy.server()
cy.route('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((xhr) => {
  // we can now access the low level xhr
  // that contains the request body,
  // response body, status, etc
})

我会将then((xhr) => 添加到您的代码中,看看会得到什么响应。

逻辑表明,如果虚假路由等待完全超时,但“失败的合法路由”没有,则在超时期限内从服务器发回带有故障代码的响应。


request.js 中错误来源的代码块有一个有趣的注释。

self.req.on('socket', function(socket) {
  var setReqTimeout = function() {
    // This timeout sets the amount of time to wait *between* bytes sent
    // from the server once connected.
    //
    // In particular, it's useful for erroring if the server fails to send
    // data halfway through streaming a response.
    self.req.setTimeout(timeout, function () {
      if (self.req) {
        self.abort()
        var e = new Error('ESOCKETTIMEDOUT')  <-- LINE 778 REFERENCED IN MESSAGE
        e.code = 'ESOCKETTIMEDOUT'
        e.connect = false
        self.emit('error', e)
      }
    })
  }

这可能是您要测试的情况(即响应中途连接中断)。
不幸的是,似乎没有语法cy.wait().catch(),见Commands-Are-Not-Promises

您不能将 .catch 错误处理程序添加到失败的命令。

您可能想尝试存根路由而不是在服务器上设置断点,但我不确定虚假响应应该采用什么形式。 (参考route with stubbing)

【讨论】:

  • 也许从 Visual Studio 发回了响应,这不清楚,捕获承诺中的 xhr 似乎不包括任何其他有用的东西,除了赛普拉斯捕获和记录的内容。真正奇怪的是更改全局 responseTimeout 确实等待。
  • 进一步考虑我想我需要将它视为两个独立的responseTimeouts。第一个是根据实际要求。似乎没有办法调整这个超时,除非你修改全局responseTimeout。第二个是wait。它只调整这个函数在抛出超时之前等待的时间。因此,如果wait 超时小于实际请求,那么wait 将抛出错误。如果大于则实际请求在超过wait 的超时之前抛出错误。
  • 是的,这符合错误消息 - Error: ESOCKETTIMEDOUT at ClientRequest - 意味着请求部分可能导致错误。但是,这不是给定 here 的预期错误
【解决方案2】:

.vist() 和 .wait() 对我不起作用,cypress 上的错误日志建议使用 .request() 代替它可以正常工作。

cy.server(); 
cy.request('/api/path').then((xhr) => {
  console.log(xhr.body)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 2021-09-09
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多