Handling Multiple Windows With Protractor For Selenium Testing
Join the DZone community and get the full member experience.
Join For FreeEvery 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 of handling 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 and tabs. 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 involving multiple windows/tabs in Selenium with Protractor.
In this Selenium Protractor tutorial, I'll show you how to handle multiple windows in Selenium with Protractor. If you are not familiar with writing Selenium Automation tests on Protractor, I’ve already covered it in our previous Selenium Protractor tutorial.
Working With Browser Window Handles In Selenium With Protractor
Before we handle browser windows, 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, additionally, Protractor provides useful methods that can be used to handle windows. 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 management of windows, 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 the browser.
For ease of understanding, I will start by handling two windows.
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 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 ");
2. Then by using Protractor’s getWindowHandle() function, I’ll get the GUID of the currently active window and store it into a variable.
xxxxxxxxxx
// it fetches the unique identifier for the first window for automated browser testing //
browser.getWindowHandle().then(function(firstGUID){
3. 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 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.
xxxxxxxxxx
// 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);
4. 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 Protractor’s getWindowHandles() function, which stores the guide values for both windows in a collection Set.
xxxxxxxxxx
// it will fetch the unique identifier for all the windows of the browsers for automated browser testing //
browser.getAllWindowHandles().then(function(getallGUID){
5. 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.
xxxxxxxxxx
// 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 ){
}
}
6. Now, I’ll switch to the new window by using the switch().window() function and pass the GUID of the new window as an argument to this function.
xxxxxxxxxx
// the switch function shifts the control to the new window //
browser.switchTo().window(myguid);
// break keyword to come out of the loop //
break;
7. Finally, let’s perform a search query on Google, after this, I’ll close the window and return to the previous window.
xxxxxxxxxx
// 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 automation test script below, I’ve taken a test case to show you how to handle and switch between two windows in a browser.
test_config.js
This is the configuration file used by Protractor to manage any config parameter, used globally within the application.
xxxxxxxxxx
// 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 and Protractor
Start with performing Step 1 to Step 3 from the previous test case.
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.
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.
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”.
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.
xxxxxxxxxx
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 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 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.
xxxxxxxxxx
// store the element
WebElement ele = element(By.id("force-new-window")).getWebElement();
2. Next, we will create an object of the action class to invoke certain events on the hyperlink.
xxxxxxxxxx
// create object for Actions class
browser.actions()
3. 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.
xxxxxxxxxx
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.
xxxxxxxxxx
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()
});
});
});
Enable Hyperlink to Open in A New Window
Usually, while clicking a hyperlink opens on the same window by default.
xxxxxxxxxx
<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.
xxxxxxxxxx
//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
xxxxxxxxxx
// 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
xxxxxxxxxx
// 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 the 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:
To know more about how to handle mouse action and keyboard events in Protractor, refer to our blog on the topic.
Wrapping It Up!
This is just the end of the beginning! You now know how to handle multiple browser windows. 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 browser windows and tabs in the Protractor framework to perform Selenium Automation Testing. 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 cross-browser testing with a protractor, and Selenium locators with a protractor, debug protractor tests and handling alerts and popups. 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 handling multiple browsers, do share this blog with them.
That’s all for now!
Happy Testing.
Published at DZone with permission of Aditya Dwivedi. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments