Search code examples
laravelautomated-testsbrowserstacklaravel-duskbrowser-testing

Laravel dusk with browserstack to run tests on multiple devices and browsers


I am using this ("browserstack/browserstack-local": "^1.1") package to run dusk tests on BrowserStack. Now the requirement is to run tests on multiple and different devices with different browsers. Currently, I am following this approach to run tests.

private function browserStackCaps($local_identifier)
{
    return [
        'project' => config('app.name'),
        'browserstack.local' => 'true',
        'browser' => env('BROWSER'),
        'device' => env('DEVICE'),
        'acceptSslCert' => true,
        'resolution' => '1920x1080'
    ];
}

The drawback of this approach is I have to change the device name and browser name in the .env file every time I need to run tests on a different device/browser. Is there any way I can run tests on the provided array? The array that contains devices and browser information.


Solution

  • I know this is old, but I found this page while searching for a solution. I ended up building one myself that would probably meet your use-case. The biggest hurdle that I had was $this->browse() in a normal Dusk test was using a single instance of Laravel\Dusk\Browser and the new capabilities were not being pulled in. This implementation adds a function called performTest to the DuskTestCase.php file. This function loops through a set of capabilities and instantiates a new instance of Laravel\Dusk\Browser for each test. This function works similarly to the existing browse function in Laravel Dusk. You call performTest by passing it a callable that accepts a single parameter which is an instance of Laravel\Dusk\Browser

    Dusk Test Case

    <?php
    
    namespace Tests;
    
    use Laravel\Dusk\TestCase as BaseTestCase;
    use Facebook\WebDriver\Remote\RemoteWebDriver;
    use Facebook\WebDriver\Remote\DesiredCapabilities;
    
    abstract class DuskTestCase extends BaseTestCase
    {
        use CreatesApplication;
        protected array $capabilities;
    
        private const BROWSERS = [
            'ios_14_iphone_xs_safari' => [
                "os_version" => "14",
                "device" => "iPhone XS",
                "real_mobile" => "true",
                "browserstack.local" => "true",
                'acceptSslCerts' => 'true'                
            ],
            'mac_osx_catalina_safari' => [
                "os" => "OS X",
                "os_version" => "Catalina",
                "browser" => "Safari",
                "browser_version" => "13.0",
                "browserstack.local" => "true",
                "browserstack.selenium_version" => "3.14.0",
                "resolution" => "1920x1080",
                'acceptSslCerts' => 'true',
            ]
        ];
    
    
    
        /**
         * Create the RemoteWebDriver instance.
         *
         * @return \Facebook\WebDriver\Remote\RemoteWebDriver
         */
        protected function driver()
        {
            $browserStackConnectionUrl = config('browserstack.connection_url');
            return RemoteWebDriver::create(
                $browserStackConnectionUrl, $this->capabilities
            );
        }
    
        protected function performTest(Callable $test){
            foreach(self::BROWSERS as $browserName => $capabilitySet){
                try {
                    $this->capabilities = $capabilitySet;
                    $browser = $this->newBrowser($this->driver());
                    $test($browser);
                    $browser->quit();
                    fprintf(STDOUT, "\e[0;32m√ {$browserName}\r\n");
                }
                catch(\Exception $exception){
                    fprintf(STDOUT, "\e[0;31mX {$browserName}\r\n");
                    throw $exception;
                }
            }
        }
    
    
    }
    

    Example Test

    <?php
    
    namespace Tests\Browser;
    
    use Tests\DuskTestCase;
    use Laravel\Dusk\Browser;
    
    class ExampleTest extends DuskTestCase
    {
        public function testExample()
        {
            $this->performTest(function(Browser $browser){
                $browser->visit('/')
                    ->assertDontSee('Foobar');
            });
        }
    }
    

    config/browserstack.php

    <?php
    
    return [
        'connection_url' => env('BROWSERSTACK_CONNECTION_URL')
    ];