Laravel Dusk with Github Actions 
Tags: laravel, dusk, github, ci
Published: 2020-11-28 03:37:01

Hello,

i was tasked to do Unit Testing for one of my projects, the test case that i was tasked with is :-
- User can login and see Dashboard
- User can login and see Developer Portal
- User can login and see Administration Panel

basically the test is quite easy and straight-forward right?

so im off with installing `Laravel Dusk` since this kind of test involves with the actions of seeing the UI itself.

if you're not familiar with Laravel Dusk, Laravel Dusk is a official library that are supported by the Laravel itself. 

> Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your machine. Instead, Dusk uses a standalone ChromeDriver installation. However, you are free to utilize any other Selenium compatible driver you wish. - [Laravel Dusk](https://laravel.com/docs/8.x/dusk#introduction)



So Without further ado, 

## The Preparation
Make sure that you have created the user factory, user seeder as well as enable user factory inside `DatabaseSeeder.php` file before starting this unit test. since its requires dummy user to test the test case.

## Laravel Dusk Installation
installing Laravel Dusk is quite the breeze, just run this into the CLI of your project `composer require --dev laravel/dusk` after installing the packages you can then run `php artisan dusk:install` to install your laravel dusk.

## Laravel Dusk Environment Configuration
By Default, when the laravel dusk environment configurations file `.env.dusk` is not exist, it will automatically use the .env as the environment configuration temporarily. in our case, we need to use a separate database which is called `dusktest` database and create the `.env.dusk` file onto your root project folder. Here's the sample of my `.env.dusk`

> **Important** Make sure to generate the APP_KEY as well. run `php artisan key:generate` then copy the key from `.env` to `.env.dusk`

```
APP_NAME=dusk
APP_ENV=local
APP_KEY={your-key-here}
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000

LOG_CHANNEL=stack
FLARE_KEY=

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dusktest
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=array
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=array
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_NAME="${APP_NAME}"
MAIL_FROM_ADDRESS="no-reply@ksud.com"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

```

## The Test Scripts
Run `php artisan dusk:make CommonTest` onto your CLI , it will created the Test File inside `my-project/tests/Browser/CommonTest.php` . After that we need to create the test case inside the test scripts . Here's the test scripts that i've created .

```
<?php

namespace Tests\Browser;

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Support\Facades\Artisan;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class CommonTest extends DuskTestCase
{
    use DatabaseMigrations;

    /**
     * Can Login and see Dashboard
     *
     * @return void
     */
    public function testCanLoginAndSeeDashboard()
    {
        //Seed dummy user data
        Artisan::call('db:seed');
        $user = User::first();
        $this->browse(function ($first) use ($user){
            $first->loginAs($user)
                  ->visit('/dashboard')
                  ->assertSee('Dashboard');
        });
    }

    /**
     * Can Login and see Developer Portal
     *
     * @return void
     */
    public function testCanLoginAndSeeDeveloperPortal()
    {
        //Seed dummy user data
        Artisan::call('db:seed');
        $user = User::first();
        $this->browse(function ($first) use ($user){
            $first->loginAs($user)
                  ->visit('/developer')
                  ->assertSee('Connective Exchange');
        });
    }

    /**
     * Can Login and see Administration Panel
     *
     * @return void
     */
    public function testCanLoginAndSeeAdministrationPanel()
    {
        //Seed dummy user data
        Artisan::call('db:seed');
        $user = User::first();
        $this->browse(function ($first) use ($user){
            $first->loginAs($user)
                  ->visit('/admin')
                  ->assertSee('Resources');
        });
    }
}

```

## Github Action Workflow 
So basically if you're familiar with github actions , the github action workflow scripts should be inside `my-project/.github/workflows/actions.yml` you can rename the file as you desired.
 
```
# my-project/.github/workflows/actions.yml
name: Unit Test

on:
  push:
    branches: [develop]
  pull_request:
    branches: [master, develop]

jobs:
  PHPUnit:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.0.21
        env:
          MYSQL_ALLOW_EMPTY_PASSWORD: yes
          MYSQL_DATABASE: dusktest
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
      - uses: actions/checkout@v2
      - name: Configure Application
        run: bin/ci
      - name: Configure Laravel Dusk
        run: bin/ci-dusk
      - name: Execute Dusk tests via PHPUnit
        run: php artisan dusk

```

you have to create some of this bash files to ensure the scripts working. 

```
# my-project/bin/ci

#!/usr/bin/env bash

cp .env.example .env
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
chmod -R 777 storage bootstrap/cache
php artisan key:generate
php artisan config:clear

```

```
# my-project/bin/ci-dusk

#!/usr/bin/env bash

php artisan dusk:chrome-driver `/opt/google/chrome/chrome --version | cut -d " " -f3 | cut -d "." -f1`
chmod -R 0755 vendor/laravel/dusk/bin/
php artisan serve  > /dev/null 2>&1 &
curl localhost:8000 &
./vendor/laravel/dusk/bin/chromedriver-linux > /dev/null 2>&1 &

```

Simpy push your codes to github, and it should be good to go! Thank you for reading.

Honorable Mentions 
- Nasrul Hazim (Helping out with the workflow configurations)