Codementor Events

Complete Guide To Handle Multiple Windows With Selenium & Protractor

Published May 20, 2020
Complete Guide To Handle Multiple Windows With Selenium & Protractor

Every day is a challenge for newbie automation testers! Just when you learned how to perform automated browser testing on a single window, you now come across the challenge to handle multiple windows. Isn’t this a nightmare! Well, no need to worry, I’ve got you covered.

While performing automated browser testing, at times you might end up in situations where you would need to handle multiple windows in Selenium. Your test cases might need you to open a new tab and then switch back to the last window to complete the other pending activities.

Let’s say you want to check if all the There might be a certain situation when you might come across a situation where the current browser tab is not active. Hence, to find these issues before they hamper your user’s experience, you need to make sure you include all the test cases to handle multiple windows in Selenium with Protractor.

In this tutorial, I’ll show you how to handle multiple windows in Selenium with Protractor. If you are not familiar with writing Selenium test automation on Protractor, I’ve already covered it in our previous Protractor tutorial.

Working with Browser Window Handles In Selenium With Protractor

Before we handle multiple windows in Selenium Protractor, we need to know how to identify different browser windows and tabs. It’s pretty straightforward, every browser or tab instance has a Global Unique Identifier(GUID), which makes it pretty easy to access them. GUID identifiers help to handle multiple windows in Selenium Protractor, additionally, Protractor provides useful methods that can be used to handle multiple windows in Selenium Protractor for automated browser testing. So, let’s have a look at these methods.

getWindowHandle()

The getWindowHandle() function in the Protractor returns the string GUID for the current active window in the browser. This is invoked on the browser object as – browser.getWindowHandle();

getWindowHandles()

The getWindowHandles() function returns the GUID’s for all the windows and tabs opened on the active browser windows. This is called via the framework as browser.getWindowHandles();

switchTo()

switchTo() method enables easy way to handle multiple windows in Selenium Protractor, tabs and switch between the two. It shifts the control from the current window to the target windows. The GUID is passed as an argument to indicate the Protractor about the target window or tabs. i.e. browser.switchTo().window(guid);

How to Handle Multiple Browser Windows And Tabs In Selenium with Protractor?

Now that you know how to get the GUID of the browser windows and the methods to handle them, you should be fine. So, let’s look at this issue in more detail with a step by step approach to handle multiple windows in Selenium Protractor.

For ease of understanding, I will start by handling two windows in Selenium.

Steps To Handle Two Windows In The Browser:

  1. First ,let’s open the window and launch the url https://www.lambdatest.com in the browser, to handle multiple windows in Selenium Protractor for automated browser testing.
// this property is used to assign an implicit wait time to 20 seconds for automated browser testing  //
browser.manage().timeouts().implicitlyWait(20000);
 
// this functions redirects to the url in the browser for automated browser testing //
browser.get(" https://www.lambdatest.com ");
  1. Then by using Selenium Protractor’s getWindowHandle() function, I’ll get the GUID of the currently active window and store it into a variable.
// it fetches the unique identifier for the first window for automated browser testing  //
 
browser.getWindowHandle().then(function(firstGUID){
  1. Similarly, you can open a new tab/window and navigate to a new URL e.g. https://www.google.com . Further, by using the sleep method, I can indicate to the Selenium Protractor to wait for some time, let’s say 4 seconds, to allow the new tab to load the URL completely. You can even use implicit and explicit wait commands depending on the requirement.
// it will enable to open the second window with a new url for automated browser testing  //
// this functions redirects to the url in the browser //
browser.get( " https://www.google.com " );
element( by.id("two-window")).click();
// make the browser sleep for 4 secs //
browser.sleep(4000);
  1. Next, I’ll get the GUIDs for both the windows i.e . the first window (parent windows) as well as the seconds window ( newly opened windows ), using the Selenium Protractor’s getWindowHandles() function, which stores the guid values for both windows in a collection Set.
// it will fetch the unique identifier for all the windows of the browsers for automated browser testing //
browser.getAllWindowHandles().then(function(getallGUID){
  1. Next, let’s perform an iteration over this collection of GUID, and switch to the new window only after encountering a new GUID, to add to the collection.
// the for loop iterates over the collection i.e. set of guids //
for( var myguid of getallGUID ){
    // the conditional statement to check if the identifier is equal to the guid of the first window //
    if( myguid != firstGUID ){
 
    }
}
  1. Now, I’ll switch to the new window by using the switchTo().window() function and pass the GUID of the new window as an argument to this function.
// the switch function shifts the control to the new window //
browser.switchTo().window(myguid);
// break keyword to come out of the loop //
break;
  1. Finally, let’s perform a search query on Google, after this, I’ll close the window and return to the previous window.
// perform some operation on the new window i.e. searching a keyword on the homepage of google to handle multiple windows in Selenium for automated browser testing//
element(by.name("q")).sendKeys("lambda test");
 
// closes the browser //
browser.close();
// it switches the control back to the first window //
browser.switchTo().window(firstGUID);

In the Selenium test automation script below, I’ve taken a test case to show you how to handle and switch between two windows in a browser.

This is the configuration file used by Selenium Protractor to manage any config parameter, used globally within the application.

// test_config.js //
// The test_config.js file servers as a configuration file for our test case //
// setting required config parameters //
exports.config = {
   directConnect: true,
   // Desired Capabilities that is passed as an argument to the web driver instance.
   capabilities: {
      'browserName': 'chrome'  // name of the browser used to test //
   },
   // Flavour of the framework to be used for our test case //
   framework: 'jasmine',
   // The patterns which are relative to the current working directory when // 
Protractor methods are invoked //
   specs: ['test_script.js'],
// overriding default value of allScriptsTimeout parameter //
      allScriptsTimeout: 999999,
      jasmineNodeOpts: {
// overriding default value of defaultTimeoutInterval parameter //
      defaultTimeoutInterval: 999999
   },
   onPrepare: function () {
      browser.manage().window().maximize();
      browser.manage().timeouts().implicitlyWait(5000);
   }
};

 
var webdriver = require('selenium-webdriver');
 
var script = require('Protractor');
 
var driver = new webdriver.Builder().
        withCapabilities(webdriver.Capabilities.chrome()).
        build();
 
// describing the test case in Protractor //
describe(' Example to demonstrate handle windows in Protractor ', function() {
    browser.ignoreSynchronization = true; // to disable sync //
   // information about the test case //
 it('Scenario to open the Window in browser ', function() {
        // this property is used to assign an implicit wait time to 20 seconds //
        browser.manage().timeouts().implicitlyWait(20000);
        // this function redirects to the url in the browser //
        browser.get("https://www.lambdatest.com");
        // it fetches the unique identifier for the first window //
        browser.getWindowHandle().then(function(firstGUID){
            // this opens the new window //
            browser.get("https://www.google.com");
            element(by.id("two-window")).click();
           // make the browser sleep for 4 secs //
            browser.sleep(4000);
      // it will fetch the unique identifier for all the windows of the browsers to handle multiple windows in Selenium for automated browser testing //
            browser.getAllWindowHandles().then(function(getallGUID){
            // fetch title of the current page
                console.log("The title of the current Page is : "+ browser.getTitle());
                console.log("Total number of open Windows : "+getallGUID.length);
 
  // for loop iterates over the collection i.e. set of guids //
                for( var myguid of allGUID ){
 // the conditional statement to check if the identifier is equal to the guid of the first window //
                    if(myguid != firstGUID){
   // the switch function shifts the control to the new window //
                   browser.switchTo().window(myguid);
    // break keyword to come out of the loop //
                        break;
                    }
                }
   // perform some operation on the new window i.e. a search a keyword on the homepage of google //
                element(by.name("q")).sendKeys("lambda test");
      // fetch the title of the page on the new window //
                browser.sleep(5000).then(function(){
 console.log(" Title after switching to new window : "+ browser.getTitle());
                })
       // close the browser //
                browser.close();
      // again switch back to the parent window //
                browser.switchTo().window(parentGUID);
           // fetch the tile of the page again //
                browser.sleep(5000).then(function(){
                    console.log("Page title after switching back to main window: "+ browser.getTitle());
                })
            })
        })
    });
});

Now let’s take a scenario, where you have to handle more than two windows for automated browser testing. This approach is slightly different, I’ll use three windows for Selenium test automation in this case. You can repeat the same process for any number of browsers you want to work with.

Steps to Handle More Than Two Windows In the Browser With Selenium & Protractor:

  1. Start with performing Step 1 to Step 3 from the previous test case.
  2. Now, you already have two tabs, open the third tab, let’s open https://www.selenium.dev, and use the sleep function for 4 seconds to wait for the new tab to load completely.
  3. Now we will store the GUID values for all the three windows in the collection Set including the value of the newly opened windows using the Protractor’s getWindowHandles() function.
  4. Finally , I’ll iterate through the collection and switch to the second tab i.e. https://www.lambdatest.com using the switchTo() method, and then I’ll verify the title of the web page to be “Cross Browser Testing Tools”.
  5. You can now perform any action on the tab and then close the window to return to the last opened window or tab.

Below is the Selenium test automation script to demonstrate how to handle and switch between more than two windows in a browser in Selenium with Protractor.

var webdriver = require('selenium-webdriver');
 
var script = require('Protractor');
 
var driver = new webdriver.Builder().
        withCapabilities(webdriver.Capabilities.chrome()).
        build();
 
// describing the test case in Selenium with Protractor for automated browser testing//
describe(' Example to demonstrate handle windows in Protractor ', function() {
    browser.ignoreSynchronization = true; // to disable sync //
   // information about the test case //
 it('Scenario to open the Window in browser ', function() {
        // this property is used to assign an implicit wait time to 20 seconds //
        browser.manage().timeouts().implicitlyWait(20000);
        // this function redirects to the url in the browser //
        browser.get("https://www.lambdatest.com");
        // it fetches the unique identifier for the first window //
        browser.getWindowHandle().then(function(firstGUID){
            // click the button to open new window
            element(by.id("three-window")).click();
           // make the browser sleep for 4 secs //
            browser.sleep(4000);
      // it will fetch the unique identifier for all the windows of the browsers for automated browser testing in Selenium with Protractor //
            browser.getAllWindowHandles().then(function(getallGUID){
            // fetch title of the current page
                console.log("The title of the current Page is : "+ browser.getTitle());
console.log("Total number of open Windows : "+getallGUID.length);
 
  // for loop iterates over the collection i.e. set of guids //
                for(var myguid of getallGUID){
     // verify the title of the page to lambda test
                  browser.switchTo().window(myguid);
                  browser.getTitle().then(function(title){
                    if(title == "Cross Browser Testing Tools"){
                        element(by.name("q")).sendKeys("Selenium");
                        browser.sleep(4000);
 
                        }
                    })
                }
                browser.quit()
            })
        })
    });
});

Additional Features to Handle Multiple Browser Windows In Selenium With Protractor

The Selenium Protractor framework is so robust that it provides various customized utilities that allow us to perform certain actions, by calling its inbuilt classes and functions on the browser object. For instance, imagine a scenario where there is a requirement to open a link in the new window but as a standard protocol, the browser does not allow to open the link in the new window by default. In such a case, we need to force open the link in the new window, using Selenium Protractor’s action class.

Below are the steps by step approach to open the link in such a use case :

  1. We need to specify the url we would want to launch ( https:// www.google.com ) and store the element id “force-new-window” for the above link to a variable of type WebElement.
// store the element
WebElement ele = element(By.id("force-new-window")).getWebElement();
  1. Next, we will create an object of the action class to invoke certain events on the hyperlink.
// create object for Actions class
browser.actions()
  1. Then, we will call various methods on the action class object
  • Invoke the keyDown () function and pass the Shift key as an argument.
  • Invoke the click () function and pass the web element from above as an argument.
  • Finally, we will bind these two methods to the action class using the perform function and our task gets executed. Now we can see the website launched in a new window.
browser.actions().keyDown(Protractor.Key.SHIFT)
                .click(ele)
                .perform()

Below is the complete script that demonstrates how Protractor forcefully launches the link in a new browser window.

var webdriver = require('selenium-webdriver');
 
var script = require('Protractor');
 
var driver = new webdriver.Builder().
        withCapabilities(webdriver.Capabilities.chrome()).
        build();
// describing the test case in Protractor //
describe(' Example to demonstrate handle windows in Protractor ', function() {
    browser.ignoreSynchronization = true; // to disable sync //
// information about the test case //
    it(' Scenario to open the Window in browser ', function() {
        // set the timeout to 20 secs //
        browser.manage().timeouts().implicitlyWait(20000);
        // launch the url to google.com //
        browser.get("https://www.google.com");
        // fetch the identifier of the first window //
        browser.getWindowHandle().then(function(firstGUID){
            // assign the element to a web element type //
            WebElement ele = element(by.id("force-new-window"));
            // create action object and invoke functions //
            browser.actions().keyDown(Protractor.Key.SHIFT)
                            .click(ele)
                            .perform()
        });
    });
});
 

Usually, while clicking a hyperlink opens on the same window by default.

<a id='two-window' href='https://google.com'>Click me</a>

But there are certain scenarios when you need the flexibility to open the link in the new windows rather than the same window or tab. This can be done simply by using the anchor tag and setting the value of the target keyword as “_blank”. This ensures that whenever a user clicks on the link, it launches in the new window.

//this open the url in a new window on clicking the button //
<a id='two-window' href='https://google.com' target='_blank'><input type='button' value=" Click to Open New Window"></a>
// this launches the link by clicking on the hyperlink //
<a id='two-window' href='https://google.com' target='_blank'>Click me</a>

Execute Automation Scripts on Online Selenium Grid Platform With Protractor

You can execute the same Selenium test automation in the cloud Selenium grid platform with minimal configuration changes that are required to build the driver and connect to the LambdaTest hub. Below is the updated script with the required changes.

// test_config.js //
// The test_config.js file servers as a configuration file for our test case //
 
LT_USERNAME = process.env.LT_USERNAME || "irohitgoyal"; // Lambda Test User name
LT_ACCESS_KEY = process.env.LT_ACCESS_KEY || "r9JhziRaOvd5T4KCJ9ac4fPXEVYlOTealBrADuhdkhbiqVGdBg"; // Lambda Test Access key
 
exports.capabilities = {
  'build': ' Automation Selenium Webdriver Test Script ', // Build Name to be display in the test logs
  'name': ' Protractor Selenium Test on Chrome',  // The name of the test to distinguish amongst test cases //
  'platform':'Windows 10', //  Name of the Operating System
  'browserName': 'chrome', // Name of the browser
  'version': '79.0', // browser version to be used
  'visual': false,  // flag to check whether to take step by step screenshot
  'network':false,  // flag to check whether to capture network logs
  'console':false, // flag to check whether to capture console logs.
  'tunnel': false // flag to check if it is required to run the localhost through the tunnel
  };
 
// setting required config parameters //
exports.config = {
   directConnect: true,
 
   // Desired Capabilities that is passed as an argument to the web driver instance.
   capabilities: {
      'browserName': 'chrome'  // name of the browser used to test //
   },
 
   // Flavour of the framework to be used for our test case //
   framework: 'jasmine',
 
   // The patterns which are relative to the current working directory when  
 
Protractor methods are invoked //
 
   specs: ['test_script.js'],
// overriding default value of allScriptsTimeout parameter //
      allScriptsTimeout: 999999,
      jasmineNodeOpts: {
// overriding default value of defaultTimeoutInterval parameter //
      defaultTimeoutInterval: 999999
   },
   onPrepare: function () {
      browser.manage().window().maximize();
      browser.manage().timeouts().implicitlyWait(5000);
   }
};
// test_script.js //
 
// Build the web driver that we will be using in Lambda Test
var buildDriver = function(caps) {
  return new webdriver.Builder()
    .usingServer(
      "http://" +
      LT_USERNAME +
      ":" +
      LT_ACCESS_KEY +
      "@hub.lambdatest.com/wd/hub"
    )
    .withCapabilities(caps)
    .build();
};
 
// describing our test scenario for Protractor framework //
describe(' Example to demonstrate handle windows in Protractor ', function() {
    browser.ignoreSynchronization = true; // to disable sync //
 
// adding the before an event that builds the driver and triggers before the test execution
  beforeEach(function(done) {
    caps.name = this.currentTest.title;
    driver = buildDriver(caps);
    done();
  });
// information about the test case
  it(' Scenario to open the Window in browser ', function() {
        // set the timeout to 20 secs //
        browser.manage().timeouts().implicitlyWait(20000);
        // launch the url to google.com //
        browser.get("https://www.google.com");
        // fetch the identifier of the first window //
        browser.getWindowHandle().then(function(firstGUID){
            // assign the element to a web element type //
            WebElement ele = element(by.id("force-new-window"));
            // create action object and invoke functions //
            browser.actions().keyDown(Protractor.Key.SHIFT)
                            .click(ele)
                            .perform()
        });
    });
});

You can execute the Selenium test automation scripts on the cloud, just by adding the desired capability to your code, to connect to the LambdaTest platform. To perform automated browser testing on LambdaTest cloud Selenium Grid, you need to generate the desired capability matrix to specify the environment you want to execute our Selenium test automation on. Here is the link to visit LambdaTest Selenium desired capabilities generator.

Below is the output on running the Selenium test automation:

Well, it’s a success mate, our Selenium test automation script ran successfully on the Cloud Selenium Grid.

selenium-automation-dashboard

Wrapping it Up!

This is just the end of the beginning! You now know how to handle multiple browser windows in Selenium. Go ahead, and handle the heck out of these browser windows. They might have been a nightmare before, but between you and me, we now know that it’s just a piece of cake! You now know how to handle multiple windows and tabs in the Protractor framework to perform Selenium test automation. The framework is robust, flexible and provides various inbuilt classes and functions.

In case, you want to learn more about using Protractor with Selenium, do subscribe to our blog. And, I’d keep you posted about new blogs. This is certainly not the last blog on Protractor, there’s more to come! If you haven’t checked out our previous blogs on automated browser testing with a protractor, and Selenium locators with a protractor, I’d urge you to do so, as these topics are essential for automated browser testing. Also, If you’d like to help your peers learn about handing multiple browsers, do share this blog with them. That’s all for now! Happy Testing.

Discover and read more posts from Aditya Dwivedi
get started