I'm trying to automate a file download in headless chrome using Laravel/Dusk.In GUI mode,the file downloads just fine in my download folder.But in headless mode,the download does not take place at all.Is there any way to solve this issue?
Asked
Active
Viewed 2,538 times
2
-
See https://stackoverflow.com/q/48888036/4848587. – Jonas Staudenmeir May 18 '18 at 13:19
3 Answers
5
For those who come across this, I found a simple solution with the current version of Laravel at the time of writing this.
I suggest first creating a directory in your storage path called temp
(probably want to gitignore this too), and then navigate to the DuskTestCase.php
file setup with the Dusk installation.
Under the driver
method, add the following under the section that initializes the ChromeOptions
variable.
$options->setExperimentalOption('prefs', [
'download.default_directory' => storage_path('temp')
]);
The driver
function should now look like this:
$options = (new ChromeOptions())->addArguments([
'--disable-gpu',
'--headless',
'--window-size=1920,1080'
]);
$options->setExperimentalOption('prefs', [
'download.default_directory' => storage_path('temp')
]);
return RemoteWebDriver::create(
'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
)
);
As a side note, this worked for me with a PDF file created via JS, so I can't definitively say how this works with a file downloaded from the back-end.

Garrett
- 353
- 7
- 14
0
public function testDownload($account){
$this->browse(function (Browser $browser) {
$download_path = storage_path('your/download/path');
$url = $browser->driver->getCommandExecutor()->getAddressOfRemoteServer();
$uri = '/session/' . $browser->driver->getSessionID() . '/chromium/send_command';
$body = [
'cmd' => 'Page.setDownloadBehavior',
'params' => ['behavior' => 'allow', 'downloadPath' => $download_path]
];
(new \GuzzleHttp\Client())->post($url . $uri, ['body' => json_encode($body)]);
// Start your test
$browser->visit("http://example.com/export")
//your asserts here
}

Yuvrajsinh Jhala
- 86
- 4
-
7Code-only answers are not considered to be good quality. Please open up and elaborate what this code snippet does. Also if you copied it somewhere, mention the source. Thanks. – quinz Jul 11 '18 at 10:53
-
This is the straight forward answer to the question, Anybody with little bit of larval dusk knowledge will understand it. Anyway it overwrites the download behaviour of chrome for particular session. Here is the reference (https://bugs.chromium.org/p/chromium/issues/detail?id=696481#c61) – Yuvrajsinh Jhala Jul 12 '18 at 05:21
-
Per documentation `Page.setDownloadBehavior` has been marked as deprecated Source: https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-setDownloadBehavior – jdenoc May 12 '22 at 04:22
0
It's not necessary to trigger a separate Guzzle POST, I used a CustomWebDriverCommand
instead:
$command = new \Facebook\WebDriver\Remote\CustomWebDriverCommand(
$driver->getSessionID(),
"/session/:sessionId/chromium/send_command",
"POST",
[
"cmd" => "Page.setDownloadBehavior",
"params" => ["behavior" => "allow", "downloadPath" => '/your/download/path']
]
);
$driver->getCommandExecutor()->execute($command);

buchi
- 1
- 1
-
Welcome to the StackOverflow community. Check the https://stackoverflow.com/help/how-to-ask to improve your question. Hope you will stay with us for a long time :) – Aleksander Ikleiw Jul 17 '20 at 15:13