SECRET OF CSS

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.

So many options!!! SpongeBob image

Pop-up windows can “sometimes” be annoying for 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 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.

What Is a Window Handle?

The window handle is a unique identifier whose primary responsibility is to hold all the windows’ addresses. When the Selenium WebDriver instance is instantiated, an alpha-numeric ID is assigned to the window. The unique ID is called a window handle, a pointer to the window that 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, regardless 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):

  • Forms that require selection of date from a newly opened window
  • Button clicks that open a new tab (or Window)
  • Pop-ups that are used to show some offers to the end-user; Job portals commonly use this strategy
  • Handling windows that show advertisements

Click operation sample scenarioShown 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 is five, and each of them has unique Window handles that can be used to automate operations on them.

Commands for Handling Windows in Selenium With PHP

Selenium provides different methods for handling multiple windows. You can also refer to our guide to handle multiple windows with Selenium and Protractor. Here are some of the widely used commands in Selenium PHP testing for switching browser windows and handling pop-up windows.

If you are a PHP expert, you can acquire a benchmark industry certification specializing in core PHP programming skills and expand your opportunities to advance your career in PHP automation testing.

SwitchTo Window

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]);

getWindowHandle

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.

getWindowHandles

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]);

How To Handle Multiple Browser Windows, Tabs, and Pop-ups in Selenium PHP

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 and 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.

Browser capabilities 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, and press the “Enter” button twice to proceed with the installation of the PHPUnit framework. On completion, the PHPUnit framework (version 9.3) is installed.

The file composer.lock contains information on the dependencies and the vendor folder has all the dependencies.

Composer.lock file

Vendor folder

The file vendor/autoload.php will be used in the test code so that classes (and their 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. 

Multiple Browser Window Handling in Selenium PHP

For demonstrating multiple window handling in Selenium PHP, we use the following test scenario:

  1. Open the LambdaTest page in the Chrome browser.
  2. Get the window handle of the currently focused window.
  3. Open the LambdaTest blog page in a new window using the HTML attribute __blank.
  4. Print the respective window handles.
  5. Switch to the window where the second URL is opened.
  6. Assert if the window title does not match the expected title.
  7. Close the window under focus.
  8. Switch to the first window and assert if the window title does not match the expected title.
  9. Close the browser window.

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

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.

1. On opening the test URL, the getWindowHandles method of WebDriver is used for getting the handles of the opened browser window(s).

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();

2. The web element with hyperlink to the site’s YouTube channel is located at the end of the page. The window.scrollTo method in JavaScript is executed using the executeScript method offered by JavaScriptExecutor. This will navigate to the end of the page.

$link = "window.scrollTo(0, document.body.scrollHeight)";
$this->webDriver->executeScript($link);

3. For getting information about the required web element, we use the POM Builder extension in Chrome to get the locator information (i.e. XPath).

Automation Practice Website

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')]"));

4. The click method is invoked on the located web element.

$browser_button->click();

5. The getWindowHandles method returns an alpha-numeric array (or set) that contains window handles (or Window ID) of the currently opened browser windows (or tabs). In our case, the number of open windows is 2.

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]);

6. The switchTo method of Selenium WebDriver is used for switching to the second window (i.e., $HandleCount[1]). Assert is raised if the window title does not match with the expected title.

$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
$this->assertEquals($win_title_2, $title_2);

7. The close method closes the window under focus (i.e., the tab where the YouTube channel is open).

$this->webDriver->close();

8. Switch to the parent window (i.e. $HandleCount[0]). Assert if the titles do not match.

$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:

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 are open, the size of the window handles array is 2.

Execution snapshot: window handles of the parent window and tab are unique

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.

Handling Multiple Browser Pop-up Windows in Selenium with PHP

For demonstrating the handling of browser popups in Selenium PHP, we use the following test scenario:

  1. Open http://www.popuptest.com/popuptest1.html in the Chrome browser.
  2. Close all the pop-up windows in reverse chronological order.
  3. Check if the title of the parent window matches the expected title.

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.

Disable Block option for http://www.popuptest.com:80

Pop-ups blocked

<?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

1. As the Selenium Grid on LambdaTest is used for testing, the user-name and access key are stored in global variables. The same can be obtained by visiting the profile page on LambdaTest.

$GLOBALS['LT_USERNAME'] = "user-name";
# accessKey:  AccessKey can be generated from automation dashboard or profile section
$GLOBALS['LT_APPKEY'] = "access-key";

2. The browser capabilities are generated using the LambdaTest Capabilities Generator.

$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"
    );

3. The combination of global variables holding the user-name and access-key is used to access the Selenium Grid on LambdaTest (@hub.lambdatest.com/wd/hub). The create method in the RemoteWebDriver class takes first the parameter the Selenium Grid URL and the second parameter is the browser capabilities.

$url = "https://". $GLOBALS['LT_USERNAME'] .":" . $GLOBALS['LT_APPKEY'] ."@hub.lambdatest.com/wd/hub";
$capabilities = $this->build_browser_capabilities();
$this->webDriver = RemoteWebDriver::create($url, $capabilities);

4. In the test method test_SwitchToNewWindow, the test URL https://www.lambdatest.com is opened and the getWindowHandle method offered by Selenium WebDriver is used to get the window handle of the current window.

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();
     ...............................................
}	

5. The JavaScript method window.open is used for creating a new secondary browser window. The height and width of window dimensions are also passed to the method. 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);

6. The getWindowHandles method returns an alphanumeric array containing the Window ID (or handle) of the currently open windows. The sizeof operator on the array returned by getWindowHandles returns the number of opened windows (i.e., in our case, it is 2).

$HandleCount = $this->webDriver->getWindowHandles();
echo ("\n Total number of window handles are " . sizeof($HandleCount));

7. Assert if the total number of window handles is less than 2.

$this->assertEquals(2, sizeof($HandleCount));

8. The switchTo method of Selenium WebDriver is used for switching to the second window (i.e., one which was opened using the window.open method). Assert is raised if the Window title does not match with the expected title.

$this->webDriver->switchTo()->window($HandleCount[1]);
$win_title_2 = $this->webDriver->getTitle();
$this->assertEquals($win_title_2, $title_2);

9. The current window is closed using the Close() method.

$this->webDriver->close();

10. Now the window handle count will be one (since only the parent window is open). The switchTo method is used for switching to the parent window, the handle (i.e., $wHandle) of which is passed as a parameter to the method. 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);

11. The quit method of Selenium WebDriver in PHP is invoked as a part of the tearDown.

public function tearDown(): void
{
    $this->webDriver->quit();
}

Execution

The window handles of the pop-up windows are marked below:

The window handles of the pop-up windows marked

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

Title of the only left window

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.

Execution snapshot 1

Execution snapshot 2

Conclusion

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!



News Credit

%d bloggers like this: