在赛普拉斯测试中加载页面后,我如何可靠地等待 XHR 请求?

问题描述 投票:0回答:3

在我的应用程序中,当我访问一个页面时,它会发出一些网络请求来获取数据并将其显示在页面上。之后,您单击按钮并填写字段以过滤该数据。

我有一个 cypress 测试,它基本上会访问页面,应用一些过滤器,并确保 dom 中的内容看起来正确:

it(`filters the data by 'price'`, () => {
  cy.server()
  cy.route('POST', 'http://my-api.biz/api').as('apiRequest')

  cy.visit('/')

  // initial page load loads the min and max price bounds for the UI,
  // as well as the data to initially populate the page. they happen
  // to hit the same URL with different POST params
  cy.wait(['@apiRequest', '@apiRequest'])

  cy.get('#price-filter-min').type('1000')
  cy.get('#price-filter-max').type('1400')

  // wait for data to get refreshed
  cy.wait('@apiRequest')

  cy
    .get('[data-test-column="price"]')
    .each($el => {
      const value = parseFloat($el.text())
      expect(value).to.be.gte(1000)
      expect(value).to.be.lte(1400)
    })
})

然而有时柏树似乎加载页面,做 XHR 请求before 等待,然后偶尔会失败:

CypressError:重试超时:cy.wait() 超时等待 30000 毫秒以等待对路由的第二次响应:“apiRequest”。没有任何回应。

因为它正在等待一个已经发生的请求。

有没有更好的方法来编写这个测试?有没有一种方法可以访问页面并等待 XHR 请求来避免这种竞争情况?

更新

我试图在一个孤立的测试用例中重新创建它,但它似乎一切正常,所以可能存在一些操作错误。

cypress
3个回答
50
投票

你可以这样做:

// Give an alias to request
cy.intercept({
  method: 'GET',
  url: '/odata/locations/**',
}).as('dataGetFirst');

// Visit site
cy.visit('admin/locations');

// Wait for response.status to be 200
cy.wait('@dataGetFirst').its('response.statusCode').should('equal', 200)

// Continue

19
投票

所以现在大部分答案都被弃用了。从 [email protected] 开始,您应该使用

intercept()
.

这是我的做法:

cy.intercept({
      method: "GET",
      url: "http://my-api.biz/api/**",
    }).as("dataGetFirst");
cy.wait("@dataGetFirst");

就是这样。你可以做更多并在等待时做一个断言链,但它本身已经是一个断言。


0
投票

由于您使用的是

cy.visit('/')
,我假设您在配置中设置了一个baseUrl。
cy.route()
中的 URL 参数执行 baseUrl + 您在幕后作为参数传递的字符串。

所以它发送 POST 请求的 URL 是

http://my-api.biz/apihttp://my-api.biz/api
或类似的东西。

尝试将您的路线命令更改为:

cy.route('POST', '/api/foobar').as('apiRequest')

附加文档和示例: 网络请求、夹具

© www.soinside.com 2019 - 2024. All rights reserved.