I'm a test-developer working on cypress API testing for the first time. I was asked to test 3 APIs with content type "multipart/form-data". The first one I needed to test it as a POST, but instead the second and the third ones respectively as a PUT and a DELETE.
The POST request is about uploading three files and worked perfectly with the following code:
//variable name
const param = 'parameters_file.xml';
const data = 'data_file.pdf';
const index = 'index_file.xml';
//Datas of the request
const method = 'POST'
const url = 'https://myapi/myapi'
//fileType
const fileTypeXML = 'application/xml';
const fileTypePDF = 'application/pdf';
//formData
const formData = new FormData();
//Conversion parameters file -> need to be stated as a function in the future
cy.fixture(param, 'binary')
.then((resParam) => Cypress.Blob.binaryStringToBlob(resParam, fileTypeXML))
.then((blobParam) => {
formData.set('PARAMFILE', blobParam, param); //adding file to formdata
})
//Conversion index file
cy.fixture(index, 'binary')
.then((resIndex) => Cypress.Blob.binaryStringToBlob(resIndex, fileTypeXML))
.then((blobIndex) => {
formData.set('INDEXFILE', blobIndex, index); //adding file to formdata
})
//conversion data file
cy.fixture(data, 'binary')
.then((resData) => Cypress.Blob.binaryStringToBlob(resData, fileTypePDF))
.then((blobData) => {
formData.set('DATAFILE', blobData, data); //adding file to formdata
})
cy.request({
method: method,
url: url,
headers: {
Idsessionid : SessionId,
"Content-Type": "multipart/form-data",
},
body: formData
}).then((response) => {
expect(response.status).to.eq(201);
})
Now that I'm approaching the second and third APIs, they're very similar to the first one: the PUT request should modify the data file uploaded with the POST request and, again, it needs the three files uploaded before; and instead the the DELETE request need just a parameters-delete file that must be uploaded as a FormData to delete the data file uploaded with the POST Request.
For the PUT request I've tried again using the same code as before:
//variable name
const param2 = 'param.xml';
const data2 = 'data.pdf';
const index2 = 'index.xml';
//request datas
const method2 = 'PUT';
let UploadedFileID = "1A2B3C4D5E6F";
const url2 = "https://myapi/myapi"+UploadedFileID;
//fileType
const fileTypeXML2 = 'application/xml';
const fileTypePDF2 = 'application/pdf';
//formData
const formDataRet = new FormData();
cy.fixture(param2, 'binary')
.then((resParam2) => Cypress.Blob.binaryStringToBlob(resParam2, fileTypeXML2))
.then((blobParam2) => {
formDataRet.set('PARAMFILE', blobParam2, param2);
})
cy.fixture(index2, 'binary')
.then((resIndex2) => Cypress.Blob.binaryStringToBlob(resIndex2, fileTypeXML2))
.then((blobIndex2) => {
formDataRet.set('INDEXFILE', blobIndex2, index2);
})
cy.fixture(data2, 'binary')
.then((resData2) => Cypress.Blob.binaryStringToBlob(resData2, fileTypePDF2))
.then((blobData2) => {
formDataRet.set('DATAFILE', blobData2, data2);
})
cy.request({
method: method2,
url: url2,
headers: {
Idsessionid: SessionId,
"Content-Type": "multipart/form-data",
},
body: formDataRet,
}).then((response) => {
expect(response.status).to.eq(201);
})
However, in this case, when I change the method from POST to PUT, when Cypress sends the request, the request body it sends it's completely empty. The same happens with the DELETE request. What I receive from the APIs is a 400 - Bad Request.
I also tried to forcibly send the PUT and DELETE Request as a POST and the APIs answer with a 204, but no real changes happens to the uploaded data file.
I tried to use the following code with the DELETE Request but it doesn't work either:
// 1. Create a new XMLHttpRequest object
let xhr = new XMLHttpRequest();
// 2. Configure it: GET-request for the URL /article/.../load
xhr.open('DELETE', url);
xhr.setRequestHeader('IdSessionid', SessionId);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
// 3. Send the request over the network
xhr.send(formData);
// 4. This will be called after the response is received
xhr.onload = function () {
if (xhr.status != 200) { // analyze HTTP status of the response
alert(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
cy.writeFile('cypress/fixtures/Token.txt', xhr.statusText);
} else { // show the result
alert(`Done, got ${xhr.response.length} bytes`); // response is the server response
}
};
xhr.onprogress = function (event) {
if (event.lengthComputable) {
alert(`Received ${event.loaded} of ${event.total} bytes`);
} else {
alert(`Received ${event.loaded} bytes`); // no Content-Length
}
};
xhr.onerror = function () {
alert("Request failed");
};
As before it sends no data to the API.
Could someone please tell me if I'm doing something wrong? Or is it just that the PUT and DELETE request with "multipart/form-data" are not supported in Cypress?
Thank you.