cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.8k stars 3.17k forks source link

Cypress not downloading file into `downloadsFolder` when app code using `window.location.href` #20981

Open amsan7 opened 2 years ago

amsan7 commented 2 years ago

Current behavior

Current app code has an event handler that links to remote url for file download like this:

<!doctype html>
<html lang="en">
<body>
<script>
  function startDownload() {
    window.location.href = 'https://drive.google.com/uc?export=download&id=1GLsHhpE__lmegbaiN9QSkeXa73kXe8nx';
  }
</script>
<button onclick="startDownload()">
</body>
</html>

The file will download, but it won't go into the downloadsFolder as specified in cypress.json. Instead, it goes to my machine's user's Downloads directory (probably browser default).

Desired behavior

The downloaded file should go to the Cypress downloadsFolder directory. My use case is downloading a file into that directory and then uploading / importing it once again.

Test code to reproduce

Using the above html snippet and calling it index.html:

it('should download zip file into downloadsFolder config location', () => {
  cy.visit('index.html')
  cy.get('button').click()
})

Cypress Version

8.7.0

Other

No response

PCourteille commented 2 years ago

Hi Alessandro,

Are you in Firefox ? I struggled with the same issue for several days, but I think I finally found why.

In the file following file: AppData\Local\Cypress\Cache\9.5.3\Cypress\resources\app\packages\server\lib\browsers\firefox.js

Part of the code is here to set the startup option for Firefox inside the "user.js" file: AppData\Roaming\Cypress\cy\production\browsers\firefox-stable\interactive\user.js

If I correctly understand, the "user.js" file expect the path with the backslash escaped, so something like:

C:\\MyProject

But the value received is already:

C:\MyProject

I'm not a developer, so I expect someone will give us better solutions, but I think we have at least two options :

Option 1:

hotfix directly in Cypress code

Inside "firefox.js", replace the line:

'browser.download.dir': options.downloadsFolder

by:

'browser.download.dir': options.downloadsFolder.replace(/\\/g, "\\\\")

Option 2:

use a plugin to update the value with "\" Create a plugin, something like:

module.exports = (on, config) => {
    on('before:browser:launch', (browser = {}, options) => {
        if (browser.family === 'firefox') {
            options.preferences['browser.download.folderList'] = 2;
            options.preferences['browser.download.dir'] = config['downloadsFolder'].replace(/\\/g, "\\\\");
            return options;
        }
    });
}

Note:

You can check the value set in Firefox with "about:config" : image

I hope my answer will help you, Best regards, Paul

amsan7 commented 2 years ago

@PCourteille Unfortunately no, I am using Chrome on Mac.

PCourteille commented 2 years ago

Hi Alessandro,

I don't have any Mac but maybe the issue is similar ?

It seems that the Cypress logic is similar with Chrome:

So my advice is: 1) Check the path on your Cypress-Chrome parameter, in "chrome://settings"

2) Check the value in Preferences file Try to found in this file the following parameter:

"download": {
    "default_directory": "C:\\users\\"

If you find something wrong in the path insert by Cypress in your Preference file, you can maybe fix it with the same approach that I did for my Firefox on Windows.

Option 2 - Chrome:

module.exports = (on, config) => {
    on('before:browser:launch', (browser = {}, options) => {
        if (browser.family === 'chromium') {
            options.preferences.default['download'] = { default_directory: config['downloadsFolder'].replace(/\\/g, "\\\\") }
            return options
        }
        if (browser.family === 'firefox') {
            options.preferences['browser.download.folderList'] = 2;
            options.preferences['browser.download.dir'] = config['downloadsFolder'].replace(/\\/g, "\\\\");
            return options;
        }
    });
}

It's just an example, I don't expect the solution to be the same...

I hope my answer will help you to found a solution, Best regards, Paul

mirobo commented 2 years ago

Please check issue #17896

A pull request ( https://github.com/cypress-io/cypress/pull/23006 ) to fix this permanently is on the way and was finalized by @AtofStryker (internally it's also double escaping the downloadsFolder path). He wasn't able to reproduce the error on MacOS with the fix in the pull request.

When the PR is merged and a new version is released, the workarounds needs to be removed.

I think this issue can be closed as a duplicate?

AtofStryker commented 2 years ago

@mirobo #23006 only fixes the issue on firefox with windows machines. I think @amsan7 is experiencing this issue in chrome on MacOS, which seems like a different issue.

samtsai commented 1 year ago

I am experiencing something similar or the same issue. Though strangely as I was just re-running my tests, it is working now. But based on my previous downloads I was definitely experiencing downloads going to default location in Chrome instead of the configured path.

The only thing I did was try a different browser (e.g., Edge) then came back and tried in Chrome.

Versions I'm running:

Cypress Version

12.3.0

cypress-app-bot commented 1 year ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

scorpyto commented 1 year ago

I confirm the issue is still existing. Cypress version 12.16.0. It is downloading the file in the default PC folder "Downloads".

vertocode commented 10 months ago

The same problem here, I'm using chrome, and mac. Cypress version 12.5.1.

quynhngx commented 10 months ago

I'm encountering the same issue with above guys.

After downloading the CSV file (while using Cypress test runner), the file does not go to the path as setting in cypress-config.js, it goes to the download folder in Mac folder.

Cypress version 13.2.0 Chrome version 118.0.5993.117 arm64)

steveyoungqa commented 10 months ago

I have a coding interview test that specifically requires verifying downloads :( I DONT want to use any hacks or plugins - any ideas for a solution??

MuhammadAfnan26 commented 8 months ago

@quynhngx Hi, did you find the solution? I have exactly same issue

WillsB3 commented 2 months ago

I'm having the same issue with Cypress 13.11.0 using Chrome 126.0.6478.182 on MacOS 14.5.

If I check the Chrome's settings (for the instance of Chrome launched by Cypress) I can see that the browser is set to save files in my users' Downloads directory:

Screenshot 2024-07-18 at 13 43 56

I expect this setting is meant to be being updated (by Cypress when it launches the browser) but for some reason it is not.

If I add @PCourteille's workaround to the Cypress config:

on('before:browser:launch', (browser = {}, launchOptions) => {
  if (browser.name === 'chrome') {
    launchOptions.preferences.default.download = {
      default_directory: config['downloadsFolder'].replace(/\\/g, '\\\\'),
    }
    return launchOptions
  }
})

The downloads directory is set correctly in Chrome's settings:

Screenshot 2024-07-18 at 13 46 53

and the file downloads there as expected 👍