I want to write a fixture to simulate the export file and make sure a file is downloaded from browser actions. any example?
NA
I want to write a fixture to simulate the export file and make sure a file is downloaded from browser actions. any example?
NA
There's not a fancy way check if the download has finished, TestCafe is somewhat limited in its ability to control the download ability in the browser.
import fs from 'fs';
const fileName = 'junk.txt';
const downloadLocation = 'C:\\Wherever\\Downloads\\';
const fileDLUrlBase = 'https://example.com/downloads/';
fixture('download test fixture');
test('download test', async t => {
await t.navigateTo(fileDLUrlBase + fileName);
await t.wait(30000);
// Wait 30 seconds
await t.expect(fs.fileExistsSync(downloadLocation + fileName));
});
You could convert that to a loop that checks, say, every 5 seconds for 60 seconds, if you wanted.
// Wait 15*1000 ms or less
async function waitForFile (path) {
for (let i = 0; i < 15; i++) {
if (fs.existsSync(path))
return true;
await t.wait(1000);
}
return fs.existsSync(path);
}
await t.expect(await waitForFile(/*path*/)).ok();
Since the question is vague i.e. we don't know whether OP's exported file is:
data
URII'm adding on my answer for the latter, as I recently had a similar question. Instead of a remote URL download, I wanted to test for download of a data
URI, but I couldn't find an answer so I'm posting my answer in case anyone has the same question.
Here's the download button with a data
URI:
<a
download="file.txt"
target="_black"
href="data:text/plain;,generated text data that will force download on click"
id="btn-download">
Download
</a>
And a snippet of my test (in TypeScript):
const DownloadButton = Selector("#btn-download");
// Simulate a file download
const fileName = await DownloadLink.getAttribute("download");
const filePath = `${downloadsFolder()}\\${fileName}`; // Used the downloads-folder package
await t.click(DownloadButton);
// Using Vladimir's answer to check for file download every x seconds
await t.expect(await waitForFile(filePath)).eql(true);
// We expect the contents of the input to match the downloaded file
await t.expect(JSON.parse(readFileSync(filePath, "utf8"))).eql(TestDocument2);
// Clean up
await unlinkSync(filePath); // Or you can use the afterEach hook to do cleanups
Point is, if your downloaded file is via an anchor href
, you cannot use the navigateTo
solution posted above for security reasons, and you will get the Not allowed to navigate top frame to data URL error.
In the last months a new security update for Google Chrome was published that practically removed the possibility to open base64 URIs in the browser directly with JavaScript.
this works for me
await t
.click(this.downloadPdfImage) // selector -- downloadPdfImage file name that get downloaded
.wait(1000)
await t.expect(fs.existsSync(this.downloadLocation + this.fileNamePdf)).ok(); //assertion to verify