Closed KrzysztofKarol closed 6 years ago
This should be fairly simple to fix: you simply need to instantiate Files from your application's window, and not from the test spec window.
// nope
// this is using the global window in the test spec
new File()
cy.window().then((win) => {
// yup
// this is using the File constructor from the application window
new win.File()
})
This isn't related to Windows OS. It affects all usecases where File/Blob/Filelist instances are created in cypress test files. I use MacOS, for example.
I've added comment to recently updated issue: https://github.com/cypress-io/cypress/issues/170#issuecomment-442843559
@brian-mann do you have any suggestions for how to fix this issue if the code instantiating the File is from a 3rd party module? In my case I'm seeing it happen in a call from papaparse:
error: TypeError: Cannot read property 'stream' of null
at parse (VM13 main.demo.js:684)
at VM13 main.demo.js:288
at parseCsvFile (VM13 main.demo.js:287)
at VM13 main.demo.js:588
at doSubmit (VM13 main.demo.js:189182)
at handleSubmit (VM13 main.demo.js:189244)
that parse call is coming from papaparse. I can't (easily) change that code.
Any suggestions would be appreciated. Thanks!
@tnrich I do not see a problem when using cypress-file-upload v5 here https://github.com/cypress-io/cypress-example-recipes/pull/707 If you are hitting a problem using the latest versions of Cypress and plugins, please create a small reproducible example we can run to see the problem.
@bahmutov it was caused by using the wrong File object. Personally, I think cypress should ship with a default cy.upload()
command (or something similar) to avoid this issue in the future.
Here was my original code:
Cypress.Commands.add("uploadFile", (selector, fileUrl, type = "") => {
return cy.fixture(fileUrl, "base64").then((input) => {
const blob = Cypress.Blob.base64StringToBlob(input);
const name = fileUrl.split("/").pop();
const testFile = new File([blob], name, { type });
const event = { dataTransfer: { files: [testFile] } };
return cy.get(selector).trigger("drop", event);
});
});
Changing it to:
Cypress.Commands.add("uploadFile", (selector, fileUrl, type = "") => {
return cy.fixture(fileUrl, "base64").then((input) => {
const blob = Cypress.Blob.base64StringToBlob(input);
const name = fileUrl.split("/").pop();
return cy.window().then((win) => {
// this is using the File constructor from the application window
const testFile = new win.File([blob], name, { type });
const event = { dataTransfer: { files: [testFile] } };
return cy.get(selector).trigger("drop", event);
})
});
});
fixed it
@tnrich I agree, this would be great. You can express your interest in this feature here: https://github.com/cypress-io/cypress/issues/170
Is this a Feature or Bug?
Bug
Current behavior:
File class is not shared with window's children.
Desired behavior:
File class is somehow shared.
How to reproduce:
instanceof File
)Test code:
Additional Info (images, stack traces, etc)
Where did I encounter a problem: https://github.com/jaydenseric/extract-files/blob/10236ac78548a3f9c64d148aa79e1444e8dff285/src/index.js#L33
SO topic: https://stackoverflow.com/questions/30040096/a-file-object-in-chrome-passed-between-windows-is-no-longer-an-instanceof-file
Temporary hack