Closed artemgurzhii closed 5 years ago
Hi @artemgurzhii Thanks for submitting the issue!
I think it's not quite a common case, but let's think on it.
At first, you of course may read a folder with Node.js fs
module and iterate through the files executing our upload
command.
If not, how do you think the command design should look like? To me a folder often contain different file formats & extensions. Right now it's not possible to automate the mime type determination (but actually doable). At the same time the new API should not break the existing one but extend it seamlessly. Or, like you shared, be a separate command.
Regarding the command you shared – I'm not getting the API. In my understanding uploading a folder should only require 1 param – a folder name (or path). Any other things provided may confuse the end user (like fileName, wtf I'm uploading a folder).
So if we can form a correct proposal here I can take a look on how it affects the code base and then decide is it worth implementing or not. Happy to hear your thoughts.
@abramenal
At first, you of course may read a folder with Node.js fs module and iterate through the files executing our upload command.
It's not really our case, we have something similar to the dropbox or google drive functionality where when user uploads folder - folder is created with files in it.
https://github.com/abramenal/cypress-file-upload/blob/master/src/upload.js#L7
How about this implementation:
export default (subject, fileOrArray, { subjectType = 'input', force = false }) =>
cy.window({ log: false }).then(async window => {
const filesToProcess = Array.isArray(fileOrArray) ? fileOrArray : [fileOrArray];
const OriginalFile = window.File;
const processedFiles = await Cypress.Promise.all(
filesToProcess.map(async ({
fileContent,
fileName,
mimeType,
encoding,
folderPath = null
}) => {
if (!fileName) {
throw new InternalError(ERR_TYPES.MISSING_FILENAME);
}
const validEncoding = encoding || getValidEncoding(fileName);
if (!validEncoding) {
throw new InternalError(ERR_TYPES.MISSING_ENCODING);
}
if (folderPath) {
class FileCopy extends window.File {
get webkitRelativePath() {
return `${folderPath}/${fileName}`;
}
}
window.File = FileCopy;
}
const blob = await getFileBlobAsync({ fileContent, mimeType, encoding: validEncoding });
const file = new window.File([blob], fileName, { type: mimeType });
window.File = OriginalFile;
return file;
}),
);
});
Usage/Api:
cy.fixture(fixturePath).then(fileContent => {
cy.get('input[type="file"].d-none').upload(
{ fileContent, fileName, mimeType, folderPath: 'folder/name' },
{ subjectType: 'input' },
);
});
P.S. This is mostly pseudo code and copy paste from our project, so I'm not sure if this will work, if you are ok with the following API, I can try to implement it and open a PR for it.
Well, this is a hackish enough one, I would actually not overwrite your custom FileCopy
but use it instead when creating a file:
const file = new CustomFile([blob], fileName, { type: mimeType });
In this case I am fine with the pseudo implementation. One thing that needs to be adjusted is conditional logic based on whether we need this folder path.
I would be happy if you can try out coding that as well as testing on your case and then opening a PR. And of course then you'll appear on our honored Contributors list 😈
Please make sure referencing this issue in your PR so it'll automatically close. After that we'll think on updating the documentation for exposed API, for sure we need an extra example showing this ability (as it's non-trivial one), maybe even describing a business need under that (cloud file storage, like you mentioned), etc.
@artemgurzhii is the issue still relevant so I can pay attention on designing and coding?
@abramenal sorry, totally forgot about this issue, yes, it's still relevant, we currently use this hack
to accomplish it, but it would be great to have it as a built-in feature
This is relevant for me as I need to test bulk upload for drag and drop for our web application. I'm just learning how to code and got stuck somewhere around here:
it.only("Uploads multiple files", () => {
let uploadFiles = [
{
fileName: "test.pdf",
encoding: "base64",
mimeType: "application/pdf"
},
{
fileName: "test.pptt",
encoding: "base64",
mimeType:
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
},
{
fileName: "test.docx",
encoding: "base64",
mimeType: "application/msword"
}
];
var newArray = [];
uploadFiles.forEach(function(...element) {
newArray.push(element);
cy.fixture(element[0].fileName).then(fileContent => {
cy.get(selectors.tableRow)
.eq(2)
.upload(newArray, { subjectType: "drag-n-drop" });
});
});
});
@Phillipe-Bojorquez hey there! If the issue is still relevant to you please feel free to open a new issue with your details so we could take a look together quickly.
@artemgurzhii I feel this feature obsolete as for now as no other users were requesting this as well. Feel free to open a PR with these changes if you still feel them reasonable so we could decide. Right now I will close the issue as "won't do" thing (at least for now). Thank you for understanding.
@abramenal do you have a solution? I am facing the same situation. Thanks in advance.
@yslopezm not yet, this needs someone to contribute to since I'm not able to support with that change now
Can anyone help me with the folder upload. Please help with the same.
@vishnuprabhu-95 this hasn't been implemented yet as of #288
Please follow #141 for further updates
Add the ability to upload folders.
We have this functionality in one of our apps. We take the path from the
webkitRelativePath
from the File API which can't be overridden.This is working fix for it: