我的测试是通过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()
}
})
如果我理解的话,你想拦截
发送的请求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'])
})
@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 => {
...
})