Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am using Cypress to use my application and encounter a problem by sending an uploaded file to the backend. It sends an empty FormData .

I am using the code found here https://github.com/cypress-io/cypress/issues/170 to handle file upload which is:

 return cy.get('input[type=file]').then(subject => {
    return cy
        .fixture('blueprint.xlsx', 'base64')
        .then(Cypress.Blob.base64StringToBlob)
        .then(blob => {
            const el = <HTMLInputElement>subject[0]
            if (el != null) {
                const testFile = new File([blob], 'blueprint.xlsx')
                const dataTransfer = new DataTransfer()
                dataTransfer.items.add(testFile)
                el.files = dataTransfer.files
            return subject

When I debug the API call, the file is set, it is in the fixtures folder and everything seems fine but the call doesn't have any formdata (which should be the file) and ends in a 400 Bad request error.

Why is the formdata empty? Is this a Cypress problem? Is there a way to send my fixture file to the backend?

Your code seems to run ok on the ng-file-upload demo page.

I also tested with an 'xlsx' file, no problem found.

describe('Angular file upload Demo', () => {
    To run these tests, add a file 'logo.png' to /cypress/fixtures
  it('uploads the fixture file', () => {
    cy.visit('https://angular-file-upload.appspot.com/')
    cy.get('[name=userName]').type('myLogo')
    cy.get('[name=file]').then(subject => {
      return cy.fixture('logo.png', 'base64')
        .then(Cypress.Blob.base64StringToBlob)
        .then(blob => {
          console.log('blob', blob)
          const el = subject[0]
          if (el != null) {
            const testFile = new File([blob], 'logo.png')
            const dataTransfer = new DataTransfer()
            dataTransfer.items.add(testFile)
            el.files = dataTransfer.files
          return subject          
    cy.contains('button', 'Submit').click()
    cy.contains('.progress', '100%')
    cy.contains('body', 'Upload Successful')
  Cypress.Commands.add('uploadFile', { prevSubject: 'element' }, (subject, fileName) => {
    console.log('subject', subject)
    return cy.fixture(fileName, 'base64')
      .then(Cypress.Blob.base64StringToBlob)
      .then(blob => {
        console.log('blob', blob)
        const el = subject[0]
        if (el != null) {
          const testFile = new File([blob], fileName)
          const dataTransfer = new DataTransfer()
          dataTransfer.items.add(testFile)
          el.files = dataTransfer.files
        return subject          
  it('uploads the file via custom command', () => {
    cy.visit('https://angular-file-upload.appspot.com/')
    cy.get('[name=userName]').type('myLogo')
    cy.get('[name=file]').uploadFile('logo.png')
    cy.contains('button', 'Submit').click()
    cy.contains('.progress', '100%')
    cy.contains('body', 'Upload Successful')
const fixturePath = 'test.png';
const mimeType = 'application/png';
const filename = 'test.png';
cy.getTestElement('testUploadFrontID')
  .get('input[type=file')
  .eq(0)
  .then(subject => {
    cy.fixture(fixturePath, 'base64').then(front => {
      Cypress.Blob.base64StringToBlob(front, mimeType).then(function(blob) {
        var testfile = new File([blob], filename, { type: mimeType });
        var dataTransfer = new DataTransfer();
        var fileInput = subject[0];
        dataTransfer.items.add(testfile);
        fileInput.files = dataTransfer.files;
        cy.wrap(subject).trigger('change', { force: true });

getTestElement is a command added by myself,

Cypress.Commands.add(`getTestElement`, selector =>
cy.get(`[data-testid="${selector}"]`)

after many hours of trying, i figured out a workaround to make ng-file-upload works.

At least my problem was about the File that was not passed as an instance of Blob, i guess.

I've used the same snippet as Jonas one on cypress side.

The workaround is to add a check into the upload function that manages changes in select and drop directives.

function upload() {
    if (!Upload.isFile(file)) {
      file = new File([file], file.name, { type: file.type })
    Upload.upload({
        url: "/api/upload",
        data: {
          file: file
    .then(/* ... */)
    /* ... */

This is just a workaround and i don't really like it.

I don't know why this happens, it happens for me only when i test it using cypress, so i don't like to add that in my production code.

Could someone please help me understanding why this happens?

Does anyone know why the file instance passed into the upload function seems to be a File instance but then it's not?

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.