New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 70 users

Issue metadata

Status: Available
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: ----
Type: ----



Sign in to add a comment

Headless mode doesn't save file downloads

Reported by i...@taapo.com, Feb 27 2017

Issue description

Chrome Version       : Chromium 58.0.3023.0

What steps will reproduce the problem?
(1) Set headless mode (--headless) on command-line
(2) Point URL to downloadable file
(3) Nothing happens

What is the expected result?

When launching in headless mode and pointing to an URL with a downloadable file, file should be downloaded and saved in "Downloads" folder.

What happens instead?

Nothing happens, file doesn't get downloaded.


 
Showing comments 65 - 164 of 164 Older
#62: We are working on giving more fine grained instrumentation, so we'll keep this in mind!

#63: That sounds like a bug, would you mind reporting it: crbug.com/new

#64: We are working on adding Download events notifications, coming soon!

Comment 66 Deleted


headless mode downlod work by using puppeteer,is there any way to enable the Download behavior in java or command line on windows?
@iceleeku...  The best way to do download via the Windows command line is to use Node JS.  You can then create a small .js script as in Comment #61 that will start Headless Chrome and do the download. Use the "chrome-launcher" Node package to start Chrome, and the chrome-remote-interface package to go to the website and start the download.
So, how could i proceed on headless mode using selenium in C#? I tried wraping nodejs and still doesn't work 
How can this be implemented in python/selenium/windows? I think there's quite a few people who could really use this but don't have the js or chrome knowledge to continue.
I'm using:

Google Chrome	61.0.3163.100 (Official Build) (64-bit)
Revision	57c9d07b416b5a2ea23d28247300e4af36329bdc-refs/branch-heads/3163@{#1250}

ChromeDriver 2.30 (undefined)

How can we set this experimental feature to allow for downloads in ruby Selenium::WebDriver? We have the following in place:

# Register the driver
Capybara.register_driver :chrome do |app|
   opts = { args: %w[headless window-size=1280,1024] }
   prefs = { prefs: { 'download.default_directory': DownloadHelpers::PATH.to_s,
                      'plugins.plugins_disabled': ["Chrome PDF Viewer"],
                      'browser.set_download_behavior': { behavior: "allow" } } }
  caps = Selenium::WebDriver::Remote::Capabilities.chrome( chromeOptions: opts.merge(prefs) )
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: caps)
end

Comment 72 Deleted

Comment 73 by amo...@team-dsi.fr, Oct 24 2017

I am looking for a way to transmit the same arguments at the python selenium module. 
Anyone having done this ?
Many tries but not succeeded for now...

Comment 74 Deleted

Is there a way download files can be enabled with the  C++ API? 
Thank you
You can create a DevToolsClient and send the commands through there. 
For instance, that's what we do to capture screenshots in headless_shell: https://cs.chromium.org/chromium/src/headless/app/headless_shell.cc?dr=CSs&l=467

I'm driving chromium using golang / agouti, which runs chromium-driver. How can I insert this command? IIUC, connecting to the port and sending the command won't affect the session controlled by chromium-driver?

It would sure help if chromium had a command-line flag for this. Or, better yet, if headless mode worked the same as normal mode, so I can do apples-to-apples testing without excessive gyrations.

Any help would be appreciated!
I was able to trace down how to do this through chromedriver by looking at the source code and noticing the /session/:session_id/chromium/send_command path. I'm using an older version of the selenium-ruby gem and working code looks like this:

  def enable_chrome_headless_downloads(driver, directory)
    bridge = driver.send(:bridge)
    path = '/session/:session_id/chromium/send_command'
    path[':session_id'] = bridge.session_id
    bridge.http.call(:post, path, {
      "cmd" => "Page.setDownloadBehavior",
      "params" => {
        "behavior" => "allow",
        "downloadPath" => directory,
      }
    })
  end

Comment 78:

Thank you!!! Can you post your version of selenium-ruby gem for posterity? 

Cheers
Here is a python implementation, built upon Comment 78 above (Thanks!).

I had to add the command to the chromedriver commands. I will try to submit a PR so it is included in the library in the future. 

    def enable_download_in_headless_chrome(self, browser, download_dir):
        #add missing support for chrome "send_command"  to selenium webdriver
        browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')

        params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
        browser.execute("send_command", params)

Shawn - thank you so much for posting your code. I tried your suggested method, but without success I'm afraid. In my case I can download the file correctly when not headless. However, I am unable to do so when headless, even after adding support for 'send_command', as you suggested. I'm using Chrome 62.0.3202.94, ChromeDriver 2.33.506120 and Python 3.6.0 on 64-Bit Windows 7. Can you think of a reason why your code would not work for me? Is your browser parameter an instance of Selenium's Chrome WebDriver?
Stewart,

Yes the "browser" is an instance of selenium.webdriver.chrome.webdriver.WebDriver 

I've stripped down the class I use to instantiate the driver and posted it with a test to github: https://github.com/shawnbutton/PythonHeadlessChrome

I am able to run this test to download a file from an internet site.

Hopefully this will help.

Shawn - any solution on Java?
shawn solution works for me!
Hi,

How do I add the command to the chromedriver commands like shawn said? I can't get file downloaded in Headless Chrome.

POST: "I had to add the command to the chromedriver commands. I will try to submit a PR so it is included in the library in the future. 

    def enable_download_in_headless_chrome(self, browser, download_dir):
        #add missing support for chrome "send_command"  to selenium webdriver
        browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')

        params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
        browser.execute("send_command", params)"


My sample download code:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

if __name__ == '__main__':
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    browser = webdriver.Chrome(chrome_options=chrome_options,
                               executable_path=r'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')
    browser.set_window_size(1024, 768)
    browser.get('https://sisweb.tesouro.gov.br/apex/f?p=2031:2:0::::')
    browser.get_screenshot_as_file('initial-page.png')
    browser.find_elements_by_link_text('NTN-B')[0].click()
    browser.get_screenshot_as_file('initial-page-after-click.png')
    browser.quit()


Thanks in advance.
Hi gilsonmn...@gmail.com,

Below is an example of how you might use the method. It works for me.

A couple of notes:
- make sure you put the download directory into the method call. It will not use the normal default download location.
- don't close the browser until the download is done, or it will abort the download. 

-------------
from time import sleep

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def enable_download_in_headless_chrome(browser, download_dir):
    #add missing support for chrome "send_command"  to selenium webdriver
    browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')

    params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
    browser.execute("send_command", params)

chrome_options = Options()
chrome_options.add_argument("--headless")
browser = webdriver.Chrome(chrome_options=chrome_options,
                           executable_path=r'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe')
browser.set_window_size(1024, 768)

enable_download_in_headless_chrome(browser, "c:\temp")

browser.get('https://sisweb.tesouro.gov.br/apex/f?p=2031:2:0::::')
browser.get_screenshot_as_file('initial-page.png')
browser.find_elements_by_link_text('NTN-B')[0].click()
browser.get_screenshot_as_file('initial-page-after-click.png')
sleep(10)
browser.quit()
Thanks, Shawn. Works perfectly with the following corretion:

enable_download_in_headless_chrome(browser, r"c:\temp")


Guys, I spent a lot of time but didn't figured out how I can do it for C# + Chrome Webdriver (headless)
I managed to get it working using Ruby/Rails/RSpec/Capybara.

Here, built upon Comment #78 (thanks mate!) as well:

Capybara.register_driver :selenium do |app|
  options = Selenium::WebDriver::Chrome::Options.new

  options.add_argument('--headless')
  options.add_argument('--no-sandbox')
  options.add_argument('--disable-gpu')
  options.add_argument('--disable-popup-blocking')
  options.add_argument('--window-size=1366,768')

  options.add_preference(:download, directory_upgrade: true,
                                    prompt_for_download: false,
                                    default_directory: '/User/paulo/projects/app/tmp')

  options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })

  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)

  bridge = driver.browser.send(:bridge)

  path = '/session/:session_id/chromium/send_command'
  path[':session_id'] = bridge.session_id

  bridge.http.call(:post, path, cmd: 'Page.setDownloadBehavior',
                                params: {
                                  behavior: 'allow',
                                  downloadPath: '/User/paulo/projects/app/tmp'
                                })

  driver
end


// VERSIONS:

- capybara (2.16.1)
- selenium-webdriver (3.7.0)
- ChromeDriver 2.33.506106 (8a06c39c4582fbfbab6966dbb1c38a9173bfb1a2)

Comment 90 Deleted

Can someone please provide code on how to do it in Selenium java that would help us do this?

we have tried the following code but is not working : 

Code 1 ::
	Map<String, Object> commandMap = new HashMap<>();
	String downloadLocation = “<download-location>”;
	commandMap.put("behavior", "allow");
	commandMap.put("downloadPath", downloadLocation);
	Command cmd = new Command(((ChromeDriver) driver).getSessionId(), "Browser.setDownloadBehavior",
									commandMap);
	((ChromeDriver) driver).getCommandExecutor().execute(cmd);

Exception Occurred : 
	Exception:
		org.openqa.selenium.UnsupportedCommandException: Browser.setDownloadBehavior
		Build info: version: '3.7.1', revision: '8a0099a', time: '2017-11-06T21:01:39.354Z'
		System info: host: 'INIDC-KULKAO11', ip: '192.168.56.1', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_131'
		Driver info: driver.version: unknown

Code 1 ::
	Map<String, Object> commandMap = new HashMap<>();
	String downloadLocation = “<download-location>”;
	commandMap.put("behavior", "allow");
	commandMap.put("downloadPath", downloadLocation);
	Command cmd = new Command(((ChromeDriver) driver).getSessionId(), "Page.setDownloadBehavior",
									commandMap);
	((ChromeDriver) driver).getCommandExecutor().execute(cmd);

Exception Occurred : 
	Exception:
		org.openqa.selenium.UnsupportedCommandException: Page.setDownloadBehavior
		Build info: version: '3.7.1', revision: '8a0099a', time: '2017-11-06T21:01:39.354Z'
		System info: host: 'INIDC-KULKAO11', ip: '192.168.56.1', os.name: 'Windows 7', os.arch: 'amd64', os.version: '6.1', java.version: '1.8.0_131'
		Driver info: driver.version: unknown


Also, when tried with the 'send_command' that too was not working.

While going through the ChromeDriverCommandExecutor code, we couldn't find any way to add support for new commands. And currently the only custom command support provided in it is LAUNCH_APP.

Can someone please help us on how best we can perform this? Or the change would have to come in the Chrome's Command Executor only.

Thanks In Adv. 
Need help urgently.
Anyone got a sample for C# ?

Thanks in advance
Hi Team

Please find below a hack that i have used in Java to achieve this functionality. 

------------------------------------------------------------------------
static void sendCommandForDownloadChromeHeadLess(HttpCommandExecutor driverCommandExecutor,SessionId sessionId,String downloadPath) {
		Json json = new Json();
		Map<String, Object> paramsMap = new HashMap<>();
		paramsMap.put("cmd", "Page.setDownloadBehavior");
		Map<String,String> cmdParamsMap = new HashMap<>();
		cmdParamsMap.put("behavior", "allow");
		cmdParamsMap.put("downloadPath", downloadPath);
		paramsMap.put("params", cmdParamsMap);
		String content = json.toJson(paramsMap);
		log.debug("The request content is :: {}" ,content);
		URL remoteServerUri = null;
		try {
			Field field = HttpCommandExecutor.class.getDeclaredField("remoteServer");
			field.setAccessible(true);
			remoteServerUri = (URL) field.get(driverCommandExecutor);
		}catch (Exception e) {
			log.debug("The HttpCommandExecutor has been modified please check with the framework team",e);
			log.error("This will cause all the file validations to fail");
			return;
		}
		CloseableHttpClient httpclient = null;
		try {
			httpclient = HttpClients.createDefault();
			URIBuilder builder = new URIBuilder(remoteServerUri.toURI());
			builder.setPath("session/"+sessionId.toString()+"/chromium/send_command");
			HttpPost sendCommandPost = new HttpPost(builder.build());
			sendCommandPost.setHeader("Content-Type", ContentType.APPLICATION_JSON.getMimeType());
			StringEntity entity = new StringEntity(content, ContentType.APPLICATION_JSON);
			sendCommandPost.setEntity(entity);
			CloseableHttpResponse response = httpclient.execute(sendCommandPost);
			int statusCode = response.getStatusLine().getStatusCode();
			log.debug("The Response Status code is {}",statusCode);
			if(statusCode <= 200 && statusCode >= 300) {
				log.debug("Un-Successfull status code received");
			}
		}catch (IOException e) {
			log.error("Error Occured while enabling download file setting for chrome headless mode");
			log.error("This will cause all the file validations to fail",e);
		} catch (URISyntaxException e) {
			log.debug("this should never ever occur");
		}finally {
			if(httpclient != null) {
				try {
					httpclient.close();
				} catch (IOException e) {
					log.warn("Error Occured while closing the http client",e);
				}
			}
		}
		
	}
-----------------------------------------------------------------------------------------------------------------------------

Please note, that this is not the best of the ways to do this. We can definitely do this in a better manner. Once I have figured out that, will try to post that code over here.
Disclaimer : I think This will only work while using chrome headless in standalone mode and will not work with Selenium Grid. 

Thanks to everyone who have provided information for this in other programming languages. Used their code for ref.



For people who are searching for a Solution for C#. A very elegant solution has been provided by Cezary Piątek in his Tellurium framework. 
GitHub link to framework : https://github.com/cezarypiatek/Tellurium

Please refer to the class : Tellurium.MvcPages.SeleniumUtils.ChromeRemoteInterface.ChromeRemoteInterface

https://github.com/cezarypiatek/Tellurium/blob/master/Src/MvcPages/SeleniumUtils/ChromeRemoteInterface/ChromeRemoteInterface.cs

This class has the required implementation.

Comment 95 Deleted

we can use the last solution(using Tellurium) only for Core projects ? 
How we can use it .NET Framework 4.6 ? 
Anyone got a demo for C# ?
Thanks.

Comment 97 by kavi7...@gmail.com, Dec 13 2017

Hi. How can we download file from headless chrome using selenium java. Is there any capabilities added recently to chrome to attain this functionality? Do we have JSON string to add those capabilities to selenium Webdriver. Kindly advise.

Comment 98 by kavi7...@gmail.com, Dec 13 2017

How can Page.setDownloadBehavior be set in java selenium? Thank you.
I am running into an issue with the JAVA implementation. No matter what, if I attempt to download a file headless no other code will execute after that step as it closes the driver immediately. The error "chrome not reachable." In some cases the driver is closed before the file has even finished downloading. Any help or suggestions? 

Hi Nick,

Did you try adding wait time until download is complete? Can you share me the code you are trying out, I can try.

Thanks 
Hi Ankit,

What jar file is needed for Json json = new Json();code? I am not able to find an object with Json. Can you please advise. It is very critical.

Thanks a lot
We have used the following class :

org.openqa.selenium.json.Json
Hi Ankit,

I have imported selenium-java-2.41.0 jar but not able to find org.openqa.selenium.json.Json. What is the jar that was used for this import?
I have added a wait. The odd thing is, I can download files from other sites. However, what I am attempting to do is click a button which uses gets/post to generate a pdf, which is then downloaded.
I had to import selenium-java.3.7.1 to locate the org.openqa.selenium.json.Json class. 
Also, I just noticed that the content type I am trying to retrieve is Application/pdf and  Application/csv. Not sure if that helps.
i'm having the same issue as you nick. i'm using python implementation recommended in Comment 86. 

In my case the desired behavior is that clicking the download button opens a new tab and then the file downloads in that tab and then the tab closes. In headless mode I click download but nothing happens. Regular mode works fine. Here's my config:

            chrome_options = Options()
            if HEADLESS:
                chrome_options.add_argument("--headless")
                chrome_options.add_argument('--no-sandbox')
                chrome_options.add_argument('--disable-gpu')
                chrome_options.add_argument('--disable-popup-blocking')
                chrome_options.add_argument('--window-size=1440,900')
            else:
                chrome_options.add_argument("--kiosk")
            prefs = {
                'download.default_directory': DOWNLOAD_PATH,
                'download.prompt_for_download': False,
                'download.directory_upgrade': True,
                'safebrowsing.enabled': False,
                'safebrowsing.disable_download_protection': True}
            chrome_options.add_experimental_option('prefs', prefs)
            driver = webdriver.Chrome(
                chrome_options=chrome_options, executable_path=DRIVER_PATH)
            if HEADLESS:
                driver.set_window_size(1440, 900)
                enable_download_in_headless_chrome(driver, DOWNLOAD_PATH) # from comment 86 above
Hi all. How can Page.setDownloadBehavior be set in webdriver io? Thank you.
Status update: the download behavior flag lets you save downloads in headless mode, but we're still looking at adding download notification at the DevTools level.
Hi All. How to configure download behavior flag in web driver java?

Thanks
so the setDownloadBehavior works, but when its turned on, I don't get any network requests/responses for the url chrome headless downloads. Is anybody seeing the same behaviour?
#112: Right, currently downloads aren't seen by the network interception layer. We discussed adding them there as one potential solution here.

Comment 114 Deleted

Hi,

Can anybody help with setDownloadBehavior ? what is the exact code line in java to attain this functionality. Can this be added in chromeOptions under args and prefs?

Thanks
How can I apply it using robot framework please?

i have this code:

Create Chrome Browser
    [Arguments]    ${link_to_open}
    ${chrome_options}=    Evaluate    sys.modules['selenium.webdriver'].ChromeOptions()    sys, selenium.webdriver
    ${prefs}=    Create Dictionary    download.default_directory=${DOWNLOADS_DIR}
   Call Method    ${chrome options}    add_argument    headless 
   Call Method    ${chrome options}    add_argument    disable-gpu
  Selenium2Library.Go To    ${link_to_open}
Shawn and Stewart, in case you and/or other people need to know, that python workaround and possibly all the other workarounds need to be run on a per tab/window basis.

Comment 119 Deleted

Can someone post workaround code for java ?
Yes I tried that but I get the below error.How to fix this ?
[1517577658.639][SEVERE]: Unable to receive message from renderer

ChromeDriverService driverService = ChromeDriverService.createDefaultService();

	       ChromeDriver driver = new ChromeDriver(driverService, options);

	       Map<String, Object> commandParams = new HashMap<>();
	       commandParams.put("cmd", "Page.setDownloadBehavior");

	       Map<String, String> params = new HashMap<>();
	       params.put("behavior", "allow");
	       params.put("downloadPath", downloadFilepath);
	       commandParams.put("params", params);

	       ObjectMapper objectMapper = new ObjectMapper();
	       HttpClient httpClient = HttpClientBuilder.create().build();

	       String command = objectMapper.writeValueAsString(commandParams);

	       String u = driverService.getUrl().toString() + "/session/" + driver.getSessionId() + "/chromium/send_command";

	       HttpPost request = new HttpPost(u);
	       request.addHeader("content-type", "application/json");
	       request.setEntity(new StringEntity(command));
	       httpClient.execute(request);

I tried this code but I'm not able to save that file to a directory 

Comment 124 Deleted

How we can use it .NET Framework 4.5 ? 
Anyone got a demo for C# ?

Comment 126 Deleted

Comment 127 Deleted

 Download in headless mode works fine for me in windows. However, it does not work in Linux. Did anybody made it work in Linux?
The code which works in windows is as shown below: 

Launch Headless Chrome
    Create Download Directory
    ${chrome options}=    Evaluate    sys.modules['selenium.webdriver'].ChromeOptions()    sys, selenium.webdriver
    Call Method    ${chrome options}    add_argument    start-maximized
    Call Method    ${chrome_options}    add_argument    --headless
    Call Method    ${chrome_options}    add_argument    --disable-gpu
    Call Method    ${chrome_options}    add_argument    --window-size\=1920,1080
    Call Method    ${chrome_options}    add_argument    --lang\=en-us
    Call Method    ${chrome_options}    add_argument    --no-sandbox
    ${prefs}       Create Dictionary    download.default_directory=${download directory}    download.prompt_for_download=false   
    Call Method    ${chrome options}    add_experimental_option    prefs    ${prefs}
    Create Webdriver    Chrome    chrome_options=${chrome options}
    Enable Download In Headless Chrome    ${download directory}
    Go To   about:blank

Below is the code used to enable download behavior and setting the download directory for chrome headless.

def enable_download_in_headless_chrome(download_dir):
logger.info('Getting SeleniumLibrary Instance')
instance = BuiltIn().get_library_instance('SeleniumLibrary')
driver = instance.driver
# add missing support for chrome "send_command"  to selenium webdriver
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')

params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
command_result = driver.execute("send_command", params)
logger.info("response from browser:")
for key in command_result:
    logger.info("result:" + key + ":" + str(command_result[key]))

Comment 129 Deleted

There are Python and Java samples here
Anyone got a sample for C# ?
Thanks in advance
The python samples given here does not work on Linux for me. My code works fine in windows. I have no clue on why it's not working in Linux.
Anyone able to figure how can we achieve this in java ? Thanks in advance
Anyone got an example for C# ?
Thanks in advance
Hi guys, Any kind of c# dev to handle with this issue??

I´m facing this issue after chrome update. I can´t download files in chrome headless mode.

Thanks in advance
 
Hi guys! Does anyone have sample of this workaround on JavaScript? How could it be used with protractor?
Hi guys, who can help me

I have an automation process created with java selenium-webdriver, chromedriver and work with eclipse. The point is that by doing the process with headless and disable gpu I get that the download is correct but it does not appear in the directory and instead if the headless option and gpu if it appears in the directory. Attached the code below and if there is someone who knows how to do it and can help me, I will be grateful, thanks.

PROCESS:

System.setProperty ("webdriver.chrome.driver", "C: \\ Users \\ Dani \\ Desktop \\ driver \\ chromedriver.exe");
    String downloadFilepath = "C: \\ Users \\ Dani \\ Documents \\ BILLS"; // directory download
    HashMap <String, Object> prefs = new HashMap <String, Object> ();
        //prefs.put("profile.default_content_setting_values.automatic_downloads ", 1);
        prefs.put ("profile.default_content_settings.popups", 0);
        prefs.put ("download.prompt_for_download", false);
        //prefs.put("download.directory_upgrade ", true);
    prefs.put ("download.default_directory", downloadFilepath);
    ChromeOptions options = new ChromeOptions ();
        options.addArguments ("- headless");
        options.addArguments ("--disable-gpu");
        options.addArguments ("- window-size = 1920,1200");
        options.addArguments ("--disable-infobars");
        options.addArguments ("--disable-notifications");
        options.setExperimentalOption ("prefs", prefs);
    DesiredCapabilities cap = new DesiredCapabilities ();
        cap.setCapability (CapabilityType.ACCEPT_SSL_CERTS, true);
        cap.setCapability (ChromeOptions.CAPABILITY, options);
    WebDriver driver = new ChromeDriver (options);
    driver.manage (). timeouts (). implicitlyWait (20, TimeUnit.SECONDS); // indicate seconds between actions
Sobre el Traductor de GoogleComunitatMòbil
Quant a GooglePrivadesa i condicionsAjudaEnvia suggeri
I would also love to know if anyone has got this working with protractor
Whats the problem to download file in headless mode and what solution is current run in?
Currently, if a download is being started in a new window via target _blank link or window.open, it's not being saved. Any solution for this?
Our app uses a new tab for downloads and the standard solutions does not work for us either since it only effects the current page.  My theoretical approach is to register for the Target.targetCreated event and apply the Page.setDownloadBehavior command to the new page.  The only problem is I have no idea how to do this via chromedriver.
Javascript solution currently working with:

webdriverio 4.12.0
selenium-standalone 6.13.0
chromedriver 2.36
chrome 65.0.3325.162

on Ubuntu server 16.04.4. It allowes headless chrome session to download file:

const unirest = require('unirest');

let session = browser.session();
// key sessionId is webdriverio implementation, debug your session object
let sessionId = session['sessionId'];
let params = {
    'cmd': 'Page.setDownloadBehavior', 
    'params': {'behavior': 'allow', 'downloadPath': 'absolutePath' }};

unirest
        .post('http://localhost:4444/wd/hub/session/' + sessionId + '/chromium/send_command')
        .send(JSON.stringify(params))
        .end();

It is based on the answer https://stackoverflow.com/questions/48831273/protractor-file-download-test-fails-when-headless-chrome.
For those who were asking for a C# .net solution:

var workingDir = "C:\\WorkingFolder";
var opts = new ChromeOptions();

opts.AddArguments("--headless");

var driverService = ChromeDriverService.CreateDefaultService(workingDir);
var driver = new ChromeDriver(driverService, opts);


// Allow download in headless mode
var param = new Dictionary<string, string>();
param.Add("behavior", "allow");
param.Add("downloadPath", workingDir);

var cmdParam = new Dictionary<string, object>();
cmdParam.Add("cmd", "Page.setDownloadBehavior");
cmdParam.Add("params", param);

var content = new StringContent(JsonConvert.SerializeObject(cmdParam), Encoding.UTF8, "application/json");

var url = driverService.ServiceUrl + "session/" + driver.SessionId + "/chromium/send_command";
var httpClient = new HttpClient();
await httpClient.PostAsync(url, content);

I am facing a similar issue and my code base is Java. When I try to download a file in chrome using headless mode, the download does not happen. But the download works when the chrome is open. Please help me with a code snippet to assist on this problem
    In Java use following code :

System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver");
             ChromeOptions options = new ChromeOptions();
                    options.addArguments("--test-type");
                    options.addArguments("--headless");
                    options.addArguments("--disable-extensions"); //to disable browser extension popup
    
                    ChromeDriverService driverService = ChromeDriverService.createDefaultService();
                    ChromeDriver driver = new ChromeDriver(driverService, options);
    
                    Map<String, Object> commandParams = new HashMap<>();
                    commandParams.put("cmd", "Page.setDownloadBehavior");
                    Map<String, String> params = new HashMap<>();
                    params.put("behavior", "allow");
                    params.put("downloadPath", "//home//vaibhav//Desktop");
                    commandParams.put("params", params);
                    ObjectMapper objectMapper = new ObjectMapper();
                    HttpClient httpClient = HttpClientBuilder.create().build();
                    String command = objectMapper.writeValueAsString(commandParams);
                    String u = driverService.getUrl().toString() + "/session/" + driver.getSessionId() + "/chromium/send_command";
                    HttpPost request = new HttpPost(u);
                    request.addHeader("content-type", "application/json");
                    request.setEntity(new StringEntity(command));
                    httpClient.execute(request);
            driver.get("http://www.seleniumhq.org/download/");
            driver.findElement(By.linkText("32 bit Windows IE")).click();
Can someone tell me if he could download with headless in java with chromedriver?
Thanks
It doesnt work for me in headless mode. 
@Daniel does it work for you ?
Guys, help me please. I still get response from browser:
result:status:0
result:sessionId:6d06f404b019eedcf01d430a0515e94e
result:value:None
with chrome 66 and chromedriver 2.37. This is my Python code:

                def enable_download_in_headless_mode(self, browser, download_directory):
                    browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
                    params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_directory}}
                    command_result = browser.execute("send_command", params)
                    print("response from browser:")
                    for key in command_result:
                        print("result:" + key + ":" + str(command_result[key]))

                opts.add_argument("--disable-popup-blocking")
                opts.add_argument("--ignore-certificate-errors")
                opts.add_argument("--no-sandbox")
                opts.add_argument("--headless")
                opts.add_argument('--disable-gpu')
                opts.add_argument('--disable-popup-blocking')
                self.logger.info("WebDriverChrome")
                self.download_location = os.path.join(Config.Environment().path, Config.Environment().get_attr(
                    "component") + '/reports')
                prefs = {'download.default_directory': self.download_location,
                         'download.prompt_for_download': False,
                         'download.directory_upgrade': True,
                         'safebrowsing.enabled': False,
                         'safebrowsing.disable_download_protection': True}
                opts.add_experimental_option("prefs", prefs)

                self.driver = webdriver.Chrome(chrome_options=opts, desired_capabilities=d)
                self.enable_download_in_headless_mode(browser=self.driver, download_directory=self.download_location)
                self.driver.set_window_size(width=1920, height=1295)
                self.logger.info("WebDriverChrome - Done")
Sorry @ a...@view26.com  no works for me and i have not found the solution yet.
I have tried the @osvaib code but not works and fails.
I have searched the internet but I do not find it. I do not know if anyone will have any.


Who can help us @view,@dani please?

thanks
import * as got from 'got';

async onPrepare() {
        await got.post(
            `${(await browser.getProcessedConfig()).seleniumAddress}/session/${(await browser.getSession())['id_']}/chromium/send_command`,
            {
                body: JSON.stringify({
                    cmd: 'Page.setDownloadBehavior',
                    params: { behavior: 'allow', downloadPath: downloadsPath },
                }),
            },
        );
}
Protractor solution:
import * as got from 'got';

async onPrepare() {
        await got.post(
            `${(await browser.getProcessedConfig()).seleniumAddress}/session/${(await browser.getSession())['id_']}/chromium/send_command`,
            {
                body: JSON.stringify({
                    cmd: 'Page.setDownloadBehavior',
                    params: { behavior: 'allow', downloadPath: downloadsPath },
                }),
            },
        );
}
Have the same issue on Linux. Python samples given here do not work on Linux for me. Did anybody made it work on Linux?
@osvaib
hi guys,i use your code,it can download files from some url ,but some url download not work。
i use tencent legu to reinforce my apk,and download the reinforced apk, and the code you post can not work。
and if i disable headless mode,it can download frome tencent,but once the downloading completes,the chrome is closed, 
and so the codes below downloading to operate chrome will case exception,
however, download from other URL chrome does not closed when downloading completes。
looking forward to your reply!
Everybody who has problems with downloads not being saved in headless:
Check if a download is being started in a new tab (via target _blank link or window.open) — most likely it's the reason why it doesn't work for you.

This is the issue of current implementation which supports download behavior setting only for the current tab. Waiting for the solution from the devs.
Cc: caseq@chromium.org

Comment 156 Deleted

@Comment 154

This is correct. However, the "command" can be run on a new tab in most cases and then a refresh will trigger the download.

For example, my function is here:

def headless_download_enable(download_dir):
	browser.execute_script("var x = document.getElementsByTagName('a'); var i; for (i = 0; i < x.length; i++) { x[i].target = '_self'; }")
	browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
	params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
	browser.execute("send_command", params)

This function is triggered on each new page load. The first execute command uses javascript to force all targets on the page to _self, this works for most of my use cases and allows headless downloading to proceed unimpeded. However, I ran into a javascript pop-up today. For that, I trigger the pop-up with a click, switch to the new tab, run the fix and then run driver.refresh() which then allows the download to proceed.

Hope this helps anyone stuck.

Comment 158 by mariushu...@gmail.com, Jul 16 (4 days ago)

Dear devs, can we expect the bug to be fixed soon?

Comment 159 by rashdha...@gmail.com, Jul 17 (3 days ago)

Is there any workaround for protractor till the bug is fixed?

Comment 160 by rashdha...@gmail.com, Jul 17 (3 days ago)

@151: This solution does not seem to work.

Comment 161 by magdich....@gmail.com, Jul 17 (3 days ago)

@159: see my solution above

Comment 162 by magdich....@gmail.com, Jul 17 (3 days ago)

@159 my solution will work with async/await 

Comment 163 by rashdha...@gmail.com, Jul 18 (2 days ago)

@magdich....@gmail.com :
I added this in my config file inside onPrepare() with async/await.But I still dont see download happening onclick.Please see the config below
var downloadsPath = path.resolve(__dirname, '\DataDownload')
var specsToRun = process.env.specsToRun || [
    'tests/comp.js'];
exports.config = {  
    framework: 'jasmine2',
    allScriptsTimeout: 600000,
    getPageTimeout: 600000,
    specs: specsToRun,
    capabilities: {
        shardTestFiles: true,
        maxInstances: 1,
        'directConnect': true,
        'browserName': 'chrome',
        'platform': 'ANY',
        'version': 'ANY',
        SELENIUM_PROMISE_MANAGER: false,
        'chromeOptions': {
            args: ["--headless", '--disable-gpu', "--disable-dev-shm-usage", "--window-size=800x600",'--enable-logging', '--remote-debuging-port=9222'],
            prefs: {
                'download': {
                    'prompt_for_download': false,
                    'default_directory': downloadsPath,
                    'directory_upgrade': true                   
            }
        }
    }    
},

Comment 164 by rashdha...@gmail.com, Jul 18 (2 days ago)

onPrepare:function () {       
        browser.driver.manage().timeouts().implicitlyWait(1000);
        browser.manage().window().maximize();
        global.presenceOf = protractor.ExpectedConditions.presenceOf;
        global.EC = protractor.ExpectedConditions;     

        global.isAngularSite = function (flag) {
            browserinstance.ignoreSynchronization = !flag;
        };        
       
        async function getprep(){
            await got.post(
            `${(await browser.getProcessedConfig()).seleniumAddress}/session/${(await browser.getSession())['id_']}/chromium/send_command`,
            {
                body: JSON.stringify({
                    cmd: 'Page.setDownloadBehavior',
                    params: { behavior: 'allow', downloadPath: downloadsPath },
                }),
            },
        );
    }
    }
Showing comments 65 - 164 of 164 Older

Sign in to add a comment