用赛普拉斯覆盖现有命令

Overwriting an existing command with Cypress

我正在尝试 overwrite an existing command in Cypress.io. I'm looking to log() a route response's status & the route's url to extend the functionality of the built-in route()。不幸的是,我在 console 中收到此消息 The route undefined had a undefined status code.。请注意,我暂时使用浏览器的 console。最后,我将使用 log() 内置方法。这是我到目前为止尝试过的:

cypress/support/commands.js
Cypress.Commands.overwrite('route', (originalFn, response) => {
  console.log(`The route ${response.url} had a ${response.status} status code.`);

  return originalFn(response);
});

更新:

我正在获取路线,但我仍然没有获取 responsestatus。这是我当前的代码:

Cypress.Commands.overwrite('route', (originalFn, url, response) => {
  console.log(`The route ${url} had ${response} status code`);
  return originalFn(url, response);
});

使用模式 cy.route(method, url, response) 时,响应参数用于存根调用和 return 向您的应用提供的响应,请参阅 (route() - Arguments)

response (String, Object, Array)

Supply a response body to stub in the matching route.

请注意,创建 cy.route() 的覆盖将挂接到路由配置,而不是路由的捕获。

模式 cy.route(options) 有一个 onResponse 选项,可用于 console.log() 响应,但 cy.log() 在那里不起作用,可能是因为我们调用了一个命令在命令中。

Cypress.log()可以代替

cy.route({
  url: 'http://example.com',
  method: 'GET',
  onResponse: (response => {
    const message = `The route '${response.url}' had a ${response.status} status code.`;
    const log = Cypress.log({
      displayName: 'Route debugging',
      message: message,
      consoleProps: () => {
        // return an object which will
        // print to dev tools console on click
        return {
          message: message,
        }
      }
    })
    log.finish();  // remove log spinner
  })
})

/*
  Command log output:

    ROUTE DEBUGGING
    The route 'http://example.com' had a 200 status code.

*/

根据您要实现的目标,有几种选择。 Richard 的 上面描述了一种方法 - 我将尝试介绍其他方法。

(注意:https://docs.cypress.io/ 处的 Cypress 文档可能会让您比这个答案有更好的理解。我将尝试 link 内嵌相关文章)

(如果您不关心为什么您的代码无法正常工作,您可以跳到 'Inspecting Api Responses' 部分)

您的代码中发生了什么

让我们看一下 https://docs.cypress.io/api/commands/route.html#Examples

中的示例代码
cy.server()
cy.route('**/users').as('getUsers')
cy.visit('/users')
cy.wait('@getUsers')

没有你的覆盖,cy.route这里只是注册路由,所以你可以稍后等待(记住,cy.route 不会做任何api 调用自身)。覆盖后,cy.route 将完全替换为您的回调:

Cypress.Commands.overwrite('route', (originalFn, url, response) => {
  console.log(`The route ${url} had ${response} status code`);
  return originalFn(url, response);
});

所以当 cy.route('**/users') 被调用时,它会计算

(originalFn, url, response) => {
  console.log(`The route ${url} had ${response} status code`); // Logs "The route **/users had undefined status code"
  return originalFn(url, response); // Registers the route with an mock value of undefined
})(originalCypressRouteFn, '**/users')

您可以看到为什么 response 未定义 - 它根本没有传递到路由调用,因为甚至还没有发出请求。

请注意,如果我们尝试模拟调用(参见 https://docs.cypress.io/api/commands/route.html#With-Stubbing

cy.route('https://localhost:7777/surveys/customer?email=john@doe.com', [
  {
    id: 1,
    name: 'john'
  }
])

您将改为记录

"The route https://localhost:7777/surveys/customer?email=john@doe.com had [object Object] status code"

正在检查 Api 响应

如果您只想检查来自 api 的响应,您可以使用内置调试工具(在调用 cypress open 之后)。浏览器的网络选项卡可用(它将记录在给定测试期间发出的所有请求 运行),您还可以单击左侧面板中记录的响应,这会将请求和响应记录到浏览器控制台。

如果您尝试断言对 api 调用的响应,您可以使用 cy.wait(参见 https://docs.cypress.io/guides/guides/network-requests.html#Waiting)在它之后访问底层 xhr 请求完成:

cy.wait('@apiCheck').then((xhr) => {
  assert.isNotNull(xhr.response.body.data, '1st API call has data')
})

如果您想要记录在 CLI 运行(使用 cypress run)期间进行的 API 调用,您可以:

  1. 打印调试信息,这会给你很多信息,包括所有请求和响应(参见https://docs.cypress.io/guides/references/troubleshooting.html#Print-DEBUG-logs):DEBUG=cypress:* cypress run(你可以更改cypress:*来限制范围调试到 api 调用,虽然我不知道你想要的命名空间是什么)
  2. 使用记录所有请求的插件(例如https://github.com/NeuraLegion/cypress-har-generator