Laravel Dusk how to destroy session data between tests

I am starting to use Laravel Dusk for browser testing and created a couple of tests to validate my registration form. I have the following code:

class LoginTest extends DuskTestCase
{

public function testLogin()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/admin')
            ->type('email', 'inigo@mydomain.co.uk')
            ->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 already logged in for this test!

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

      

See comment. The first function works fine, but when it comes to the second function I have to log out 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 the unit tests were completely independent and the session data was automatically destroyed.

Is there a better way to do this - some kind of Dusk method that I am missing, perhaps than a call $browser->visit('/admin/logout');

?

thank

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

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

      

What job. So

  • It's safe to assume that this second browser only exists for the duration of this single function, right?
  • What are the obvious advantages / disadvantages of creating a second browser instance rather than using the teardown method?
+9


source to share


7 replies


In my case tearDown()

it was not enough, for some reason logged in users were still persisted between tests, so I put deleteAllCookies()

in 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();
    }
}

      



This was the only way I could do a session around all tests. Hope this helps.

Note. I am using Homestead and Windows 10.

+8


source


You can clear your session with the method tearDown()

:



class LoginTest extends DuskTestCase
{
    // Your tests

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

        parent::tearDown();
    }
}

      

+4


source


If you just want to log out of your signed-in user, after the login test, just use:

 $browser->visit('/login')
     ->loginAs(\App\User::find(1))
     ...
     some assertions
     ...
     ->logout();

      

+4


source


You may call

$this->logout();

      

InteractsWithAuthentication - Github

Edit:

This is the behavior of the Dusk Test, the main browser instance remains for other tests.

Second solution, create a second browser instance which will be destroyed after one test

See Dusk / TestCase # L103

+3


source


If it helps someone else. You can use the method tearDown

to clear all cookies. Below is an example of this, you can add this method to DuskTestCase.php file

public function tearDown()
{
    parent::tearDown();

    $this->browse(function (Browser $browser) {
        $browser->driver->manage()->deleteAllCookies();
    });
}

      

Hope this helps.

+2


source


I'm not sure if your answer is right for you, but you can create multiple browsers to run a test that requires clean history / cookies / cache.

For example, if you have a lot of tests where the user has to log in, and you don't want to log out for just one test that validates the reset password form, then you can create an additional browser for that exact one and switch to the previous browser when navigating to the next tests.

It might look like this:

public function testfirstTest()
{
  $this->browse(function ($browser) {
    //some actions where you login etc
  });
}

public function testSecondTestWhereYouNeedToBeLoggedOut()
{
  $this->browse(function ($currentBrowser, $newBrowser) {
  //here the new browser will be created, at the same time your previous browser window won't be closed, but history/cookies/cache will be empty for the newly created browser window
    $newBrowser->visit('/admin')
    //do some actions
    $newBrowser->quit();//here you close this window
  });
}

public function testWhereYouShouldContinueWorkingWithUserLoggedIn()
{
  $this->browse(function ($browser) {
    $browser->doSomething()//here all actions will be performed in the initially opened browser with user logged in
  });
}

      

+1


source


Please take a look at this link. I have explained this in detail.

https://github.com/laravel/dusk/issues/110#issuecomment-486626469

0


source







All Articles