Issue

I came across a limitation with cypress while trying to upload an image using formData. Cypress cy.request() currently does not support formData submission.

const formData = new FormData();
  formData.set('file', new File(['data'], 'upload.txt'), 'upload.txt');
  cy.request({
    method: 'POST',
    url: '/upload/end/point',
    body: formData,
    headers: {
      'content-type': 'multipart/form-data',
    },
  });

Solution

First I load in my image from a fixture file and set that file into a FormData. I then call a custom command function called formRequest passing in the defined formData.


cy.fixture('image.jpg', 'binary')
    .then((imageBinary: any) => {
          const blob = Cypress.Blob.binaryStringToBlob(imageBinary);
            let formData = new FormData();
            formData.set('file', blob);
            cy.formRequest(
              'POST',
              `${secretUrl}/api/image-upload`,
              token,
              formData
           );
        }

The formRequest custom command will make an XMLHttpRequest() in order to send the formData.

Cypress.Commands.add('formRequest', (method, url, token, formData) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.setRequestHeader('Authorization', `Bearer ${token}`);
    xhr.onerror = () => {
      reject(JSON.parse(xhr.statusText));
    };
    xhr.onload = () => {
      if (xhr.status >= 200) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject(JSON.parse(xhr.statusText));
      }
    };
    xhr.send(formData);
  });
});