-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support to get downloaded file when its name is not known. #14863
Comments
There's an example of reading a file directly after download by looking for extension. Is this helpful? https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/testing-dom__download/cypress/integration/spec.js#L263 |
It solves only first part of the request as there's a chance that file is not in the downloads folder yet as Cypress doesn't wait for the file to download before the task is executed. It could work when used with |
@viktorgogulenko thanks for that, that should work when the file is generated in the backend and later sent in the response. Unfortunately, in my case, the file is generated by frontend code with I managed to create a workaround with: // plugins/index.js
const path = require('path');
const { existsSync, readdirSync, lstatSync } = require('fs');
const downloadsDirPath = 'cypress/downloads';
const getLastDownloadFilePath = () => {
if (!existsSync(downloadsDirPath)) {
return null;
}
const filesOrdered = readdirSync(downloadsDirPath)
.map(entry => path.join(downloadsDirPath, entry))
.filter(entryWithPath => lstatSync(entryWithPath).isFile())
.map(fileName => ({ fileName, mtime: lstatSync(fileName).mtime }))
.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
if (!filesOrdered.length) {
return null;
}
// TODO: this works only for chrome family browsers
if (filesOrdered[0].fileName.indexOf('crdownload') > -1) {
return null;
}
return filesOrdered[0].fileName;
}; and in test, I use it with // integration/test.spec.js
cy.fixture('expectedFile').then(expectedFile => cy
.waitUntil(() => cy
.task('getLastDownloadFilePath')
.then(result => result),
{ timeout: 3000, interval: 100 })
.then(filePath => {
cy.readFile(filePath).should(actualFile => {
// assertion goes here
});
})
); |
Seems that the link is broken |
Just go to the base directory with newer examples: https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/testing-dom__download |
@TomaszG Thank you so much for posting your solution! It was a real life saver for our project and now we can actually test all our file downloads that have random names. 🙏 |
@TomaszG In your example, how does Edit: I see that plugins/index.js is deprecated these days - i'm looking for an equivalent solution at the moment |
Same for me too it says Timed out retrying after 20000ms: cy.wait() timed out waiting 20000ms for the 1st request to the route: pdfReport. No request ever occurred.
|
Could you please show a content of your "Network" tab after you clicked on button to download a file? Do you have a call at all? |
|
@chaitanyarajugithub please try to use |
No luck, Same issue --> Used Can you provide any open-source example that works intercept? I am using the latest cypress version 12.7.0 |
@chaitanyarajugithub I'll try to push something, but meanwhile I'm curious why do you have |
It's just a typo error in the above comment but I used the correct match case in the code. here is the screenshot. |
@chaitanyarajugithub I've found in examples something similar how to deal with files using interceptor |
// cypress.config.js
const { defineConfig } = require('cypress')
const { testUsers } = require('@hm/common-data')
module.exports = defineConfig({
(...)
e2e: {
setupNodeEvents(on, config) {
return require('./cypress/plugins')(on, config)
},
(...)
},
}) // cypress/plugins/index.js
module.exports = (on, config) => {
on('task', {
...require('./tasks'),
})
return config
} // cypress/plugins/tasks.js
const yourTask = () => {
// do stuff
return null
}
module.exports = {
yourTask,
} |
amended generic version, without path dependency (might not work on Windows): Cypress.Commands.add(
"downloadAndReadFile",
{ prevSubject: "element" },
(subject) => {
return cy.wrap(subject).then(($el) => {
cy.wrap($el).invoke("attr", "href").then(url => {
cy.intercept(url).as("download");
cy.wrap($el).click();
cy.wait("@download").then((res) => {
const downloads = Cypress.config("downloadsFolder");
const fileName = res.response.headers["content-disposition"].split("filename=")[1];
return cy.readFile(`${downloads}/${fileName}`);
});
});
});
}); used like this: cy.contains("Download link")
.downloadAndReadFile()
.should("exist")
.and("contain", "my-expected-content"); |
Hey guys can someone help in how to download dynamic files in cypress and test the content present in it |
Yes same for me. Could any one help on this? |
@satya081 @pratikjain10999 please open your Network tab in Developer Tools, initiate downloading of the file and check what call is responsible for that, click on it and make a screenshot with details of this call (URL, headers etc). I'm pretty sure that call could be unique enough so we could grab some info from there but this is hard to understand what's happening in your case without more details. |
@dibyanshusinha: if you have access to the file path, can't you just use something like cy.readFile(thing.message).should('eq', 'Hello World') |
@jorunfa The filename is dynamic in nature I mean Is there a way to know the exact filename of the file which was just downloaded ? |
FYI As I was saying, I did this which works quite well. I wish there was a cypress event something such as cy.on('download:triggered', (...args)), it would have helped a lot. For all those who end up here and don't mind relying on the logs. Here's a snippet.
|
It would be useful to have an option to parse downloaded files when their name is not known at the moment of download. I tried to create a helper function (task) for that which returns the latest file, however, it's not reliable as it's executed when file is not there yet:
I believe it may be useful to have the ability to:
These two should allow handling such cases.
The text was updated successfully, but these errors were encountered: