Reputation: 856
In my Fixture, I have an action that will start to download a file with browser. This worked very fine until the server will respond directly.
.expect(fs.existsSync(downloadsFolder()+'/export.xml')).ok()
But now I have some file the server need to create, and so a waiting time will occur. I tried to expand the function:
.expect(fs.existsSync(downloadsFolder()+'/export.xml')).ok('War wohl nicht erfolgreich',{ timeout: 300000 })
But the result is the same with a first tryout. I did some research and found:
async function CheckFileExistsWithTimeDelay(t, timeDelay, fileNameAndPath) {
for (var i = 0; i < timeDelay; i++) {
console.log('Waited for a total of ' + i.toString() + ' microseconds');
await t.wait(1);
if (fs.existsSync(fileNameAndPath)) {
// break;
return;
}
}
};
This also does not work. I think the watch file function blocks the Fs and so the browser cannot download the file (write the file). Also, this does not work:
async function waitForFile (path) {
for (let i = 0; i < 300; i++) {
if (fs.existsSync(path))
return true;
await t.wait(1000);
}
return fs.existsSync(path);
}
await t.expect(await waitForFile(downloadsFolder()+'/export.xml')).ok("War wohl nicht erfolgreich", { timeout: 300000 });
It looks like that the file download will fail until testcafe is waiting some time. If the file is downloaded directly everything is fine.
Is there any good example to wait for a downloaded file without blocking the fs?
It was requested so I add it here: The line where testcafe will get the command to download)
await t
.click(Selector('button').withText('Aktionen'))
.click(Selector('a').withText('Xml Exportieren'));
As I wrote. Immediately download works perfect. Until the download is delayed it fails. It looks like that some hook is hanging on the file and so chrome cannot download.
NEW INFO 1 The server will response exact 38,7 seconds after the download link was clicked. After I do this with testcafe I will get inside the browser window
If I use a real case, it means I will click on the link on the physical website the file is downloaded well after the 38 seconds. No error.
NEW INFO 2 I also tried to add a long .wait(150000) to the fixture and then check if the file exists. The browser tried to download the file in the background while waiting inside .wait(150000) loop. And also this is failed.
So I think it is proof that it is a Testcafe issue and not a node issue.
Upvotes: 1
Views: 2042
Reputation: 2348
Here is the another example of how to wait for a downloaded file in test:
import { Selector } from 'testcafe';
import fs from 'fs';
const waitForFileDownloaded = (filePath, timeDelay) => new Promise(resolve => {
let i = 1;
const intervalId = setInterval(() => {
if (fs.existsSync(filePath)) {
clearInterval(intervalId);
resolve(true);
}
i++;
if (i > timeDelay) {
clearInterval(intervalId);
resolve(false);
}
}, 1000);
});
fixture `Downloading`
.page `https://github.com/DevExpress/testcafe`;
test('Test', async t => {
await t
.click(Selector('a').withText('218 releases'))
.click(Selector('a').withText('Source code'))
.expect(await waitForFileDownloaded('c:\\Users\\username\\Downloads\\testcafe-1.6.0.zip', 60)).ok();
});
Also could you please clarify if the downloading process is started after TestCafe clicked on the link (for example, using only await t.wait()
with a big timeout)?
Upvotes: 1