How to test Facebook login with Laravel Dusk

Published on Jul 4, 2022

If we have authentication on our website, then the login tests are one of the most important tests. We need to validate that the users can signup and login. I had to test socialite the Facebook login, and it wasn't easy with Laravel Dusk. Here I share a solution that can help you out in this case:

    public function testGuestCanFacebookLogin()
    {
        $driver = [];
        $this->browse(function (Browser $browser) use (&$driver) {
            $browser->visit('/login')
                ->waitFor('@button-facebook-login')
                ->press('@button-facebook-login');
            $driver = $browser->driver;
            return $driver;
        });

        $getTabs = $driver->getWindowHandles();
        $driver->switchTo()->window($getTabs[1]);

        $this->browse(function (Browser $browser) {
            $browser->waitFor('button[data-testid=cookie-policy-manage-dialog-accept-button]')
                ->assertPresent('button[data-testid=cookie-policy-manage-dialog-accept-button]')
                ->click('button[data-testid=cookie-policy-manage-dialog-accept-button]')
                ->type('input#email', getenv('FACEBOOK_TEST_LOGIN_EMAIL'))
                ->type('input#pass', getenv('FACEBOOK_TEST_LOGIN_PASSWORD'))
                ->click('#loginbutton')
                ->assertUrlIs('https://www.facebook.com/login.php');
        });

        $driver->switchTo()->window($getTabs[0]);

        $this->browse(function (Browser $browser) {
            $browser->waitFor('welcome')
                ->assertFragmentIs('/user');
        });
    }

Okay! It looks fine but let's discuss the details. I prefer to create dusk-related attributes on DOM elements because the code part looks nicer and it is more professional.

In the first section, we need to add one empty array $driver which will help us to store the browser's data. As you might know, for Facebook login if we click on the login button a new window will open so we need to know which one we are at.

$driver = [];
$this->browse(function (Browser $browser) use (&$driver) {
    $browser->visit('/login')
        ->waitFor('@button-facebook-login')
        ->press('@button-facebook-login');
    $driver = $browser->driver;
    return $driver;
});

The second part helps us to switch to Facebook's window because we are still on the first window tab, so we need to switch to the second one.

$getTabs = $driver->getWindowHandles();
$driver->switchTo()->window($getTabs[1]);

In the third part, we are now on Facebook's login page. One good thing is here if we check facebook's source code it has test-related attributes, so it looks like they also use browser tests for their login tests. In the source code, we will find the button[data-testid=cookie-policy-manage-dialog-accept-button] attribute to accept the cookies. After that, we can enter the email and the password and press the login button. (You can use your own Facebook credential, but I suggest you make test accounts for testing).

$this->browse(function (Browser $browser) {
    $browser->waitFor('button[data-testid=cookie-policy-manage-dialog-accept-button]')
        ->assertPresent('button[data-testid=cookie-policy-manage-dialog-accept-button]')
        ->click('button[data-testid=cookie-policy-manage-dialog-accept-button]')
        ->type('input#email', getenv('FACEBOOK_TEST_LOGIN_EMAIL'))
        ->type('input#pass', getenv('FACEBOOK_TEST_LOGIN_PASSWORD'))
        ->click('#loginbutton')
        ->assertUrlIs('https://www.facebook.com/login.php');
});

Forth part, after we logged in to Facebook, we need to switch back to the first window.

$driver->switchTo()->window($getTabs[0]);

Lastly, we are logged in to our application so we can see the logged-in user interface or whatever our site looks like.

$this->browse(function (Browser $browser) {
      $browser->waitFor('welcome')
          ->assertFragmentIs('/user');
});

Thanks for reading, I hope it was helpful. :)