abramenal/cypress-file-upload

[Bug] Upload with HTML file input does not work in Chrome 73

abramenal opened this issue ยท 17 comments

Current behavior:

File upload does not gets triggered when using Chrome v73 and higher.
There were no info in Chrome changelog:
https://developers.google.com/web/updates/2019/03/nic73

UPD:
Found related Chromium bug which seems to be fixed in corresponding Chrome release:
https://bugs.chromium.org/p/chromium/issues/detail?id=792336

Code snippets:

Electron 59: el.files = [testFile] trigger change on input
Chrome >69: el.files = [testFile] trigger change on input
Chrome 73: el.files = [testFile] not trigger change on input

This issue is fixed in #29.

Linked issue: cypress-io/cypress#3730

Desired behavior:

File upload should work seamlessly on any platform.

Versions

Chrome: >73

The issue is fixed, but I'll keep this issue open for a while in order to receive some feedback if it's still persist for some other browsers.

Not working if input is hidden, please check this PR: https://github.com/abramenal/cypress-file-upload/pull/38/files

hey guys, thanks for all your help! idk why mine's not working on Chrome 73, it used to work :(

const UPLOAD_DOCS = 'uploadDocs'; Cypress.Commands.add(UPLOAD_DOCS, () => { cy.fixture('license.jpg', 'base64').then((fileContent) => { cy.get('.front-image > .image-upload > p').upload( { fileContent, fileName: 'license.png', mimeType: 'image/jpg' }, { subjectType: 'drag-n-drop' } ); cy.get('.front-image > .image-upload > p').contains('license.png'); });

i have my cypress-file-upload @3.0.4 and Cypress 3.2.0

Tried to follow the code not sure where to put cy.wrap(subject).trigger('change', {force: true}),
Thanks!

Hey - would also really like the option to force this change because our inputs are often not visible (e.g. when using a label element to handle the clicks etc.)

@ChrisSargent @rchovatiya88
thanks for the feedback!
Will release this change today.

@ChrisSargent @rchovatiya88

Just released v3.0.5!
Check out the new API and re-open issue in case of any further issues.

@allcontributors[bot] add @ChrisSargent for question

@abramenal

I've put up a pull request to add @ChrisSargent! ๐ŸŽ‰

@allcontributors[bot] add @rchovatiya88 for question

@abramenal

I've put up a pull request to add @rchovatiya88! ๐ŸŽ‰

Awesome, thanks for the quick update!

Thanks for the quick update and adding me as a contributor!

@abramenal @ChrisSargent
i've updated to 3.0.5 but was still facing issue. ๐Ÿ˜ž This is my workaround which worked for me. ๐Ÿ˜„

/upload.spec.js - Test File

it('Upload docs', () => {
    cy.upload_file('license.jpg', 'image/jpg', '.front-image > .image-upload > input');
  });

/command.js -

Cypress.Commands.add('upload_file', (fileName, type, selector) => {
  cy.get(selector).then((subject) => {
    cy.fixture(fileName, 'base64').then((content) => {
      const el = subject[0];
      const blob = b64toBlob(content, type);
      cy.window().then((win) => {
        const testFile = new win.File([blob], fileName, { type });
        const dataTransfer = new DataTransfer();

        dataTransfer.items.add(testFile);
        el.files = dataTransfer.files;
      });
    });
  });

  cy.get(selector).trigger('change', { force: true });
});

function b64toBlob(b64Data, contentType = '', sliceSize = 512) {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, { type: contentType });
  blob.lastModifiedDate = new Date();
  return blob;
}

@rchovatiya88

As a first step I would suggest providing force parameter to manually trigger the change event. See https://github.com/abramenal/cypress-file-upload#api

If that works for you, likely this is a bug connected to our environment auto-detection. If so, please bring more details on your setup (node / browser / os versions, dockerfile, etc., anything that may be useful for investigation).

If that still doesn't work for you โ€“ then it is either a problem with the package usage in your code, or weird fixture that you're trying to upload.

Looking forward your reply!

Hi, I'm using 3.3.3 and I can't upload file using chrome 76 :( it works on electron 61

const fileName = 'testdata/resolution/img/sample.jpeg'
    cy.fixture(fileName).then(fileContent => {
        cy.get(elements.ODP_BTN_UNGGAH_BUKTI).upload({ fileContent, fileName, mimeType:'image/jpeg', force:true });
    });

And for me not working. using Chrome 80.
My code working fine in Chrome 70.
commands.js

Cypress.Commands.add('uploadFile', (fileName, fileType = ' ', selector) => {
    return cy.get(selector).then(subject => {
        cy.fixture(fileName, 'base64')
            .then(Cypress.Blob.base64StringToBlob)
            .then(blob => {
                const el = subject[0];
                const testFile = new File([blob], fileName, {
                    type: fileType
                });
                const dataTransfer = new DataTransfer();
                dataTransfer.items.add(testFile);
                el.files = dataTransfer.files;
                return cy.wrap(subject).trigger('change', {force: true});
            });
    });
});





test.js

        const fileName = 'JPEG.jpeg';
        const fileType = 'aplication/jpeg';
        const fileInput = '.editor-image-component .t-file-uploader-input';

        cy.uploadFile(fileName, fileType, fileInput);

Probably this recipe got a bit wasted, so here it is again:
https://github.com/abramenal/cypress-file-upload/blob/master/recipes/react-html5-input/cypress/integration/input.spec.js#L30

cy.fixture('cy.png', 'base64').then(fileContent => {
  cy.get('[data-cy="hidden-input"]').upload(
    { fileContent, fileName: 'cy.png', mimeType: 'image/png' },
    { subjectType: 'input' },
  );
});

There's an auto-detection mechanism for checking chrome version (and if it is greater or equal to 73 there's a forced even trigger).
However if you still experience issues like that, please try to set force option explicitly, and if it works, submit a new issue with details about your setup.

cy.fixture('cy.png', 'base64').then(fileContent => {
  cy.get('[data-cy="hidden-input"]').upload(
    { fileContent, fileName: 'cy.png', mimeType: 'image/png' },
    { subjectType: 'input', force: true },
  );
});

Learn more about the setup used:
https://github.com/abramenal/cypress-file-upload/blob/master/recipes/react-html5-input/cypress/integration/input.spec.js#L30

Thanks for the answer, I am sent the new issue with details
#156