在使用 TypeScript 时添加自定义 Cypress 命令
我正在尝试创建一个新的 cypress 命令,它允许我使用 formData 上传文件,因为 cy.request 还不支持 formData。
我正在为 POST 本身使用 request-promise-native。
首先,在我的 commands.ts 中,我像这样扩展 Cypress.Chainable 接口:
declare global {
namespace Cypress {
interface Chainable<Subject = any> {
postFormData(
url: string,
formData: FormData,
token: string): Chainable<FullResponse>
}
}
}
FullResponse 是 request-promise-native 的响应类型定义。
我的 postFormData 函数如下所示:
function postFormData(
url,
formData,
token
): Cypress.Chainable<FullResponse> { // this is line 52
const response: FullResponse = await post(url, {
auth: { bearer: token },
formData
})
return cy.wrap(response) // this is line 58
}
最后,我正在注册新命令:
Cypress.Commands.add('postFormData', postFormData)
在我的 test.ts 中,我是这样调用命令的:
const response = cy.postFormData(
url,
formData,
accessToken)
expect(response.statusCode).to.equal(202)
然而,tsc 给了我这些错误:
commands.ts:52:4 - error TS1064: The return type of an async function or method must be the global Promise<T> type.
commands.ts:58:3 - error TS1058: The return type of an async function must either be a valid promise or must not contain a callable 'then' member.
cy.wrap 返回一个 Chainable 而不是 Promise,那我该如何解决这个问题?
答案#1
这是一个可能的解决方案
import { post, FullResponse } from 'request-promise-native'
declare global {
namespace Cypress {
interface Chainable<Subject = any> {
postFormData(
url: string,
formData: FormData,
token: string): Chainable<FullResponse>
}
}
}
function postFormData(url, formData, token): Cypress.Chainable<any> {
return cy.wrap(
post(url, {
auth: { bearer: token },
formData
})
)
Cypress.Commands.add('postFormData', postFormData)
正确用法是:
cy.postFormData(
url,
formData,
accessToken)
.then((response) => {
expect(response.statusCode).to.equal(202)
})
更新
由于 request 处于维护模式,并且浏览器和 formData 存在问题,这里提供一个使用 axios 的解决方案:
import axios, { AxiosResponse } from 'axios'
declare global {
namespace Cypress {
interface Chainable<Subject = any> {
postFormData(
url: string,
formData: FormData,
token: string
): Chainable<AxiosResponse>
}
}
}
function postFormData(url, formData, token): Cypress.Chainable<any> {
return cy.wrap(
axios(url, {
method: 'post',
url,
data: formData,
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'multipart/form-data'
}
})
)
}
Cypress.Commands.add('postFormData', postFormData)
用法:
cy.postFormData(
url,
formData,
accessToken)
.then((response) => {
expect(response.status).to.equal(202)
})
