Using Browser Macros in Laravel Dusk

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.

tgugnani: Web Stuff Enthusiast.