2

I know that there is a plugin for doing this in cypress already. However using it with jar files just corrupts the file and therefore it is useless in my usecase. This is really weird because i tried it with every combination of encoding and it still does not work. Works perfectly fine with other filetypes however.

This is the code i am using (works except with jar files).

 cy.fixture('test.jar', 'binary')
            .then(Cypress.Blob.binaryStringToBlob)
            .then(fileContent => {
                cy.get('[data-cy="dropzone"]')
                    .contains('Jar file')
                    .parent()
                    .find('div')
                    .attachFile({
                        fileContent,
                        filePath: 'test.jar',
                        mimeType: 'application/java-archive',
                        encoding: 'binary',
                        lastModified: new Date().getTime(),
                        subjectType: 'drag-n-drop',
                        force: true
                    });
            });

I know that you can perform post requests in cypress. Is it possible to perfom the file upload with it after clicking the dropzone element?

Vahn Toan
  • 93
  • 10

1 Answers1

2

cypress-file-upload lacks explicit support for .jar extension, this is the current list of supported extensions

const FILE_EXTENSION = Object.freeze({
  JSON: 'json',
  JS: 'js',
  COFFEE: 'coffee',
  HTML: 'html',
  TXT: 'txt',
  CSV: 'csv',
  PNG: 'png',
  JPG: 'jpg',
  JPEG: 'jpeg',
  GIF: 'gif',
  TIF: 'tif',
  TIFF: 'tiff',
  ZIP: 'zip',
  PDF: 'pdf',
  VCF: 'vcf',
  SVG: 'svg',
  XLS: 'xls',
  XLSX: 'xlsx',
  DOC: 'doc',
  DOCX: 'docx',
  MP3: 'mp3'
});

The default encoding used is therefore utf8. To explicitly pass in the encoding as an option, you need to use raw mode

cy.fixture('sample.jar', 'binary')
  .then(Cypress.Blob.binaryStringToBlob)
  .then(fileContent => {
    cy.get('[data-cy="dropzone"]').attachFile({
      fileContent,
      filePath: 'sample.jar',
      mimeType: 'application/java-archive',
      encoding: 'binary',
      lastModified: new Date().getTime(),
    },
    { 
      subjectType: 'drag-n-drop', 
      force: true
    });
  });    

Note you need to try both subjectType values, as they trigger different events.

Here's the code that shows which shows which events are triggered with force option

export const EVENTS_BY_SUBJECT_TYPE: Record<Required<HtmlSubjectType>, string[]> = {
  [HtmlSubjectType.input]: ['change'],
  /**
   * @see https://developer.mozilla.org/en-US/docs/Web/API/DragEvent
   */
  [HtmlSubjectType.dragAndDrop]: ['dragstart', 'drag', 'dragenter', 'drop', 'dragleave', 'dragend'],
};

If you still get no action, you will need to manually trigger events, e.g chain .trigger('change') after attachFile(). Ideally you can figure out which events from the app source code.


The workaround given by abramenal is incorrect, this is the part of cypress-file-upload that handles the options parameter. If you pass fixture as a string, encoding is ignored

function getFixtureInfo(fixtureInput) {

  // Normal mode
  // fixture name and options passed separately.
  if (typeof fixtureInput === 'string') {
    return {
      filePath: fixtureInput,
      encoding: '',
      mimeType: '',
      fileName: getFileName(fixtureInput)
    };
  }

  // Raw mode
  // If you pass an object, encoding can be specified
  return {
    filePath: fixtureInput.filePath,
    encoding: fixtureInput.encoding || '',
    mimeType: fixtureInput.mimeType || '',
    fileName: fixtureInput.fileName || getFileName(fixtureInput.filePath),
    fileContent: fixtureInput.fileContent,
    lastModified: fixtureInput.lastModified
  };
}
Fody
  • 23,754
  • 3
  • 20
  • 37
  • i tried using that code but it just passes the test without doing anything. i remember that i had to add the drag n drop option for it to even work but i cant find out where to put it exactly. adding it after last modified changed nothing. any ideas? – Vahn Toan Jan 11 '22 at 12:16
  • Looking at function `attachFile`, to change the subjectType to "drag-n-drop" you can just add the 2nd options parameter. I'll show it above. This option basically controls how the `input` element is found. If it's the default option of "input", then `cy.get('[data-cy="dropzone"]')` must yield the input itself, but if it's "drag-n-drop" then the input must be a child of `cy.get('[data-cy="dropzone"]')` and the input must have `type="file"` attribute. You can check all that in the browser. – Fody Jan 11 '22 at 19:54
  • However, if you're not getting any action after attaching the file, it sounds like you need to add the `force` option, which forces the events to fire (which causes the after-attach action to happen). – Fody Jan 11 '22 at 20:01
  • i edited my snippet. still same behaviour – Vahn Toan Jan 11 '22 at 20:13
  • Not, that's not the way - see the edit I made. – Fody Jan 11 '22 at 20:14
  • thank you very much but i am now getting the same error i had before. the file gets uploaded but when i try to use it or download it it gets corrupted. only happens with jar files – Vahn Toan Jan 11 '22 at 21:56
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240984/discussion-between-vahn-toan-and-fody). – Vahn Toan Jan 12 '22 at 08:51