ddutra's avatar

Laravel Dusk Authentication for every test

Hello guys,

Been experimenting with Laravel Dusk. I've been using Codeception for acceptance tests for my projects.

Anyways I'd like to organize my tests in test Classes. Let's say I create a Tests/Browser/EmployeesTest class and in this class I keep all the tests in my application related to the Employees Management module.

Coming from Codeception the first thing I miss is the ability to have a __before() function that runs before every function and logs the user in. I've tried with setUp() and even __construct() with no success.

Do you have to login the user for every test function? Something I am missing?

PS: The following code does not work.

<?php

namespace Tests\Browser;

use \App\Models\User;
use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class EmployeesTest extends DuskTestCase
{
    public function setUp()
    {
        parent::setUp();
        $this->browse(function ($browser) {
            $browser->loginAs(User::where('email', '[email protected]')->firstOrFail);
        });
    }

    /**
     * Verify if the employees list is showing
     *
     * @return void
     */
    public function testEmployeeListIsShowing()
    {
        $this->browse(function ($browser) {
            $browser->visit('/employees/list')
                    ->waitFor('#employees-datalist');
        });
    }

    /**
     * Open the Create employee form
     * 
     * @return void
     */
    public function testOpenCreateEmployeeForm()
    {
        $this->browse(function($browser) {
            $browser->visit('/employees/list')
                    ->waitFor('#employees-create-btn');
        });
    }
}

And of course if I do this:

<?php

namespace Tests\Browser;

use \App\Models\User;
use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class EmployeesTest extends DuskTestCase
{
    /**
     * Verify if the employees list is showing
     *
     * @return void
     */
    public function testEmployeeListIsShowing()
    {
        $this->browse(function ($browser) {
            $browser->loginAs(User::where('email', '[email protected]')->firstOrFail)
                    ->visit('/employees/list')
                    ->waitFor('#employees-datalist');
        });
    }

    /**
     * Open the Create employee form
     * 
     * @return void
     */
    public function testOpenCreateEmployeeForm()
    {
        $this->browse(function($browser) {
            $browser->loginAs(User::where('email', '[email protected]')->firstOrFail)
                    ->visit('/employees/list')
                    ->waitFor('#employees-create-btn');
        });
    }
}

It works.

Thanks.

0 likes
2 replies
aaronranard's avatar

Hey, in Dusk 2.0 the concept of Pages was introduced. This means you can extend the base Page component and add complex functionality into there, so your example above would become:

tests/Browser/Pages/LoginPage.php

<?php

namespace Tests\Browser\Pages;

use App\Models\User;
use Laravel\Dusk\Browser;

class LoginPage extends Page
{
    /**
     * Get the URL for the page.
     *
     * @return string
     */
    public function url()
    {
        return '/login';
    }
    /**
     * Abstract the Login functionality
     *
     * @param  \Laravel\Dusk\Browser  $browser
     * @param  string  $name
     * @return void
     */
    public function login(Browser $browser)
    {
        $browser->loginAs(User::where('email', '[email protected]')->firstOrFail);
    }
}

and then in EmployeesTest.php:


<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\Browser\Pages\LoginPage;

class EmployeesTest extends DuskTestCase
{
    /**
     * Verify if the employees list is showing
     *
     * @return void
     */
    public function testEmployeeListIsShowing()
    {
        $this->browse(function ($browser) {
            $browser->on(new LoginPage)
                    ->login()
                    ->visit('/employees/list')
                    ->waitFor('#employees-datalist');
        });
    }

    /**
     * Open the Create employee form
     * 
     * @return void
     */
    public function testOpenCreateEmployeeForm()
    {
        $this->browse(function($browser) {
            $browser->on(new LoginPage)
                    ->login()
                    ->visit('/employees/list')
                    ->waitFor('#employees-create-btn');
        });
    }
}

Checkout https://laravel.com/docs/5.5/dusk#page-methods

neter's avatar

@aaronranard @ddutra Hello, I am new to PHP and laravel dusk.

$this->browse(function ($browser) { $browser->on(new LoginPage) ->login()

My question when we create an object of page class. I am not able to access the methods of that class like they are not prepopulated or shown as a suggested method of the page class in the next step like the way you are accessing the login() method of page class. Thanks

Please or to participate in this conversation.