Cypress:POST 请求未被拦截

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

我的测试是通过API发出POST请求登录,URL与拦截中的URL相同,但无论我做什么,请求都不会被拦截。有什么想法吗?我的测试在 beforeEach 钩子中调用

loginAPI()
,我得到 403 响应,因为请求永远不会被拦截,所以我可以设置一个 Header。

Cypress.Commands.add('getSessionCookie', (emailAddress: string, password: string) => {
  cy.task('createAndAccessSecret', Cypress.env('version')).then((cfToken) => {
    cy.setHeaderQA()
    cy.request('POST', Cypress.env("authBaseUrlApi") + "sign-in ", {
      email: emailAddress,
      password: password,
      cf_token: cfToken
    }).then((response) => {
      return response.headers['set-cookie'];
    })
  })
})

Cypress.Commands.add('setHeaderQA', () => {
  const {headerKey, headerValue } = Cypress.env();
  cy.log(`Header: ${headerKey} ${headerValue}`);
  cy.intercept('POST', 'https://auth.website.dev/v2/sign-in', (req) => {
    cy.log(`Intercepted request: ${req.method} ${req.url}`);
    req.headers[headerKey] = headerValue;
  })
})

Cypress.Commands.add('loginAPI', (emailAddress: string, password: string, { cacheSession = true } = {}) => {
  const login = () => {
    cy.getSessionCookie(emailAddress, password).then((cookies => {
      cookies.forEach(cookie => {
        const firstPart = cookie.split(';')[0]
        const separator = firstPart.indexOf('=')
        const name = firstPart.substring(0, separator)
        const value = firstPart.substring(separator + 1)
        console.debug('cookie', name, value)
        cy.setCookie('__session', value)
      })
    }))
  }
  if (cacheSession) {
    cy.session([emailAddress, password], login)
  } else {
    login()
  }
})
automated-tests cypress
2个回答
2
投票

如果我理解的话,你想拦截

发送的请求
cy.request('POST', Cypress.env("authBaseUrlApi") + "sign-in ", {...

cy.intercept()
进一步向下。

如果是这样,不——至少在 e2e 测试中它不起作用。我认为这是因为测试在一个窗口中运行,应用程序在另一个窗口中运行(这就是为什么有

cy.window()
可以访问应用程序的窗口)。

如果您将

cy.request()
更改为使用
window.fetch()
,那么
cy.intercept()
将会 抓住它。我经常使用它来独立于应用程序进行现场测试拦截。

我的头顶上

cy.window().then(async (win) => {
  const url = `${Cypress.env("authBaseUrlApi")}sign-in`
  const response = await win.fetch(url, {
    method: "POST",
    body: {
      email: emailAddress,
      password: password,
      cf_token: cfToken
    }
  })
  return response.headers['set-cookie']
  // or maybe 
  cy.wrap(response.headers['set-cookie'])
})

0
投票

@aladin 有一个正确的解决方法,但我认为更大的情况是代码过于复杂。

由于

cy.loginAPI()
控制过程,只需传入存储的
Cypress.env()
值即可。

如果传入,请使用格式

cy.request(options)
添加标头。

注意,如果

{headerKey, headerValue}
作为键/值对存储在
Cypress.env()
中会更好。

Cypress.Commands.add('getSessionCookie', 
  (
    emailAddress: string, 
    password: string, 
    header?: object           <- optional
  ) => {
  cy.task('createAndAccessSecret', Cypress.env('version')).then((cfToken) => {

    const requestOptions = {
      method: 'POST', 
      url: Cypress.env("authBaseUrlApi") + "sign-in ",
      body: {
        email: emailAddress,
        password: password,
        cf_token: cfToken
      }
    }
    if (header) {
      const {headerKey, headerValue} = header;
      requestOptions.headers[headerKey] = headerValue;
    }

    cy.request(requestOptions).then((response) => {
        ...
})

Cypress.Commands.add('loginAPI', (...) => {
  const login = () => {
    const {headerKey, headerValue} = Cypress.env()
    cy.getSessionCookie(emailAddress, password, {headerKey, headerValue})
      .then((cookies => {
        ...
})
© www.soinside.com 2019 - 2024. All rights reserved.