Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel Dusk, how to destroy session data between tests

I am getting started using Laravel Dusk for browser testing, and have created a couple of tests to test my login form. I have the following code:

class LoginTest extends DuskTestCase
{

public function testLogin()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/admin')
            ->type('email', '[email protected]')
            ->type('password', 'MyPass')
            ->press('Login')
            ->assertSee('Loading...');
    });
}

public function testLoginFailure(){
    $this->browse(function (Browser $browser){

        $browser->visit('/admin/logout'); // I have to add this to logout first, otherwise it's already logged in for this test!

        $browser->visit('/admin')
            ->type('email', '[email protected]')
            ->type('password', 'somefakepasswordthatdoesntwork')
            ->press('Login')
            ->assertSee('These credentials do not match our records.');
    });
}

See the comment. The first function runs fine, but when it comes to the second function, I have to logout first, since the user is already logged in as a result of running the first function. This came as a surprise to me as I thought unit tests were completely independent, with session data being destroyed automatically.

Is there a better way of doing this- some Dusk method that I'm missing perhaps- than having to call $browser->visit('/admin/logout'); ?

Thanks

EDIT Thanks for the 2 answers so far, which both seem valid solutions. I've updated the second function to the following:

public function testLoginFailure(){
    $this->createBrowsersFor(function(Browser $browser){
        $browser->visit('/admin')
            ->type('email', '[email protected]')
            ->type('password', 'somefakepasswordthatdoesntwork')
            ->press('Login')
            ->assertSee('These credentials do not match our records.');
    });
}

Which does the job. So

  1. I can safely assume that this second browser only exists for the duration of this single function, correct?
  2. What are the obvious advantages/disadvantages of creating a second browser instance rather than using the teardown method?
like image 775
Inigo Avatar asked Jul 04 '17 13:07

Inigo


3 Answers

In my case, tearDown() was not enough, for some reason, a logged users was still persisted between tests, so I placed deleteAllCookies() at setUp().

So, in my DuskTestCase.php I added:

/**
 * Temporal solution for cleaning up session
 */
protected function setUp()
{
    parent::setUp();
    foreach (static::$browsers as $browser) {
        $browser->driver->manage()->deleteAllCookies();
    }
}

It was the only way I could flush up session around all tests. I hope it helps.

Note: I'm using Homestead and Windows 10.

like image 68
Zalo Avatar answered Nov 07 '22 17:11

Zalo


If you just want to logout your signed in user, after login test, simply use:

 $browser->visit('/login')
     ->loginAs(\App\User::find(1))
     ...
     some assertions
     ...
     ->logout();
like image 24
branci Avatar answered Nov 07 '22 16:11

branci


You could flush the session in a tearDown() method:

class LoginTest extends DuskTestCase
{
    // Your tests

    public function tearDown()
    {
        session()->flush();

        parent::tearDown();
    }
}
like image 25
Martin Bean Avatar answered Nov 07 '22 18:11

Martin Bean