Chrome 59 (still beta/canary) supports a headless mode.
Before this will work with Dusk, Chromedriver will have to add support for headless chrome. The latest version of Chromedriver is currently 2.29 which Supports Chrome v56-58 which does not include headless Chrome.
I tried to have Dusk run Chrome in headless mode with this code in my DuskTestCase.php
protected function driver()
{
$desiredCapabilities = DesiredCapabilities::chrome();
$options = new ChromeOptions();
$options->setBinary('/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary');
$options->addArguments([
'--headless',
// avoid an error from a missing Mesa library
'--disable-gpu',
]);
$desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $options);
return RemoteWebDriver::create(
'http://localhost:9515', $desiredCapabilities
);
}
I get this error:
1) Tests\Browser\ExampleTest::testBasicExample
Facebook\WebDriver\Exception\UnknownServerException: unknown error: unrecognized Chrome version: HeadlessChrome/60.0.3073.0
(Driver info: chromedriver=2.28.455517 (2c6d2707d8ea850c862f04ac066724273981e88f),platform=Mac OS X 10.12.3 x86_64)
I realize that we will have to wait for Chromedriver to add support for headless Chrome but I thought it would be useful to create this issue to have a place to discuss progress.
UPDATE I updated to Chromedriver 2.29 and I no longer get the "unrecognized Chrome version" error but now I run php artisan dusk and it just seems to hang for a bit and then eventually errors out. The hanging appears to be when facebook/webdriver sends a curl request to Chromedriver and it times out waiting for a response. For example, it tries to curl something like http://localhost:9515/session/26935cbeaf02f3d76abdbd43ca28432d/url and times out.
If you're going to use it like that, I guess you're right and Chrome Driver needs to support it.
I might have understood it wrong, but I think with headless mode we would be able to talk to the browser directly instead of going through the Chrome Driver, which would be quite a rework to stop relying on Facebook Webdriver and figure out a way for Dusk to communicate with the browser. The upside should be an undeniably boost in performance with the loss of _work delegation_ to Facebook WebDriver. Dusk would have to define a layer for browsers and implement the contract on a HeadlessChrome class, as well as PhantomJS and so on.
@deleugpn , dusk already has phantomjs() capability, doesn't it?!
@shehi yes, but if I'm not mistaken, it still relies on Facebook Webdriver for that. My interpretation for the new --headless from Chrome is that we would bypass Facebook WebDriver and talk straight to Chrome. And for that, we would have to rework the way dusk's communication with browsers work.
@deleugpn Just let me set the record straight - the headless Chrome will still communicate through WebDriver protocol, there is no difference from full-featured Chrome.
The Chromedriver is the way of communicating and remotely controlling Chrome. There is AFAIK nothing like "talk to the browser directly" - the chromedriver is the way of communicating with the browser directly...
The "indirect" way is though Selenium server - but the Selenium server also implements the WebDriver protocol (and passes tha calls to the respective browser driver - like chromedriver), so it is still the same way of communication.
Chrome 59 just got released on the stable channel. Is there any progress on using it with Dusk?
@jonnybarnes I'm waiting on the Chromedriver update to work on it. The support for Chrome 59 was added a little over a month ago into the Chromedriver, but no release to actually use it so far.
@deleugpn I think Chromedriver may support it. I asked the question on the mailing list: https://groups.google.com/d/topic/chromedriver-users/T5G20PugKVU/discussion
@ejunker I'm lousy at C++, but https://github.com/bayandin/chromedriver/commit/7cca62f731168102358b057fedb7fbb28ac21356 came after https://github.com/bayandin/chromedriver/commit/d2b414fd71281a64a1c02a92b65344c2fdf57b63, so I don't really know how that would be possible.
Chrome driver 2.30 is out but still opens the browser on mac.
protected static function buildChromeProcess()
{
return (new ProcessBuilder())
->setPrefix(realpath(__DIR__.'/../bin/chromedriver-'.static::driverSuffix()))
->setArguments(['--headless', '--disable-gpu'])
->getProcess()
->setEnv(static::chromeEnvironment());
}
This appears to be being worked on: https://twitter.com/laravelphp/status/874256617105129473
Dusk 2.0, which will release with Laravel 5.5, utilizes Chrome 59's new "headless" mode! Easily disable if you want to see the browser. 馃敟
This is working great for me with chromedriver 2.30 and Chromium 59. Note that arguments need to be specified without the double hyphens.
@kolev, you're trying to pass the arguments to chromedriver, not Chromium itself.
First, I installed the lbaey/chromedriver package to automatically download the latest version of Chromedriver to vendor/bin.
Here's what I'm using in my TestCase (actually a Behat FeatureContext) to set it all up:
protected static function buildChromeProcess()
{
return (new ProcessBuilder())
->setPrefix(base_path('vendor/bin/chromedriver'))
->getProcess()
->setEnv(static::chromeEnvironment());
}
protected function driver()
{
$capabilities = DesiredCapabilities::chrome();
$chromeOptions = (new ChromeOptions)->addArguments(['headless', 'disable-gpu']);
$capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);
return RemoteWebDriver::create('http://localhost:9515', $capabilities);
}
It seems I had to replace the 'setPrefix(...)' with setPrefix(implode(DIRECTORY_SEPARATOR, [__DIR__, '..', 'vendor', 'bin', 'chromedriver'])) as the app container doesn't have basePath().
I am hacking this in a clean dev version of Laravel 5.5 though, just for a standalone play.
Any updates on this? Does it work by default in Laravel 5.5 (stable)?
Think this can be closed now since it's implemented in the latest Dusk release.
Most helpful comment
This is working great for me with chromedriver 2.30 and Chromium 59. Note that arguments need to be specified without the double hyphens.
@kolev, you're trying to pass the arguments to chromedriver, not Chromium itself.
First, I installed the lbaey/chromedriver package to automatically download the latest version of Chromedriver to vendor/bin.
Here's what I'm using in my TestCase (actually a Behat FeatureContext) to set it all up: