Reputation: 13109
I'm trying to create a new cypress
command which allows me to post a file using formData
as cy.request
doesn't support formData
yet.
I'm using request-promise-native
for the POST
itself.
First, in my commands.ts
I'm extending the Cypress.Chainable
interface
like this:
declare global {
namespace Cypress {
interface Chainable<Subject = any> {
postFormData(
url: string,
formData: FormData,
token: string): Chainable<FullResponse>
}
}
}
FullResponse
is the response type definition for request-promise-native
.
My postFormData
function looks like this:
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
}
Finally, I'm registering the new command:
Cypress.Commands.add('postFormData', postFormData)
In my test.ts
, I'm calling the command like this:
const response = cy.postFormData(
url,
formData,
accessToken)
expect(response.statusCode).to.equal(202)
However, tsc
gives me these errors:
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
returns a Chainable
but not a Promise
, so how can I solve this?
Upvotes: 2
Views: 2440
Reputation: 13109
This is a possible solution
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)
The correct usage is:
cy.postFormData(
url,
formData,
accessToken)
.then((response) => {
expect(response.statusCode).to.equal(202)
})
Update
As request
is in maintainance mode and there's an issue with browsers and formData
, here's a solution using 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)
Usage:
cy.postFormData(
url,
formData,
accessToken)
.then((response) => {
expect(response.status).to.equal(202)
})
Upvotes: 1