Laravel Dusk provides you with an option to define custom methods for your browser testing. If you have a set of code that you are re-using in multiple places, it's good idea to refactor that into a browser macro.
Once you refactor the code into browser macro method, you can re-use it in your dusk browser tests.
Typically, you would define your browser macro's inside a Service Provider.
Here is how you can do it.
Create a new service provider in your laravel application.
php artisan make:provider DuskServiceProvider
This will create a new service provider inside your app > Providers directory. Let's register this provider
Open file app > config > app.php and include the newly created provider in the provider's array
'providers' => [
// Other Service Providers
App\Providers\DuskServiceProvider::class,
],
You can now add new browser macro method's inside the boot
method of your DuskServiceProvider
class.
<?php
namespace App\Providers;
use Laravel\Dusk\Browser;
use Illuminate\Support\ServiceProvider;
use Facebook\WebDriver\WebDriverBy;
class DuskServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
Browser::macro('chooseRandomRadioOption', function ($radioElement) {
$radio_options = $this->driver->findElements(WebDriverBy::name($radioElement));
$radio_options[array_rand($radio_options)]->click();
});
Browser::macro('elementExists', function ($element) {
return count($this->driver->findElements(WebDriverBy::cssSelector($element))) > 0 ? true : false;
});
}
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
}
In this service provider I have added two methods chooseRandomRadioOption
and elementExists
. As you notice the macro function accepts two parameters, the first one is the name of the custom method and the second one is the closure function.
Inside chooseRandomRadioOption
method I am making use of driver instance on browser object to find all the radio elements and then choose a random one. Similarly elementExists
returns a boolean true or false depending upon particular element exists on the css path. Such functions comes handy instead of repeating the code in your tests.
$this->browse(function ($browser) use ($user) {
$browser->visit('/home')
->chooseRandomRadioOption('sex')
->elementExists('.table-bordered');
});
We can make use of the browser macro functions in our tests. This makes the code more readable and compact.