38
Handling Multiple Browser Windows And Tabs In Selenium PHP
One of the common scenarios in a web application (or a web app) is opening up a new browser window (or tab) once the user performs a specific activity. Many web developers use the HTML tag ‘__blank’ that informs the browser to open a new window (or tab, depending on the user’s set preference) when a link is clicked. Handling Windows in Selenium with PHP can be used for automating interactions with browser windows, tabs, and even pop-up windows.

Pop-up windows can ‘sometimes’ be annoying for the website visitors, but sometimes, you have no other choice than to use the same. How does Selenium differentiate between different windows or tabs? How can automation be used to switch between different browser windows or tabs seamlessly? How do you manage window handling in Selenium?
In this blog, we deep dive into Selenium test automation usage for automating interactions with browsers, tabs, and pop-ups. We use the PHPUnit, the unit-testing framework for PHP, for demonstrating window handling in Selenium PHP.
The Window Handle is a unique identifier whose primary responsibility is to hold all the windows’ address. When the Selenium WebDriver instance is instantiated, an alpha-numeric ID is assigned to the Window. The unique ID is called Window Handle, a pointer to the Window and helps identify the browser window.
Whether it is a new window/tab/pop-up, the Window Handle (or ID) is unique for each one of them. The Selenium WebDriver uses the Window Handle functions in Selenium PHP for switching between different windows (or tabs).
As far as the Window Handle’s retention is concerned, the unique ID is retained till the closure of the Selenium WebDriver session (i.e. either via WebDriver.Quit or WebDriver.Close APIs). The Window Handle functions are used for getting details of the handles of all the windows. The fundamentals of window handling in Selenium remain the same, irrespective of whether you are handling windows in Selenium with PHP or using Selenium with other programming languages (e.g. Python, Java, etc.).
Here are some of the common scenarios where you would encounter multiple windows (or tabs):

Shown above is a sample scenario where a click operation in the parent (or base) window opens up two ‘child windows’. Each of these has unique window handles, and the handle is retained till the windows are not destroyed (i.e. closed). With this, the total number of windows becomes three (parent + child-1 + child-2).
Click on a button/link in ‘Child-1’, and ‘Child-2’ opens ‘Grand Child-1’ and ‘Grand Child-2’ respectively. With this, the total number of windows are five, and each of them has unique Window handles that can be used to automate operations on them.
Selenium provides different methods for handling multiple windows. You can also refer to our guide to handle multiple windows with Selenium & Protractor. Here are some of the widely used commands in Selenium PHP for switching browser windows and handling pop-up windows:
The SwitchTo command is used for switching the focus to a new browser window or tab. For changing the focus to a new window, the Window Handle of the desired browser window is passed as an argument to the command.
/* $wHandle is the Window Handle (or ID) of the Window to which the switch has to be performed */
$this->webDriver->switchTo()->window($wHandle);
/* Switch can also be done by obtaining the number of windows using getWindowHandles or getWindowHandle */
$this->webDriver->switchTo()->window($HandleCount[win-number]);
The getWindowHandle method in Selenium PHP returns the Window ID (which is a unique alpha-numeric identifier for the window) of the currently active (or focused) window.
$wHandle = $this->webDriver->getWindowHandle();
In the example shown above, $wHandle is the ID of the window obtained using the getWindowHandle method.
This is an important method for handling windows in Selenium with PHP. The getWindowHandles method returns a set of window (and tab) handles opened by the same driver instance, including the parent and child windows. For example, if a click operation on a button in the parent window opens up a new tab; the getWindowHandles method will return the handles of the parent window and child window (i.e. tab). The sizeof operator when applied on the set returned by getWindowHandles returns the size of the set i.e. 2 in this case.
On a similar line, if a web page opened in the parent window opens up 8 pop-up windows; the Handle Count obtained by applying sizeof operator on the set returned by getWindowHandles method is 9.
Each of the windows will have a unique Window Handle (or Identifier) for easy identification of the window.
/* For a web page that opens a new tab, getWindowHandles returns an array of comprising of 2 window handles (i.e. handle of parent and child window) */
$HandleCount = $this->webDriver->getWindowHandles();
/* Returns the size of the Window Handle array. In the current example, it will be 2 */
echo ("\n Total number of window handles are " . sizeof($HandleCount));
/* Print the Window Handle of the Parent Window */
echo ("\n Window 0: " . $HandleCount[0]);
/* Print the Window Handle of the Child Window */
echo ("\n Window 0: " . $HandleCount[1]);
We demonstrate the test scenarios for window handling in Selenium PHP using PHPUnit on LambdaTest’s cloud-based Selenium Grid. Cross browser testing using PHPUnit on a cloud-based Selenium Grid helps in testing across different combinations of browsers, platforms, and device emulators.
To get started, we create an account on LambdaTest and note the user-name & access-key available on the profile page. The tests are performed on (Chrome 85.0 + Windows 10) combination. The browser capabilities are generated using the LambdaTest capabilities generator.

For installing the PHPUnit framework, we create a composer.json file for the project:
{
"require":{
"php":">=7.1",
"phpunit/phpunit":"^9",
"phpunit/phpunit-selenium": "*",
"php-webdriver/webdriver":"1.8.0",
"symfony/symfony":"4.4",
"brianium/paratest": "dev-master"
}
}
Run the command composer require, press ‘Enter’ button twice to proceed with the installation of the PHPUnit framework. On completion, PHPUnit framework (version 9.3) is installed.
The file composer.lock contains information of the dependencies and the vendor folder has all the dependencies.


The file vendor\autoload.php will be used in the test code so that classes (and its methods) provided by those libraries can be used in the implementation. Now it’s time to demonstrate the various scenarios for handling Windows in Selenium With PHP.
For demonstrating multiple window handling in Selenium PHP, we use the following test scenario:
Implementation
<?php
require 'vendor/autoload.php';
use PHPUnit\Framework\TestCase;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
$GLOBALS['LT_USERNAME'] = "user-name";
# accessKey: AccessKey can be generated from automation dashboard or profile section
$GLOBALS['LT_APPKEY'] = "access-key";
class WindowSwitchTest extends TestCase
{
protected $webDriver;
public function build_browser_capabilities(){
/* $capabilities = DesiredCapabilities::chrome(); */
$capabilities = array(
"build" => "[PHP] Window Switching with Chrome on Windows 10",
"name" => "[PHP] Window Switching with Chrome on Windows 10",
"platform" => "Windows 10",
"browserName" => "Chrome",
"version" => "85.0"
);
return $capabilities;
}
public function setUp(): void
{
$url = "https://". $GLOBALS['LT_USERNAME'] .":" . $GLOBALS['LT_APPKEY'] ."@hub.lambdatest.com/wd/hub";
$capabilities = $this->build_browser_capabilities();
/* Download the Selenium Server 3.141.59 from
https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar
*/
/* $this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities); */
$this->webDriver = RemoteWebDriver::create($url, $capabilities);
}
public function tearDown(): void
{
$this->webDriver->quit();
}
/*
* @test
*/
public function test_SwitchToNewWindow()
{
$test_url_1 = "https://www.lambdatest.com";
$title_1 = "Most Powerful Cross Browser Testing Tool Online | LambdaTest";
$test_url_2 = "https://www.lambdatest.com/blog/";
$title_2 = "LambdaTest | A Cross Browser Testing Blog";
$this->webDriver->get($test_url_1);
$this->webDriver->manage()->window()->maximize();
$wHandle = $this->webDriver->getWindowHandle();
/* echo ("\n Primary Window Handle is " . $wHandle ); */
sleep(5);
/* Open the second window */
/* $link = "window.open('https://www.lambdatest.com/blog/', '_blank', 'toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800')"; */
$link = "window.open('". $test_url_2 ."', '_blank', 'toolbar=yes,scrollbars=yes,resizable=yes,width=1200,height=1200')";
$this->webDriver->executeScript($link);
/* $this->webDriver->manage()->window()->maximize(); */
/* The focus is now on the second window */
/* The Handle count will be two */
$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));
echo ("\n Window 0: " . $HandleCount[0]);
echo ("\n Window 1: " . $HandleCount[1]);
sleep(10);
/* Assert if the Window Count is not 2 */
$this->assertEquals(2, sizeof($HandleCount));
/* Check if the Window titles match */
$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
echo ("\n Title of the window 1 is " . $win_title_2);
sleep(10);
$this->assertEquals($win_title_2, $title_2);
/* Close the newly opened Window and return to the old window */
$this->webDriver->close();
sleep(10);
/* Return to the window with handle = 0 */
$this->webDriver->switchTo()->window($wHandle);
/* Check if the Window titles match */
$win_title_1 = $this->webDriver->getTitle();
echo ("\n Title of the window 0 is " . $win_title_1);
$this->assertEquals($win_title_1, $title_1);
sleep(10);
}
}
?>
Code Walkthrough
$GLOBALS['LT_USERNAME'] = "user-name";
# accessKey: AccessKey can be generated from automation dashboard or profile section
$GLOBALS['LT_APPKEY'] = "access-key";
$capabilities = array(
"build" => "[PHP] Window Switching with Chrome on Windows 10",
"name" => "[PHP] Window Switching with Chrome on Windows 10",
"platform" => "Windows 10",
"browserName" => "Chrome",
"version" => "85.0"
);
$url = "https://". $GLOBALS['LT_USERNAME'] .":" . $GLOBALS['LT_APPKEY'] ."@hub.lambdatest.com/wd/hub";
$capabilities = $this->build_browser_capabilities();
$this->webDriver = RemoteWebDriver::create($url, $capabilities);
public function test_SwitchToNewWindow()
{
$test_url_1 = "https://www.lambdatest.com";
$title_1 = "Most Powerful Cross Browser Testing Tool Online | LambdaTest";
...............................................
...............................................
$this->webDriver->get($test_url_1);
$wHandle = $this->webDriver->getWindowHandle();
...............................................
}
The executeScript method offered by JavaScriptExecutor in Selenium PHP is used for executing the newly formed JavaScript code in the context of the currently opened window.
$link = "window.open('". $test_url_2 ."', '_blank', 'toolbar=yes,scrollbars=yes,resizable=yes,width=1200,height=1200')";
$this->webDriver->executeScript($link);
$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));
$this->assertEquals(2, sizeof($HandleCount));
$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
$this->assertEquals($win_title_2, $title_2);
$this->webDriver->close();
Raise an assert if the window title does not match with the expected one.
$test_url_1 = "https://www.lambdatest.com";
$title_1 = "Most Powerful Cross Browser Testing Tool Online | LambdaTest";
...........................................
$this->webDriver->get($test_url_1);
...........................................
...........................................
$wHandle = $this->webDriver->getWindowHandle();
/* Return to the window with handle = 0 */
$this->webDriver->switchTo()->window($wHandle);
/* Check if the Window titles match */
$win_title_1 = $this->webDriver->getTitle();
$this->assertEquals($win_title_1, $title_1);
public function tearDown(): void
{
$this->webDriver->quit();
}
Execution
A similar approach is used for switching the context to the parent window on the child window’s closure.

Here is the execution snapshot where the PHPUnit framework was triggered for running the tests:

I hope this gives you a fairly good idea of handling windows in Selenium with PHP. Next up, we learn about handling multiple browser tabs in Selenium PHP.
For demonstrating handling of multiple browser tabs in Selenium PHP, we use the following test scenario:
Implementation
<?php
require 'vendor/autoload.php';
use PHPUnit\Framework\TestCase;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$GLOBALS['LT_USERNAME'] = "user-name";
# accessKey: AccessKey can be generated from automation dashboard or profile section
$GLOBALS['LT_APPKEY'] = "access-key";
class TabSwitchTest extends TestCase
{
protected $webDriver;
public function build_browser_capabilities(){
/* $capabilities = DesiredCapabilities::chrome(); */
$capabilities = array(
"build" => "[PHP] Tab Switching with Chrome on Windows 10",
"name" => "[PHP] Tab Switching with Chrome on Windows 10",
"platform" => "Windows 10",
"browserName" => "Chrome",
"version" => "85.0"
);
return $capabilities;
}
public function setUp(): void
{
$url = "https://". $GLOBALS['LT_USERNAME'] .":" . $GLOBALS['LT_APPKEY'] ."@hub.lambdatest.com/wd/hub";
$capabilities = $this->build_browser_capabilities();
/* Download the Selenium Server 3.141.59 from
https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar
*/
/* $this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities); */
$this->webDriver = RemoteWebDriver::create($url, $capabilities);
}
public function tearDown(): void
{
$this->webDriver->quit();
}
/*
* @test
*/
public function test_SwitchToNewTab()
{
$test_url = "http://automationpractice.com/index.php";
$title_1 = "My Store";
$title_2 = "Selenium Framework - YouTube";
$this->webDriver->get($test_url);
$this->webDriver->manage()->window()->maximize();
sleep(5);
$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));
echo ("\n Window 0: " . $HandleCount[0]);
$win_title = $this->webDriver->getTitle();
echo ("\n Title of the window 0 is " . $win_title);
$this->assertEquals($win_title, $title_1);
/* Go to the end of the Page since we are looking to click the YouTube button */
$link = "window.scrollTo(0, document.body.scrollHeight)";
$this->webDriver->executeScript($link);
/* $browser_button = $this->webDriver->findElement(WebDriverBy::XPath("//a[.='Click Here']")); */
$browser_button = $this->webDriver->findElement(WebDriverBy::XPath("//a[contains(.,'Youtube')]"));
if($browser_button) {
$browser_button->click();
/* The Window Count is now 2 */
$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));
echo ("\n Window 0: " . $HandleCount[0]);
echo ("\n Window 1: " . $HandleCount[1]);
/* Check if the Window titles match */
$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
echo ("\n Title of the window 1 is " . $win_title_2);
sleep(5);
$this->assertEquals($win_title_2, $title_2);
/* Close the newly opened Window and return to the old window */
$this->webDriver->close();
sleep(5);
/* Return to the window with handle = 0 */
$this->webDriver->switchTo()->window($HandleCount[0]);
}
/* Check if the Window titles match */
$win_title_1 = $this->webDriver->getTitle();
echo ("\n Title of the window 0 is " . $win_title_1);
$this->assertEquals($win_title_1, $title_1);
sleep(5);
}
}
?>
Code Walkthrough
A significant part of the implementation in this part of the Selenium PHP tutorial remains the same as that used in handling windows in Selenium with PHP.
public function test_SwitchToNewTab()
{
$test_url = "http://automationpractice.com/index.php";
$title_1 = "My Store";
$title_2 = "Selenium Framework - YouTube";
......................................
......................................
$this->webDriver->get($test_url);
$this->webDriver->manage()->window()->maximize();
......................................
......................................
$HandleCount = $this->webDriver->getWindowHandles();
$link = "window.scrollTo(0, document.body.scrollHeight)";
$this->webDriver->executeScript($link);

The findElement method of WebDriverBy class is used for getting details about the web element [with XPath – //a[contains(.,’Youtube’)].
$browser_button = $this->webDriver->findElement(WebDriverBy::XPath("//a[contains(.,'Youtube')]"));
$browser_button->click();
Hence, sizeof operator when applied to the array (or set) returned by getWindowHandles returns 2.
$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));
echo ("\n Window 0: " . $HandleCount[0]);
echo ("\n Window 1: " . $HandleCount[1]);
$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
$this->assertEquals($win_title_2, $title_2);
$this->webDriver->close();
$this->webDriver->switchTo()->window($HandleCount[0]);
$win_title_1 = $this->webDriver->getTitle();
$this->assertEquals($win_title_1, $title_1);
Execution
Here are the Window Handles of the two browser windows that were instantiated during testing:
Shown below is the Selenium test automation execution snapshot:

As seen in the execution snapshot, the Window Handles of the parent window and tab are unique. When the window and tab is open, the size of the window handles array is 2.

Now that we have seen the implementation and execution for handling windows in Selenium with PHP as well as multiple tabs, let us learn more about handling multiple browser pop-up windows.
For demonstrating handling of browser popups in Selenium PHP, we use the following test scenario:
If the same test is performed on a local Selenium Grid, you have to ensure that pop-ups are enabled for Google Chrome. For enabling, pop-ups for Chrome on the local machine, go to chrome://settings/ 🡪 Privacy and security 🡪 Site Settings 🡪 Pop-ups and redirects. Disable Block option for
http://www.popuptest.com:80


<?php
require 'vendor/autoload.php';
use PHPUnit\Framework\TestCase;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$GLOBALS['LT_USERNAME'] = "user-name";
# accessKey: AccessKey can be generated from automation dashboard or profile section
$GLOBALS['LT_APPKEY'] = "access-key";
class PopUpTest extends TestCase
{
protected $webDriver;
public function build_browser_capabilities(){
/* $capabilities = DesiredCapabilities::chrome(); */
$capabilities = array(
"build" => "[PHP] Pop Up Testing with Chrome on Windows 10",
"name" => "[PHP] Pop Up Testing with Chrome on Windows 10",
"platform" => "Windows 10",
"browserName" => "Chrome",
"version" => "85.0"
);
return $capabilities;
}
public function setUp(): void
{
$url = "https://". $GLOBALS['LT_USERNAME'] .":" . $GLOBALS['LT_APPKEY'] ."@hub.lambdatest.com/wd/hub";
$capabilities = $this->build_browser_capabilities();
/* Download the Selenium Server 3.141.59 from
https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar
*/
/* $this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities); */
$this->webDriver = RemoteWebDriver::create($url, $capabilities);
}
public function tearDown(): void
{
$this->webDriver->quit();
}
/*
* @test
*/
public function test_SwitchToNewWindow()
{
$test_url = "http://www.popuptest.com/popuptest1.html";
$title = "PopupTest 1 - test your popup killer software";
$this->webDriver->get($test_url);
sleep(5);
/* This will open-up main window and six pop-up windows */
/* Once the page is loaded, the total window count will be 7 */
$HandleCount = $this->webDriver->getWindowHandles();
/* This is the ID of the parent window */
$mainHandle = $HandleCount[0];
echo ("\n Total number of window handles are " . sizeof($HandleCount));
echo ("\n Window 0: " . $HandleCount[0]);
$win_title = $this->webDriver->getTitle();
echo ("\n Title of the parent window is " . $win_title);
foreach( $HandleCount as $handle)
{
if($handle != $mainHandle)
{
echo ("\n Window handle of the current window: " . $handle);
$this->webDriver->switchTo()->window($handle);
echo ("\n Title of the current window: " . $this->webDriver->getTitle());
/* Close the pop-up window and return to the old window */
$this->webDriver->close();
sleep(2);
}
}
$this->webDriver->switchTo()->window($mainHandle);
$this->webDriver->manage()->window()->maximize();
sleep(5);
$curr_window_title = $this->webDriver->getTitle();
echo ("\n\n Title of the only left window: " . $curr_window_title);
$this->assertEquals($curr_window_title, $title);
sleep(5);
}
}
?>
Code WalkThrough
$test_url = "http://www.popuptest.com/popuptest1.html";
$title = "PopupTest 1 - test your popup killer software";
$this->webDriver->get($test_url);
The sizeof operation when performed on the set returned by getWindowHandles should return 7 (i.e. one parent window + six pop-up windows).
The first element (i.e. $HandleCount[0]) in the set is the Window Handle of the parent window and the same is saved in a temporary variable (i.e. $mainHandle)
/* This will open-up main window and six pop-up windows */
/* Once the page is loaded, the total window count will be 7 */
$HandleCount = $this->webDriver->getWindowHandles();
/* This is the ID of the parent window */
$mainHandle = $HandleCount[0];
echo ("\n Total number of window handles are " . sizeof($HandleCount));
If the current window handle is that of a pop-up window, the switchTo method is used to switch to the pop-up window. Selenium WebDriver’s close method is used for closing the pop-up window(s). The pop-up windows will be closed in the order – popup6.html 🡪 popup5.html 🡪 popup4.html 🡪 popup3.html 🡪 popup2.html 🡪 popup1.html. The loop is exited when all pop-up windows are closed and only one window is active (i.e. parent window).
foreach($HandleCount as $handle)
{
if($handle != $mainHandle)
{
echo ("\n Window handle of the current window: " . $handle);
$this->webDriver->switchTo()->window($handle);
$this->webDriver->close();
sleep(2);
}
}
$this->webDriver->switchTo()->window($mainHandle);
$this->webDriver->manage()->window()->maximize();
$curr_window_title = $this->webDriver->getTitle();
$this->assertEquals($curr_window_title, $title);
Execution
The window handles of the pop-up windows are marked below:

Only the parent window is left on the closure of all the pop windows, eventually closed after the test has been executed.

As seen in the execution snapshot obtained by visiting the automation tab on the LambdaTest platform, we notice that the pop-up windows are opened and later closed in reverse chronological order.



Browser windows, including tabs and pop-up windows, are identified using Window Handles. These handles act as Window IDs and are unique for every browser window. In this Selenium WebDriver PHP tutorial, we had a look at handling windows in Selenium with PHP using methods like switchTo, getWindowHandle, and getWindowHandles. These methods are instrumental in window handling in Selenium test automation with PHP.
Happy Selenium Automation Testing ☺
38