I recently got PHPUnit and Laravel Dusk tests to pass for AIP Demos when either running Dusk in an OS with a graphical environment or one that is using xvfb (X virtual frame buffer). I also got them to run on the container created by TravisCI. It took quite a bit of trial and error, but that badge of an image above is a badge of honor. I had to slay quite a few more intimidating dragons than the pat on the back one deserves for launching, say, Atlassian sites or something.
The hardest part of these tests was getting Laravel Dusk to work in a pure command-line environment, namely the docker container I use to deploy it and the TravisCI container. Take a look at the docker container that AIP Demos is deployed on. It is based on the php:apache docker container that uses Debian version 8 (jessie). I had to add a few packages:
xvfb is the virtualized X environment needed to allow a browser such as Chromium to be launched by the
chromedriver command used by Laravel Dusk.
libfontconfig are dependencies that
chromium needs. And of course, you’ll want the
chromium package. Some Linux distros, like Ubuntu, might have this as
Next, I had to consult the repo of a savvy web server admin / developer to get things working from here. It seems that the
chromedriver program will try to either start
chromium-browser. For the
php:apache container, installing
google-chrome-stable from Google doesn’t seem to do the trick. Chromium has to be started with the
--no-sandbox flag in order to properly accommodate
chromedriver. A good way to do this is by symlinking the
chromium-browser commands to a script, such as the one called xvfb-chromium created by this excellent user, which I only slightly customized. This can be done in a Dockerfile that does the following: copies the
xvfb-chromium script to either
/usr/bin or a less controversial place in the container server’s path, makes sure the script is executable, and creates the symlinks. I also decided to have Xvfb run on
DISPLAY :0 instead of
:99, which seemed to cause fewer problems. By far, the trickiest part was finding out how to make
chromedriver, started by Dusk, launch the Chromium browser in a way in which Dusk was satisfied, and I have okaufmann to thank.
One caveat of this approach is that after
php artisan dusk is ran, the
chromium process is still left running. Since a
DuskTestCase seems to only reset a database after the
php artisan dusk command finishes, I needed to run several such commands for my various tests that required an empty DB, which results in several leftover
chromium processes. I added a static tearDownAfterClass method to
DuskTestCase that gets the PIDs of the
chromium program and terminates them if the web app is running on Linux and
/usr/bin/xvfb-chromium is present.
tearDownAfterClass comes with PHPUnit and is ran after all the test methods in a class finish. It will also terminate the Xvfb process.
This setup finally got Laravel Dusk to successfully run tests in the docker container. The next challenge was making it work on TravisCI.
To make this happen, I ended up configuring the container with this .travis.yml, which basically came from one shared on laravel-news.com that should be in the docs and hopefully will be soon. The key was to use the Ubuntu “trusty” container with a modern version of PHP, making sure
composer install is ran, starting
xvfb from an
init.d script that would appear to be available in this version of Ubuntu, running
chromedriver manually in the background, manually copying
.env, setting an appropriate DISPLAY environment variable, and starting the built-in PHP web server. Another crucial thing to remember is to set
.env.testing to a URL that the web server will run on, which is typically
These are the secrets to my success. I hope you might find this experience helpful.