cypress
cypress copied to clipboard
Clicking anchor link to download file causes page load timeout
i was update Cypress 6.4.0
but i cannot click button download

file source:

source: cypress_download.zip
I can recreate this error with the test code below:
it('download file', ({ pageLoadTimeout: 5000 }), () => {
cy.visit('https://people.sc.fsu.edu/~jburkardt/data/csv/csv.html')
cy.get('a[href="addresses.csv"]').click()
})
I am facing the same problem. Clicking on the Download button change window.location.href to download the file, also triggers the beforeunload event. We are downloading the file only, not redirecting towards a page actually, but for the redirection, cypress wait for a load event to be triggered by the application but as no redirection actually is happening it gets page load timeout error. I tried stopPropagation on "window:before:unload" event but didn't work. If we can invoke the load event during the wait or can execute the stopPropagation on the correct state it can be resolved I guess.
Cypress version: 6.5.0 OS : Windows 10
Hi, @jennifer-shehane I'm also facing the same issue even after updating Cypress 6.5.0. Clicking on a button downloads the file, but after downloading the file, the cypress waiting for page load which is not the expected behavior. please suggest a workaround for this problem.
I got a workaround with the following issue,
What actually was happening in my case is that after clicking the download button a redirection was happening to download the file. From the application code: window.location.href was changing to download the file on click event. When cypress gets the redirection it waits for a page load event to get fired from AUT for continuing further. As no actual page redirection was happening so it got stuck and got page load timeout. So I tried the following workaround and it is working fine for my case:
Solution/Workaround:
All I needed was to fire a page load event to execute other cypress commands after clicking the download button rather than getting page load timeout. So before clicking the Download button or targeted file I added an event listener ‘click’ to listen out for the event and did something to trigger the page load event. Here is a tricky part, on event handling I triggered window.location.reload. But if I instantly trigger that on click event it will work but the file will not get downloaded. So I set a timeout of 5 sec, it may vary as per our requirement to download the file, after that, I am triggering window.document.location.reload(). This reloads the page and triggers a page load event. As soon as cypress get the page load event it continues executing further commands
the following solution worked for me fine:
cy.window().document().then(function (doc) {
doc.addEventListener('click', () => {
setTimeout(function () { doc.location.reload() }, 5000)
})
cy.get('[ng-click="vm.export()"]').click()
})
I hope cypress will give a proper solution for this case, till then anyone can use this workaround. @jennifer-shehane @hiatien19 @kiransurakanti
I'm experiencing the same issue here. The solution proposed by @sarja510 works until a new version fix it.
the following solution worked for me fine:
cy.window().document().then(function (doc) { doc.addEventListener('click', () => { setTimeout(function () { doc.location.reload() }, 5000) }) cy.get('[ng-click="vm.export()"]').click() })I hope cypress will give a proper solution for this case, till then anyone can use this workaround. @jennifer-shehane @hiatien19 @kiransurakanti
Unfortunately, this doesn't seem to be enough. The test seems to succeed even if the file to be downloaded doesn't exist (404s etc.). You can confirm it by changing URL of the file to be downloaded:
cy.intercept('/', (req) => {
req.url += '-this-url-doesnt-exist';
});
I fixed it by intercepting the request and checking the status code of the response:
cy.window().document().then(function (doc) {
doc.addEventListener('click', () => {
setTimeout(function () { doc.location.reload() }, 5000)
})
/* Make sure the file exists */
cy.intercept('/', (req) => {
req.reply((res) => {
expect(res.statusCode).to.equal(200);
});
});
cy.get('[ng-click="vm.export()"]').click()
})
@mklepaczewski This solution worked for me, thanks, and also to @sarja510 for the original approach. huge relief to be unblocked!
@jennifer-shehane
I got a workaround with the following issue,
What actually was happening in my case is that after clicking the download button a redirection was happening to download the file. From the application code: window.location.href was changing to download the file on click event. When cypress gets the redirection it waits for a page load event to get fired from AUT for continuing further. As no actual page redirection was happening so it got stuck and got page load timeout. So I tried the following workaround and it is working fine for my case:
Solution/Workaround:
All I needed was to fire a page load event to execute other cypress commands after clicking the download button rather than getting page load timeout. So before clicking the Download button or targeted file I added an event listener ‘click’ to listen out for the event and did something to trigger the page load event. Here is a tricky part, on event handling I triggered window.location.reload. But if I instantly trigger that on click event it will work but the file will not get downloaded. So I set a timeout of 5 sec, it may vary as per our requirement to download the file, after that, I am triggering window.document.location.reload(). This reloads the page and triggers a page load event. As soon as cypress get the page load event it continues executing further commands
the following solution worked for me fine:
cy.window().document().then(function (doc) { doc.addEventListener('click', () => { setTimeout(function () { doc.location.reload() }, 5000) }) cy.get('[ng-click="vm.export()"]').click() })I hope cypress will give a proper solution for this case, till then anyone can use this workaround. @jennifer-shehane @hiatien19 @kiransurakanti
@sarja510 This solution is worked for me.Thank You.
This might be a very stupid question, but can you please let me know what is this doing
cy.get('[ng-click="vm.export()"]').click()
@mklepaczewski
This might be a very stupid question, but can you please let me know what is this doing
cy.get('[ng-click="vm.export()"]').click()
@mklepaczewski
ng-click="vm.export()" is just a selector. It clicks the first(?) element with attribute ng-click="vm.export()". So, for example if I had this in HTML:
<a href="https://example.com/" ng-click="vm.export()">Click here</a>
then the mentioned line would find this element and click it. If your link/button has id my-button then you would replace it with something like cy.get('#my-button').click()
@mklepaczewski thanks a lot for your prompt response.
Are we verifying somewhere that the file is downloaded successfully?
@mklepaczewski thanks a lot for your prompt response.
Are we verifying somewhere that the file is downloaded successfully?
You can find it in Cypress.config('downloadsFolder');
Any updates on this? Will it be released soon?
@jennifer-shehane when are you going to release patch for this issue, it is huge bug, it is 7.5.0 already and no cure of this
Hitting this all over the place as well. I'm glad it's not just me struggling with it. Added a watch to this. Hopefully it gets sorted soon :)
Any chance for a fix for this? 8.1 and bug still is standing strong
We are also struggling with this. A fix would be really great! Thanks
@sarja510 pretty slick, love it, and it is working for me :)
Facing the same issue. Any solution?
@sarja510 the same issue here.
The work around is flaky IME so a real fix would be greatly appreciated!
@sarja510
I have tried the workaround you posted and it is returning null from the reload() method. Could you see what might be going wrong with the test. and the "Download" button I am click has no href link.

@sarja510
I have tried the workaround you posted and it is returning null from the reload() method. Could you see what might be going wrong with the test. and the "Download" button I am click has no href link.
I have this problem too!
I got a workaround with the following issue,
What actually was happening in my case is that after clicking the download button a redirection was happening to download the file. From the application code: window.location.href was changing to download the file on click event. When cypress gets the redirection it waits for a page load event to get fired from AUT for continuing further. As no actual page redirection was happening so it got stuck and got page load timeout. So I tried the following workaround and it is working fine for my case:
Solution/Workaround:
All I needed was to fire a page load event to execute other cypress commands after clicking the download button rather than getting page load timeout. So before clicking the Download button or targeted file I added an event listener ‘click’ to listen out for the event and did something to trigger the page load event. Here is a tricky part, on event handling I triggered window.location.reload. But if I instantly trigger that on click event it will work but the file will not get downloaded. So I set a timeout of 5 sec, it may vary as per our requirement to download the file, after that, I am triggering window.document.location.reload(). This reloads the page and triggers a page load event. As soon as cypress get the page load event it continues executing further commands
the following solution worked for me fine:
cy.window().document().then(function (doc) { doc.addEventListener('click', () => { setTimeout(function () { doc.location.reload() }, 5000) }) cy.get('[ng-click="vm.export()"]').click() })I hope cypress will give a proper solution for this case, till then anyone can use this workaround. @jennifer-shehane @hiatien19 @kiransurakanti
thank you you saved my life. you should work at cypress and fix this kind of thing
Also have been seeing the same issue for a while and using the suggested workaround. However we download a lot of files and check their content so doing these reloads really hurt our execution time.
@jennifer-shehane is there any vague ETA on this? Just want to consider any other solutions like just hitting the download endoints, however that would not be an E2E test.
Facing similar issues while downloading blob in UI, workaround by @sarja510 works in latest version 9.1.1 for my CI pipeline but reloads really somehow hurts the execution time as after reload, we again have to reach same state in the UI where we left off before reloads. This doesn't seem to capture real user behaviour. @jennifer-shehane Would love to know if Cypress is working on it and releasing the fix soon.
Edit: Cypress released 9.2.0 yesterday but again no update on this issue in changelog.
Here with the same issue. I'm using Cypress with an SPA (Angular) so I never have page load events. Here is my .html file:
<button mat-raised-button color="primary" id="btn-download-output" (click)="downloadFile(theAPIJob.presignedURL, theAPIJob.destFilename)">
<mat-icon class="cloud_download_button">cloud_download</mat-icon>
{{theAPIJob.destFilename}}
</button>
Clicking the button triggers the following downloadFile JS function:
downloadFile(signedURL: string, fileName: string) {
const link = document.createElement('a');
link.setAttribute('target', '_self');
link.setAttribute('href', signedURL);
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
}
Cypress successfully saves the file to the downloads folder, but then times out waiting for the page to load. There is no further activity on the webpage after the user downloads. What I need Cypress to do is execute a cy.readFile(outputFile) after the download completes to confirm it was successfully downloaded.
@sarja510
I have tried the workaround you posted and it is returning null from the reload() method. Could you see what might be going wrong with the test. and the "Download" button I am click has no href link.
- doc.location.reload();
+ doc.location?.reload();
or
- doc.location.reload();
+ doc.location && doc.location.reload();
Workaround:
This is reproducible for me when download is handled this way
location.href = link
However, changing it like this works fine
const iframeElement = document.createElement('iframe');
iframeElement.style.display = 'none';
iframeElement.src = link;
document.body.appendChild(iframeElement);
Note: might have issues with IE
I am having the same issue and it feels like a bug, or at least Cypress is lacking the option to skip waiting for page loads... I think such an option would be much appreciated.
After I tried @sarja510's workaround
cy.window().document().then(function (doc) {
doc.addEventListener('click', () => {
setTimeout(function () { doc.location.reload() }, 5000)
})
cy.get('[ng-click="vm.export()"]').click()
})
(btw thanks for that – if it weren't for other difficulties in our SPA this would've worked) I found another "solution" that I wanted to share here in case it helps somebody else.
I ended up changing the anchor tags in question to have the properties
<a href={/link/to/file.ext} target="_blank" rel="noreferrer">Download</a>
so that clicking the link actually opens a separate browser tab.
This way Cypress acknowledges the "page load" and does not hang indefinitely. In the browsers we support (mainly chrome) this is still an ok user experience (when the sent file has appropriate headers like "content-disposition: attachment..."). The browser opens a new tab and closes it again as soon as the download proceeds.
So this seems to solve the problem for us and this way I didn't have to use the async-reload-workaround which caused problems with pending requests without a session.