Testing a live site with Laravel Dusk using Docker Compose

Today we will do a quick tutorial on how to quickly install and run Laravel Dusk on your project using Docker.

We will use Docker only for running the selenium driver. It isn't therefore needed to use rocker to run the site we're testing again.


First things first.

Installing dusk into laravel

In our laravel application we follow the first steps as shown in the official documentation. So we add the laravel dusk composer dependency:

composer require laravel/dusk

Then, we add the service provider in our AppServiceProvider:

use Laravel\Dusk\DuskServiceProvider;

/**
 * Register any application services.
 *
 * @return void
 */
public function register()
{
    if ($this->app->environment('local', 'testing')) {
        $this->app->register(DuskServiceProvider::class);
    }
}

And finally, we run the `dusk:install` Artisan command:

php artisan dusk:install

Ok. Nothing new so far.


Installing docker with docker compose

I'm not going to describe how to install docker on your machine because it differs for every operating system. It's best to follow the official instructions from docker  [Docker - Build, Ship, and Run Any App, Anywhere](https://www.docker.com/).

You know you're ready when the following command shows the version of docker-compose:

$ docker-compose -v
docker-compose version 1.11.2, build dfed245

Now that docker and docker-compose are properly setup, we go to the next step.

The docker-compose file

Let's make a new `ci` directory under our project rood folder and put a new file named `selenium-docker-compose.yml` in it.

The contents of this yml file should be:

version: '2'
services:

  dusk_tests:
    image: php:7.1.1-cli
    command: tail -f /dev/null
    volumes:
      - ../:/usr/src/myapp
    links:
      - selenium

  selenium:
    image: selenium/standalone-chrome:3.0.1-fermium

Here we define two docker instances we will use.

  dusk_tests:
    image: php:7.1.1-cli

First we have a `dusk_tests`. This is a machine with php-cli installed. We will run `php artisan dusk` from within this machine. 

    command: tail -f /dev/null

This skips the default command of the php instance.

    volumes:
      - ../:/usr/src/myapp

Here we "symlink" the root folder `../` of the app in our file system with the path `/usr/src/myapp` of the php instance.

    links:
      - selenium

This creates a private network between the php instance and the selenium instance we define below. This means that we can call the url `http://selenium` or `http://selenium:80` from within the php instance and reach the port 80 of the selenium instance. Pretty handy.

  selenium:
    image: selenium/standalone-chrome:3.0.1-fermium

What we do here is we define the selenium docker instance that uses an official selenium image with the Chrome. 

We're almost there. The next step is to ...

Setup Laravel Dusk to use our selenium instance

Open the file `tests/DuskTestCase.php` and update the `driver()` method to look like this:

protected function driver()
{
    return RemoteWebDriver::create(
        'http://selenium:4444/wd/hub', DesiredCapabilities::chrome()
    );
}

Have you noticed the change? We essentially tell dusk to use the port 4444 of the selenium instance.

Last step.

Our first test

At this final step we will be creative. Go to the DustTestCase and add the following method:

protected function baseUrl()
{
    return 'https://google.com';
}

Yes, you guessed right. We will write a test using the Google's site.

Now go to the 'Browser/ExampleTest.php' and assert we see the text "Google" at google's home page. 

public function testBasicExample()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/')
                ->assertSee('Google');
    });
}

Let's run our tests. From the root path of your app, run the following command:

$ docker-compose -f ci/selenium-docker-compose.yml run dusk_tests bash -c 'cd /usr/src/myapp && php artisan dusk'

Let's explain:

-f ci/selenium-docker-compose.yml

Here we tell compose to use the file we created.

run dusk_tests bash -c 'cd /usr/src/myapp && php artisan dusk'

This runs a bash command in the instance `dusk_tests`. This bash command navigates to the app directory and runs `artisan dusk`.

Did you run the command?

What a nice image:

Alright I lied. This is the next step.

Make the tests fail

I wanted to show you a nice way of debugging when things go wrong. 

Go ahead and change the assertion in the test to something like:

->assertSee('Moogle')

Of course the tests will file (I hope!).

What I really like about dusk is that it takes a screenshot of the browser when the tests fail. Go check the folder under `/tests/Browser/screenshots`.

That's it folks.

I hope you enjoyed! Have fun!