Introduction
In our first Laravel guide we explained how to create unit and feature tests and how to automate them with Buddy. In this guide, we'll show you how to run E2E tests using Laravel Dusk.
Laravel Dusk is a type of browser tests introduced in Laravel in v5.4. The tests use the ChromeDriver by default, but they can be easily configured to use Selenium in a different browser as well.
Test project
The process of adding tests will be explained on the basis of a simple calculator. You can read how to create such calculator in our Laravel basics guide.
First, you should fork and clone this project: github.com/buddy-works/laravel-first-steps.
git clone git@github.com:buddy-works/laravel-first-steps.git
Once done, you can check the application straight away by running:
$ cd laravel-first-steps $ composer install $ php artisan serve
If you encounter any troubles, check if you have installed all required things.
Dusk installation
Installing Dusk requires a couple of steps:
- Install Laravel Dusk and add it to the project's dependency:
bash $ composer require --dev laravel/dusk
- Register DuskServiceProvider. For that, open
app\Providers\AppServiceProvider.php
and add the use statement:php use Laravel\Dusk\DuskServiceProvider;
Register the provider in the
register
method by adding this part of code:if ($this->app->environment('local', 'testing')) { $this->app->register(DuskServiceProvider::class); }
The whole
AppServiceProvider
file will look like this:<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Laravel\Dusk\DuskServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Bootstrap any application services. * * @return void */ public function boot() { // } /** * Register any application services. * * @return void */ public function register() { if ($this->app->environment('local', 'testing')) { $this->app->register(DuskServiceProvider::class); } } }
Finally, install Dusk by running
$ php artisan dusk:install
Writing first Dusk test
At the beginning, we need to remove the exemplary test or it will return errors:
$ rm tests/Browser/ExampleTest.php
Once ready, let's add our first test by running the artisan
command and adding the name of the class in which we're going to write the tests:
$ php artisan dusk:make MyFirstDuskTest
The class will be created in the tests/Browse
directory. Let's write a simple test that will open the website with the calculator and run a simple 1 + 3
addition in the tests/Browser/MyFirstDuskTest.php
and check the result:
<?php
namespace Tests\Browser;
use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class MyFirstDuskTest extends DuskTestCase
{
/**
* A Dusk test example.
*
* @return void
*/
public function testExample()
{
$this->browse(function ($browser) {
$browser->visit('/')
->type('a', 3)
->type('b', 1)
->press('Execute')
->assertPathIs('/calc')
->assertSee('4');
});
}
}
Local testing
First, we need to run the application. We'll launch it on a predefined port so that we know which address should we use in the test configuration:
$ php artisan serve --port=8080
Now we need to set the website's address in the .env
config file. This address will be used in the tests:
APP_URL=http://localhost:8080
The tests are written and ready to be launched:
$ php artisan dusk
Automating Dusk tests with Buddy
Setting up the pipeline
With everything set up locally, we can use Buddy to automate the whole process. Let's create a pipeline that will run the tests once a day at a given time (you can change the interval to whatever you need). If you haven't forked our Laravel tutorial repository before, you can do it now: github.com/buddy-works/laravel-first-steps. We're going to use it in the example below.
The tests are already available in the dusktests
branch in case you haven't written them before.
Create a new project, choose GitHub as the provider, and select the forked Laravel repository:
Project configuration
Buddy will synchronize the project and detect the type of its contents:
Post-synchronization screen
Click the button to add a new pipeline, change the source branch to
dusktests
, and set the trigger mode toRecurrent
to run the tests on a given time interval:Pipeline configuration
You can also configure the pipeline with a YAML file and push it to the dusktests
branch.
Configuring the test action
With the pipeline in place, we can now configure the tests:
Add the PHP action and paste the following commands:
composer install HOST_NAME=$(hostname -I | tr -d ' ') sed -i "s/localhost/$HOST_NAME/g" .env php artisan serve --port 8080 --host $HOST_NAME & script -c "php artisan dusk" -eq
Action details
Script details
HOST_NAME=$(hostname -I | tr -d ' ')
– fetches and trims the IP of the containersed -i "s/localhost/$HOST_NAME/g" .env
– changes the IP in.env
to the fetched addressphp artisan serve --port 8080 --host $HOST_NAME &
– runs application with host and portscript -c "php artisan dusk" -eq
– runs the Dusk tasks; we cannot do that with a script command because command fields in Buddy are not interactive
Switch to the Services tab and attach Selenium Chrome:
Attaching Chrome service
The last thing to do is updating the config file with the details of the testing server. The example below will let you run the tests both locally and remotely on Buddy. In Buddy, Selenium tests are available at
http://selenium-ch:4444/wd/hub
. Go totests\DuskTestCase.php
and set the driver address as follows:protected function driver() { $options = (new ChromeOptions)->addArguments([ '--disable-gpu', '--headless', '--window-size=1920,1080', ]); return RemoteWebDriver::create( env('SELENIUM_HUB', 'http://localhost:9515'), DesiredCapabilities::chrome()->setCapability( ChromeOptions::CAPABILITY, $options ) ); }
http://localhost:9515
is the default address of the Chrome driver. As you can see, we used an environment variable to store the address of the Selenium Hub – this is a good practice that will allow you to test your code in different environments without the need of editing the files.
To add the variable, switch to the Variables tab and click Add a new variable. Set the key to SELENIUM_HUB
, paste http://selenium-ch:4444/wd/hub
to the value input, and configure the scope (workspace, project, or pipeline).
Adding a new variable
Running the tests
The tests have been configured to run on the interval, but you can run them manually at any time with the Run button:
Running pipeline
Once the tests have finished, you can view the execution logs in the dedicated tab:
Execution tab
Congratulations! You have successfully written and configured browser tests for your PHP/Laravel application!
Auto-deployment
Just like with regular Laravel unit tests, you can expand your delivery process by adding a deployment action to your type of server for immediate feedback. Combine it with notifications, and you'll neves miss a thing going on in your project:
Test & deployment pipeline