How to manually upload a file with cypress?
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?
Solution 1:
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
};
}