cypress icon indicating copy to clipboard operation
cypress copied to clipboard

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

Open amsan7 opened this issue 2 years ago • 8 comments

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

amsan7 avatar Apr 07 '22 21:04 amsan7

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

PCourteille avatar Apr 11 '22 17:04 PCourteille

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

amsan7 avatar Apr 16 '22 19:04 amsan7

Hi Alessandro,

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

It seems that the Cypress logic is similar with Chrome:

  • firefox.js is replace by chrome.js
  • user.js is replace by Preferences file in Windows:
AppData\Roaming\Cypress\cy\production\browsers\chrome-stable\interactive\Default\Preferences

On Mac it will probably be something like:

~/Library/Application Support/Cypress/cy/production/browsers/chrome-stable/interactive/Default/Preferences

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...

  • the replace will probably be different or
  • maybe you will have to complete the path with somehting

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

PCourteille avatar Apr 16 '22 22:04 PCourteille

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?

mirobo avatar Aug 15 '22 08:08 mirobo

@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.

AtofStryker avatar Aug 15 '22 14:08 AtofStryker

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:

  • Chrome – Version 108.0.5359.124 (Official Build) (arm64)
  • Edge – Version 110.0.1587.6 (Official build) Dev (arm64)

Cypress Version

12.3.0

samtsai avatar Jan 12 '23 17:01 samtsai

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.

cypress-app-bot avatar Jul 12 '23 02:07 cypress-app-bot

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

scorpyto avatar Jul 13 '23 12:07 scorpyto

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

vertocode avatar Nov 14 '23 12:11 vertocode

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)

quynhngx avatar Nov 21 '23 10:11 quynhngx

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??

steveyoungqa avatar Dec 02 '23 16:12 steveyoungqa

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

MuhammadAfnan26 avatar Jan 16 '24 19:01 MuhammadAfnan26

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 👍

WillsB3 avatar Jul 18 '24 12:07 WillsB3