I have a little problem with trying to check if a file is downloaded.
Button click generates a PDF file and starts its download.
I need to check if it works.
Can Cypress do this?
To verify that the file has been downloaded we can install simple Cypress command, which will set up downloads directory, will wait and will verify that the file is downloaded.
In this article I’ll show how you can verify that file is downloaded with Cypress. First, imagine situation that you have a functionality where user clicks on the Download button, and file is starting to download to your computer. So, you have to test download functionality and you’re using cypress as a tool for testing.
We can’t read large file. However, we don’t need it. To verify that the file has been downloaded we can install simple Cypress command, which will set up downloads directory, will wait and will verify that the file is downloaded. Oh, wait, just one command?
This is a Cypress custom command to wait and to verify that a file has been successfully downloaded. cy-verify-downloads extends Cypress' cy command. So, you need to add this line to your project's cypress/support/commands.js:
Using null explicitly will return the file as a Cypress.Buffer instance, regardless of file extension. Pass in an options object to change the default behavior of cy.readFile (). cy.readFile () yields the contents of the file. For any file other than JSON, the contents of the file are returned.
cypress/plugins/index.js
const path = require('path');
const fs = require('fs');
const downloadDirectory = path.join(__dirname, '..', 'downloads');
const findPDF = (PDFfilename) => {
const PDFFileName = `${downloadDirectory}/${PDFfilename}`;
const contents = fs.existsSync(PDFFileName);
return contents;
};
const hasPDF = (PDFfilename, ms) => {
const delay = 10;
return new Promise((resolve, reject) => {
if (ms < 0) {
return reject(
new Error(`Could not find PDF ${downloadDirectory}/${PDFfilename}`)
);
}
const found = findPDF(PDFfilename);
if (found) {
return resolve(true);
}
setTimeout(() => {
hasPDF(PDFfilename, ms - delay).then(resolve, reject);
}, delay);
});
};
module.exports = (on, config) => {
require('@cypress/code-coverage/task')(on, config);
on('before:browser:launch', (browser, options) => {
if (browser.family === 'chromium') {
options.preferences.default['download'] = {
default_directory: downloadDirectory,
};
return options;
}
if (browser.family === 'firefox') {
options.preferences['browser.download.dir'] = downloadDirectory;
options.preferences['browser.download.folderList'] = 2;
options.preferences['browser.helperApps.neverAsk.saveToDisk'] =
'text/csv';
return options;
}
});
on('task', {
isExistPDF(PDFfilename, ms = 4000) {
console.log(
`looking for PDF file in ${downloadDirectory}`,
PDFfilename,
ms
);
return hasPDF(PDFfilename, ms);
},
});
return config;
};
integration/pdfExport.spec.js
before('Clear downloads folder', () => {
cy.exec('rm cypress/downloads/*', { log: true, failOnNonZeroExit: false });
});
it('Should download my PDF file and verify its present', () => {
cy.get('ExportPdfButton').click();
cy.task('isExistPDF', 'MyPDF.pdf').should('equal', true);
});
I would suggest you to have a look to the HTTP response body.
You can get the response with cy.server().route('GET', 'url').as('download')
(check cypress documentation if you don't know these methods).
and catch the response to verify the body is not empty:
cy.wait('@download')
.then((xhr) => {
assert.isNotNull(xhr.response.body, 'Body not empty')
})
Or if you have a popup announcing success when the download went successfully, you can as well verify the existence of the popup:
cy.get('...').find('.my-pop-up-success').should('be.visible')
Best,
EDIT
Please note cy.server().route()
may be deprecated:
cy.server() and cy.route() are deprecated in Cypress 6.0.0. In a future release, support for cy.server() and cy.route() will be removed. Consider using cy.intercept() instead.
According to the migration guide, this is the equivalent: cy.intercept('GET', 'url').as('download')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With