Laravel Dusk Automation

Yesterday, I described getting started with Laravel Dusk, and finished off with the suggestion that one of my next steps would be to get Dusk running on Codeship. I thought that this might be relatively straightforward, but there were a few twists and turns before I got my tests to green.

First Attempt

The first thing to do was to set up a second pipeline on codeship where the browser tests could take place. I would also need to ensure that a local server would be running that the browser tests could connect to. So the first attempt at the pipeline looked like this:

nohup bash -c "php artisan serve --env=dusk.local 2>&1 &" && sleep 4
php artisan dusk

The correct version of PHP

The first snag I hit was even getting the test process to run. The error I got was that I was using the wrong version of PHP. Codeship has pretty clear documentation on the various versions of PHP that are available, and how to use them. I already had

phpenv local 7.0

Talking to Chrome

So having got past issues with the version of PHP, I then hit the next snag, which was that the request to chromedriver was simply timing out for each attempt to run the test:

Facebook\WebDriver\Exception\WebDriverCurlException: Curl error thrown for http POST to /session with params: {"desiredCapabilities":{"browserName":"chrome","platform":"ANY"}}Operation timed out after 30001 milliseconds with 0 bytes received
static::$chromeProcess = new Process('./chromedriver-linux', realpath(__DIR__.'/../bin'), ['DISPLAY' => ':0'], null, null);

Sundry Items

As part of my fiddling trying to get the chromedriver to work, I came across a couple of other tidbits that I put in place prior to getting everything working. The main thing was wanting to specify the location of the chrome browser, as Codeship doesn’t have it in the standard linux location. A suggestion that also came out of the research I did was to prevent Chrome running as though it were the first time (i.e. all the gubbins Chrome does to introduce itself to the user). To resolve these, I expanded the driver method of the base DuskTestCase class:

protected function driver()
{
$chromeOptions = new ChromeOptions();
$chromeOptions->setBinary('/usr/bin/chromium-browser');
$chromeOptions->addArguments(['no-first-run']);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);

return RemoteWebDriver::create(
'http://localhost:9515',
$capabilities
);
}

Clean Running

These changes were all very well, but I didn’t want these changes to be having an impact on my local dev environment, where I already had the Dusk tests running nicely. So I decided to use some environment variables to control things a bit more cleanly.

public static function prepare()
{
if (env('DUSK_START_CHROMEDRIVER', true)) {
static::startChromeDriver();
}
}
protected function driver()
{
$chromeOptions = new ChromeOptions();
if ($binary = env('DUSK_CHROME_BINARY')) {
$chromeOptions->setBinary($binary);
}
$chromeOptions->addArguments(['no-first-run']);
$capabilities = DesiredCapabilities::chrome();
$capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions);

return RemoteWebDriver::create(
'http://localhost:9515',
$capabilities
);
}
phpenv local 7.0
export DUSK_START_CHROMEDRIVER=false
export DUSK_CHROME_BINARY=/usr/bin/chromium-browser
nohup bash -c "./vendor/laravel/dusk/bin/chromedriver-linux 2>&1 &"
nohup bash -c "php artisan serve --env=dusk.local 2>&1 &" && sleep 4
php artisan dusk
The all important green ticks for my tests

Conclusion

In essence, setting this up was not all that complicated, it just took some time for me to work out what the actual problems were. Dusk has motivated me to get my browser testing automated, which is definitely a good thing (tm).

just some guy, y'know?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store