6

I've just used Laravel Dusk to test a javascript site.

Want to reuse the current browser with its session and cookies for some reason (keep me logged in on the site), so I don't need to pass auth process.

Any way to reuse the current browser?

I've already searched about this, but I found no practical info/example. Note: I use Dusk by default with Google Chrome and a standalone ChromeDriver (not Selenium)

Arie Pratama
  • 95
  • 2
  • 7
  • 1
    Dusk already reuses the browser within a test class and keeps you logged in. Do you want to reuse it over multiple classes? – Jonas Staudenmeir Jun 30 '18 at 12:23
  • Yes, reusing over multiple classes is what I mean, actually when running laravel dusk by command (php artisan dusk --filter=TestClass). When I firstly run a test by command, it needs to auth. When I run another test, is there a way to use session and cookies from the first test? Thanks for replying btw – Arie Pratama Jun 30 '18 at 17:10
  • I think the best approach would be using `tearDownAfterClass()` and `setUpBeforeClass()` to save the cookies and restore them on the next call. – Jonas Staudenmeir Jun 30 '18 at 17:16
  • I found the ways to get cookies and set cookies on facebook/php-webdriver that uses by Laravel Dusk. I'll try collaborating them with tearDownAfterClass() and setUpBeforeClass() – Arie Pratama Jun 30 '18 at 17:33
  • @AriePratama Did you get this fixed? I have a similar requirement. – Anthony Nov 05 '18 at 22:36

2 Answers2

8

I had the same requirement using Laravel Dusk. The trick is to use the Facebook/WebDriver/Remote/RemoteWebDriver class and its manage() method.

Pseudo code:

use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Cookie;
use Facebook\WebDriver\WebDriverOptions;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Chrome\ChromeProcess;

//the cookie file name
$cookie_file = 'cookies.txt';

//create the driver
$process = (new ChromeProcess)->toProcess();
$process->start();
$options = (new ChromeOptions)->addArguments(['--disable-gpu','--enable-file-cookies','--no-sandbox']);
$capabilities = DesiredCapabilities::chrome()->setCapability(ChromeOptions::CAPABILITY, $options);
$driver = retry(5, function () use($capabilities) {
    return RemoteWebDriver::create('http://localhost:9515', $capabilities);
}, 50); 

//start the browser
$browser = new Browser($driver);
$browser->visit('https://tehwebsite.com/login');

//Cookie management - if there's a stored cookie file, load the contents         
if (file_exists($cookie_file)) {
    //Get cookies from storage
    $cookies = unserialize(file_get_contents($cookie_file));
    //Add each cookie to this session
    foreach ($cookies as $key => $cookie) {
        $driver->manage()->addCookie($cookie);
    }
}

//if no cookies in storage, do the browser tasks that will create them, eg by logging in 
$browser
    ->type('email', 'login@email.com')
    ->type('password', 'sdfsdfsdf')
    ->check('rememberMe')
    ->click('#login');

//now the cookies have been set, get and store them for future runs
if (!file_exists($cookie_file)) {
    $cookies = $driver->manage()->getCookies();
    file_put_contents($cookie_file, serialize($cookies));
}
Anthony
  • 435
  • 5
  • 8
  • You saved my life :) , thank you so much. I was failing with session usage like : RemoteWebDriver::createBySessionId('http://localhost:9515', $capabilities); ... Do you have any idea how this works. Why cant I reuse session in that way completely. – Erdinç Çorbacı Feb 08 '20 at 03:35
3

When you use laravel dusk, i found a way to setcookie to the brower:

Use the visits twice when use planCookie function like below code:


$this->browse(function (Browser $browser) {
    $url = 'https://google.com';
    $browser->visit($url);
    $browser->plainCookie('key', 'value');
    $browser->visit($url);
    $browser->assertSee('Some Text');
});

Hope this helpful.

Avenger
  • 51
  • 3