Home » Php » selenium – Php webdriver – how to force new test to use different profile?

selenium – Php webdriver – how to force new test to use different profile?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’m running multiple tests across a Selenium grid containing a multiple nodes, using a dynamically created Firefox profile, like this:

$firefoxProfile = new FirefoxProfile();
$capabilities = DesiredCapabilities::firefox ();
$capabilities->setCapability(FirefoxDriver::PROFILE, $firefoxProfile);

$this->webdriver = RemoteWebDriver::create("http://my.tests.com", $capabilities, 5000);

But every time the hub picks up a node with a previous running Firefox instance it uses the same profile and drops the previously running session. It happens because the application uses the same cookies for authentication purposes.

Is there some way to force selenium grid to create a new profile on the fly and get a totally new firefox instance?

Some further information

For getting the hub started I currently use the following command line

    java -jar /opt/selenium/selenium-server.jar -trustAllSSLCertificates -timeout  300 \
                                        -role hub -newSessionWaitTimeout 60 -maxSession 2 \
                                        -port 9444 -nodeTimeout 300 \
                                        -browserTimeout 300 &

And to get nodes started I use

    xvfb-run -n 99 --server-args="-screen 0 800x600x16 -ac"  \
      -a java -jar /opt/selenium/selenium-server.jar -role node \
                 -browser browserName=firefox,maxInstances=2 \
                 -hub http://my.tests.com:9444/grid/register 

The weird thing is that when I set up a standalone Selenium server it creates multiple firefox instances as I would like to be…

How to&Answers:

You could also try an alternative lightweight Selenium replacement called Selenoid. The main difference is that it starts every browser in new Docker container. This guarantees that your sessions are completely isolated.

Answer:

I’m running multiple tests across a Selenium grid containing a
multiple nodes, using a dynamically created Firefox profile, like this

Do you protect your variables? It’s like you reused some class instance.
spl_object_hash() could help you out here. It

returns a unique identifier for the object

which is always the same for a given instance.

PS:

Try to separate them & use unittests /use the fixtures available in PHPUnit/:

class BaseTestCase extends PHPUnit_Framework_TestCase
{
    static $driver;
    private $capabilities;
    public function setCapabilities($capabilities)
    {
        $this->capabilities = $capabilities;
    }
    public static function setUpBeforeClass()
    {

        $host = 'http://my.tests.com';

        self::$driver = RemoteWebDriver::create($host, $this->capabilities, 5000);
    }

    public static function tearDownAfterClass()
    {

        self::$driver->close();
    }

    public function getDriver()
    {
        return self::$driver;
    }
}

class FirefoxTest extends BaseTestCase
{

    public function setUp()
    {
        $firefoxProfile = new FirefoxProfile();
        $capabilities = DesiredCapabilities::firefox ();
        $capabilities->setCapability(FirefoxDriver::PROFILE, $firefoxProfile);
        self->setCapabilities($capabilities);
        $this->getDriver()->get("http://my.tests.com/x");
    }

    public function testTitle()
    {

        echo $this->getDriver()->getTitle();
    }

    public function testSomethingElse()
    {
        // do test
    }
}

This example won’t share the same $driver between both FirefoxTest and XXXTest but that is recommended as you will want a clean slate for each test.

However all the tests in FirefoxTest will share the same driver.
The execution order of tests, when you do ‘phpunit tests’ will be:
setUpBeforeClass()

setUp()
testTitle()

setUp()
testSomethingElse()

tearDownAfterClass() 

a bit more about fixtures