Summer Sale! All accounts are 50% off this week.

MxFlix's avatar

Dusk: Two tests not working together, but individually.

I have a Dusk test file with the following content:

<?php

namespace Tests\Browser;

use Illuminate\Support\Facades\Auth;
use Tests\Browser\Pages\Login;
use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;


class UserTest extends DuskTestCase
{

    use DatabaseMigrations;


    //<editor-fold desc="Login">

    /** @test */
    public function a_registered_user_can_log_in()
    {
        factory('App\User')->create(['username' => 'John']);

        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                    ->type('username', 'John')
                    ->type('password', 'secret')
                    ->click('#submit')->assertPathIs('/home');
        });
    }

    /** @test */
    function a_wrong_username_or_password_is_gives_a_human_readable_error_message()
    {
        factory('App\User')->create(['username' => 'RealName']);

        $this->browse(function (Browser $browser) {
            $browser->visit('/login')
                    ->type('username', 'WrongName')
                    ->type('password', 'secret')
                    ->click('#submit')
                    ->assertSee('These credentials do not match our records.');
        });
    }
    //</editor-fold>
}

When I run the tests individually (using --filter), they run perfectly fine. But if I run them all together, the second test fails to find the requested elements (NoSuchElementsException). It also doesn't help when I create a Page class for the Login Page and define the elements there.

The whole thing does work if I call php artisan dusk --process-isolation, but of course that takes much longer, as all tests are executed one after the other. It also works when I put the tests in different files, but that also executes them one after the other, and it doesn't feel all that good from a coding standpoint to have only one test per file.

Does anyone of you know how I can run the tests simultaneously and have them complete properly?

0 likes
4 replies
Bartestro's avatar

If it is still your problem you can try to add ->waitFor(element) maybe page is not rendered properly yet. You can verify this by checking screenshots for example... Hope this helps...

reado's avatar

Hey,

I'm not sure if this is the correct answer but I was running into the same problem. My guess was that since you're doing the successful use case first (like I was), maybe the user is authenticated into the browser session and when the browser tries to go to '/login' on the second test it will automatically redirect the user back to 'home' since they're already authenticated.

In theory you can create a test that will automatically redirect to 'home' if they're already authenticated.

Other thing that worked for me was to also include something like

        $this->browse(function (Browser $browser) {
            $browser->visit(new LoginPage)
                ->loginUser($this->user)
                ->assertPathIs('/home')
                ->logout();
        });

its a little janky because you're forcing the user to log out but at least the tests can pass without having to worry about their processing order

1 like
lindstrom's avatar

Just getting into Dusk myself and had this problem. Logging out didn't work for me, because I was setting remember to true. I ended up having to delete the session cookie in each of my tests.

    $this->browse( function(Browser $browser) {
        $browser->visit(route('login')
            ->type('username', 'someusername')
            -> type('password', 'somepassword')
            ->click('@login-button')
            ->assertPathIs('/account')
            ->deleteCookie('app_session_cookie');
    });

Alternatively, and I haven't tried this, you may be able to uncheck remember and also call logout after your path assertion.

Just in case anyone finding this is unsure/new -- the session cookie is defined in config/session.php and either uses the APP_NAME concatenated with _session (e.g. you_app_name_session) or the default (laravel_session).

Please or to participate in this conversation.