Dusk test not working as expected

Published 2 months ago by rajcoder

I am using dusk for testing and have encountered a problem.

I have 2 test functions in ExampleTest file.

In the first test, I am creating a factory user and logging him through login form and asserting that user should see home. This works.

But the second test, where I again visit login page and enter wrong credentials, fails as I guess it somehow maintains the session for the user and thus going to /login redirects back to /home.

What is the problem? How can I remove the logged in user after method gets over ?

shez1983

code please? you could also manually LOGOUT after each test (create a teardown() function that runs after each test to make sure you log out)

rajcoder

@shez1983 Thanks for mentioning the tearDown() method. But it does not seem right to logout a user as there may be cases where I am testing that on wrong credentials assertPathIs('/login') and then the tearDown() method tries to find logout link eg. clickLink('logout') and since I am at the login page itself there might be an error.

So can you suggest me what code should I have in my tearDown() method to destroy the current session of the user ?

Or somehow each test method runs as if it is a separate test

shez1983

like i said if you show the code of your tests then maybe we can find the real problem instead of trying to come up with a band-aid..

impbob

A good test should be as isolated as possible

  1. Create the world and verifiy state
  2. Do something
  3. Verify state is different (or unchanged)

So ... check is guest, attempt to login, verify user is authenticated

    public function check_guests_can_log()
    {
        $this->browse(function (Browser $browser) {
            $user = factory(\App\User::class)->create();

            $browser->assertGuest()
                ->visit('logon')
                // Attempt to login. Eg.
                // ->type('name', 'dave')
                // ->type('password', 'lister')
                // ->click('login')
                ->assertAuthenticatedAs($user);
        });
    }

And ... check is guest, attempt to login, verify still guest

    public function check_guests_can_not_login_with_invalid_credentials()
    {
        $this->browse(function (Browser $browser) {
            $user = factory(\App\User::class)->create();

            $browser->assertGuest()
                ->visit('logon')
                // Attempt to login. Eg.
                // ->type('name', 'dave')
                // ->type('password', 'rimmer')
                // ->click('login')
                ->assertGuest();
        });
    }

If you don't verify the first state, how can you be sure your actions changed the state?

Dusk has a range of authentication asserts here: https://laravel.com/docs/5.6/http-tests#authentication-assertions

jamienathaniel

At the end of the first test where you have successfully logged in you need to chain on ->logout() at the very end (within the browser).

That will fix your issue for the second test.

Please sign in or create an account to participate in this conversation.