Selenium C# Tutorial: Handling Multiple Browser Windows
Learn how to handle multiple windows in Selenium C# along with some Selenium test automation examples.
Join the DZone community and get the full member experience.
Join For FreeA common scenario in a website (or web application) is opening up a new browser (or tab) on the click of a button. With these multiple browsers, windows can be automated using Selenium test automation.
Once the Selenium WebDriver instance is instantiated, a unique alphanumeric id is assigned to the window. This is called window handle and is used to identify browser windows. Since the id is unique, it is used by the Selenium WebDriver to switch between different windows (or tabs).
The id is retained till the closure of the Selenium WebDriver session via WebDriver.Quit or manual killing of the process. The SwitchTo() command is used to do a context switch to the intended browser window.
In my previous Selenium C# tutorial, I've covered how to Here in this part of Selenium C# tutorial, I’ll guide you on window handling in Selenium C#.
Commands Used For Window Handling In Selenium C#
These commands are vital for performing Selenium Test Automation as they allow help in switching to a new window or a tab, knowing the info about the current window and of all the windows open. Here are some of the widely used commands that are used for window handling in Selenium C#.
SwitchTo Window
This command is used to switch the focus to a new browser window (or tab) by supplying the Window Name or Window Handle as an argument to the command.
driver.SwitchTo().Window(WindowHandle);
driver.SwitchTo().Window(WindowName);
CurrentWindowHandle
This command returns the window handle (as a String) of the current window.
xxxxxxxxxx
String currentWindowHandle = driver.CurrentWindowHandle;
WindowHandles
The WindowHandles command gets the handles of all the open instances of the browser under test. The return type is a String ReadOnlyCollection.
The syntax of WindowHandles is:
xxxxxxxxxx
ReadIOnlyCollection<string> IWebDriver.WindowHandles { get;};
Example usage of WindowHandles:
xxxxxxxxxx
IList<string> totWindowHandles = new List<string> (WebDriver.WindowHandles);
Now in the next section this Selenium C# tutorial, we answer, how to handle multiple browser windows in Selenium C#.
Handling Multiple Browser Windows In Selenium C#
The fundamental principles of Window Handles are used for window handling in Selenium C#. By default, the Parent Window is the one that has the focus. To switch the context from the Parent Window to a Child Window, the command WebDriver.SwitchTo(WindowHandle) is used. Instead of Window Handle, Window Id can also be used as both these identifiers are unique to every browser window (or tab).
To demonstrate window handling of multiple browsers in Selenium C#. A Chrome WebDriver instance is initiated with the URL under test as https://www.lambdatest.com. A unique Window handle of the typed string is used to identify the window.
xxxxxxxxxx
/* Using Chrome Webdriver Instance for window handling in selenium C#*/
using NUnit.Framework;
using System;
using System.Collections.ObjectModel;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
namespace Selenium_Window_Demo_2
{
class Selenium_Window_Demo_2
{
IWebDriver driver;
[SetUp]
public void start_Browser()
{
/* Local Selenium WebDriver */
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test, Order(1)]
public void test_window_ops()
{
String test_url_1 = "https://www.lambdatest.com";
String test_url_2 = "https://www.lambdatest.com/blog/";
String test_url_2_title = "LambdaTest | A Cross Browser Testing Blog";
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
driver.Url = test_url_1;
/* Not a good practice to use Thread.Sleep as it is a blocking call */
/* Used here for demonstration */
System.Threading.Thread.Sleep(4000);
/* Different ways in which ExecuteScript can be used */
/* js.ExecuteScript("window.open(test_url_2)"); */
/* js.ExecuteScript("window.open(arguments[0])", test_url_2); */
/* Reference - https://www.w3schools.com/jsref/met_win_open.asp */
js.ExecuteScript("window.open('" + test_url_2 + "', '_blank', 'toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800')");
System.Threading.Thread.Sleep(6000);
Assert.AreEqual(2, driver.WindowHandles.Count);
var newWindowHandle = driver.WindowHandles[1];
Assert.IsTrue(!string.IsNullOrEmpty(newWindowHandle));
/* Assert.AreEqual(driver.SwitchTo().Window(newWindowHandle).Url, "https://www.lambdatest.com/blog/"); */
string expectedNewWindowTitle = test_url_2_title;
Assert.AreEqual(driver.SwitchTo().Window(newWindowHandle).Title, expectedNewWindowTitle);
/* Close the newly opened Window and return to the old window */
driver.SwitchTo().Window(driver.WindowHandles[1]).Close();
System.Threading.Thread.Sleep(2000);
/* Return to the window with handle = 0 */
driver.SwitchTo().Window(driver.WindowHandles[0]);
System.Threading.Thread.Sleep(2000);
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
The window.open() method with relevant parameters such as URL, _blank, window size, etc. is used to open the URL https://www.lambdatest.com/blog
. This would be a child window to the parent window which is already open.
xxxxxxxxxx
/*window.open() method for window handling in Selenium C# */
js.ExecuteScript("window.open('" + test_url_2 + "', '_blank', 'toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800')");
System.Threading.Thread.Sleep(6000);
Assert.AreEqual(2, driver.WindowHandles.Count);
The WindowHandle count now becomes two (0 and 1). The SwitchTo().Window() command with Window Handle of the second window (i.e. child window) is used to switch to that browser window.
xxxxxxxxxx
/*WindowHandle count and SwitchTo().Window() for window handling in Selenium C# window handling in Selenium C# */
var newWindowHandle = driver.WindowHandles[1];
Assert.IsTrue(!string.IsNullOrEmpty(newWindowHandle));
/* Assert.AreEqual(driver.SwitchTo().Window(newWindowHandle).Url, "https://www.lambdatest.com/blog/"); */
string expectedNewWindowTitle = test_url_2_title;
Assert.AreEqual(driver.SwitchTo().Window(newWindowHandle).Title, expectedNewWindowTitle);
The Child Window is closed and the window count becomes one. The context is switched to the parent window using the command driver.SwitchTo().Window(driver.WindowHandles[0])
xxxxxxxxxx
/* Close the newly opened Window and return to the old window for window handling in Selenium C#*/
driver.SwitchTo().Window(driver.WindowHandles[1]).Close();
System.Threading.Thread.Sleep(2000);
/* Return to the window with handle = 0 */
driver.SwitchTo().Window(driver.WindowHandles[0]);
As seen in the output snapshot, the two browser windows are open with URL 1 - https://www.lambdatest.com and URL 2 — https://www.lambdatest.com/blog. The WindowHandle of the second browser window is used with the SwitchTo() command to switch the context to that window. Once that child window is closed, the same approach is used to switch to the parent window (driver.WindowHandles[0]).
Now that you know how to open multiple windows in Selenium C#, let’s move on to learn how to handle multiple browser tabs for windows handling in this Selenium C# tutorial.
Handling Multiple Browser Tabs In Selenium C#
The concept of Window Handle remains the same whether a URL is opened in a new window or a new tab. For demonstrating how to handle multiple browser tabs in Selenium C#, we use the test URL as http://the-internet.herokuapp.com/windows The Click Here link on the test page is located using the XPath property. In our earlier articles, we covered XPath in Selenium in greater detail.
Once the button is clicked, the internet herokuapp URL opens up in a new browser tab. The window handle count becomes two with the driver.WindowHandles[0] representing the window handle of ‘parent window’ and driver.WindowHandles[1] representing window handle of ‘child window’.
xxxxxxxxxx
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System;
using System.Collections.ObjectModel;
namespace Selenium_Window_Demo_1
{
class Selenium_Window_Demo_1
{
IWebDriver driver;
[SetUp]
public void start_Browser()
{
// Local Selenium WebDriver
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test, Order(1)]
public void test_window_ops()
{
String test_url = "http://the-internet.herokuapp.com/windows";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Url = test_url;
var browser_button = driver.FindElement(By.XPath("//a[.='Click Here']"));
Assert.AreEqual(1, driver.WindowHandles.Count);
string WindowTitle = "The Internet";
Assert.AreEqual(WindowTitle, driver.Title);
browser_button.Click();
Assert.AreEqual(2, driver.WindowHandles.Count);
Console.WriteLine("Window Handle[0] - " + driver.WindowHandles[0]);
var newTabHandle = driver.WindowHandles[1];
Assert.IsTrue(!string.IsNullOrEmpty(newTabHandle));
Console.WriteLine("Window Handle[1] - " + driver.WindowHandles[1]);
Assert.AreEqual(driver.SwitchTo().Window(newTabHandle).Url, "http://the-internet.herokuapp.com/windows/new");
string expectedNewWindowTitle = "New Window";
Assert.AreEqual(driver.SwitchTo().Window(newTabHandle).Title, expectedNewWindowTitle);
/* Thread Sleep is not a good practice since it is a blocking call */
/* Only used for demonstration */
System.Threading.Thread.Sleep(2000);
driver.SwitchTo().Window(driver.WindowHandles[1]).Close();
driver.SwitchTo().Window(driver.WindowHandles[0]);
System.Threading.Thread.Sleep(2000);
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
The SwitchTo().Window(driver.WindowHandles[0]) is used to switch back to the parent window after closing the child window.
xxxxxxxxxx
var newTabHandle = driver.WindowHandles[1];
Assert.IsTrue(!string.IsNullOrEmpty(newTabHandle));
Assert.AreEqual(driver.SwitchTo().Window(newTabHandle).Url, "http://the-internet.herokuapp.com/windows/new");
string expectedNewWindowTitle = "New Window";
Assert.AreEqual(driver.SwitchTo().Window(newTabHandle).Title, expectedNewWindowTitle);
/* Thread Sleep is not a good practice since it is a blocking call */
/* Only used for demonstration */
System.Threading.Thread.Sleep(2000);
driver.SwitchTo().Window(driver.WindowHandles[1]).Close();
driver.SwitchTo().Window(driver.WindowHandles[0]);
Here are the Window Handles of the two browser windows that were instantiated during automated browser testing:
The output snapshot from Visual Studio is below:
Now, let’s move on to handling browser pop-up windows in this selenium C# tutorial.
Handling Browser Pop-up Windows In Selenium C#
There are many types of websites (e.g. job sites) that throw a couple of pop-up windows. Selenium test automation can be used to automate the handling of these pop-ups. It does not depend on the number of pop-ups being shown as each new window will be assigned a unique window handle. The window handle can be used with the SwitchTo() command to switch between different windows.
To demonstrate the handling of browser pop-ups, we use the popup test URL. Pop-ups for Chrome can be enabled by going to Privacy and Security — Site Settings — Pop-ups and redirects and disabling Block option for http://www.popuptest.com:80
Alternatively, you can open the test URL in the Chrome browser and enable pop-ups for that particular site.
The site opens up 6 pop-up windows. In this Selenium test Automation scenario, we close pop-up windows, one at a time in reverse chronological order i.e. http://www.popuptest.com/popup6.html will be closed first, http://www.popuptest.com/popup5.html will be closed next and so on.
Window Handles of these pop-ups are used to perform the following operation:
xxxxxxxxxx
Switch to a window (or pop-up)
driver.SwitchTo().Window(WindowHandle)
Close the browser window
driver.SwitchTo().Window(driver.WindowHandles[window-number]).Close() or
driver.Close() (if the window to be closed is in focus)
Once all the pop-windows are closed, the Window Count becomes 1. The Window Title is then matched with the expected title to make sure that the parent window is in focus. On confirmation, the parent window is also closed and the resources used by Chrome WebDriver instance are freed using a driver.Quit().
xxxxxxxxxx
using NUnit.Framework;
using System;
using System.Collections.ObjectModel;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using System.Collections.Generic;
namespace selenium_pop_up_windows
{
class selenium_pop_up_windows
{
IWebDriver driver;
/******* Helper functions ********/
/* API - Get Window Title */
public String getCurrWindowTitle()
{
String windowTitle = driver.Title;
return windowTitle;
}
/* API - Get Window Handle */
public String getMainWinHandle(IWebDriver driver)
{
return driver.CurrentWindowHandle;
}
/* The test website open-ups number of pop-ups */
/* API - Close all the pop-ups and return to the primary window */
public Boolean closeAllWindows(String currWindowHandle)
{
IList<string> totWindowHandles = new List<string>(driver.WindowHandles);
foreach (String WindowHandle in totWindowHandles)
{
Console.WriteLine(WindowHandle);
if (!WindowHandle.Equals(currWindowHandle))
{
driver.SwitchTo().Window(WindowHandle);
driver.Close();
}
}
driver.SwitchTo().Window(currWindowHandle);
if (driver.WindowHandles.Count == 1)
return true;
else
return false;
}
[SetUp]
public void start_Browser()
{
/* Local Selenium WebDriver */
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void test_window_ops()
{
String test_url = "http://www.popuptest.com/popuptest1.html";
String expected_win_title = "PopupTest 1 - test your popup killer software";
driver.Url = test_url;
/* Not a good practice to use Thread.Sleep as it is a blocking call */
/* Used here for demonstration */
System.Threading.Thread.Sleep(8000);
String windowTitle = getCurrWindowTitle();
String mainWindow = getMainWinHandle(driver);
Assert.IsTrue(closeAllWindows(mainWindow));
/* Addition of delay for checking the output */
System.Threading.Thread.Sleep(4000);
Assert.IsTrue(windowTitle.Contains(expected_win_title), "Title does not match - Test Failed");
}
[TearDown]
public void close_Browser()
{
driver.Quit();
}
}
}
For modularity, we have created a few Helper Functions:
getCurrWindowTitle()
Get the Window title of the currently focused window.
xxxxxxxxxx
public String getCurrWindowTitle()
{
String windowTitle = driver.Title;
return windowTitle;
}
getMainWinHandle(IWebDriver driver)
It returns the handle of the window under focus. This API is called after switching to the intended window hence, driver.CurrentWindowHandle is sufficient to return the window handle.
xxxxxxxxxx
public String getMainWinHandle(IWebDriver driver)
{
return driver.CurrentWindowHandle;
}
closeAllWindows(String currWindowHandle)
This API closes all the pop-up windows one by one till the Window Handle count becomes 1 (driver.WindowHandles.Count == 1) i.e. only the parent window is open.
xxxxxxxxxx
public Boolean closeAllWindows(String currWindowHandle)
{
IList<string> totWindowHandles = new List<string>(driver.WindowHandles);
foreach (String WindowHandle in totWindowHandles)
{
if (!WindowHandle.Equals(currWindowHandle))
{
driver.SwitchTo().Window(WindowHandle);
driver.Close();
}
}
driver.SwitchTo().Window(currWindowHandle);
if (driver.WindowHandles.Count == 1)
return true;
else
return false;
}
The Window handles are stored in a Collection of type String.
xxxxxxxxxx
IList<string> totWindowHandles = new List<string>(driver.WindowHandles);
The currently focused pop-window is closed and a SwitchTo() command is used to switch to the other pop-up window shown on the screen. The API will close pop-up windows in the order popup6.html — popup5.html — popup4.html — popup3.html — popup2.html — popup1.html. The API returns true when all pop-ups are closed and the Parent window is the currently focused window.
xxxxxxxxxx
foreach (String WindowHandle in totWindowHandles)
{
if (!WindowHandle.Equals(currWindowHandle))
{
driver.SwitchTo().Window(WindowHandle);
driver.Close();
}
}
if (driver.WindowHandles.Count == 1)
return true;
....................................
....................................
The implementation under [Test] annotation uses these helper functions to perform Selenium test automation. The Window Title of the parent window is compared to verify the closure of all the pop-up windows.
xxxxxxxxxx
String windowTitle = getCurrWindowTitle();
String mainWindow = getMainWinHandle(driver);
Assert.IsTrue(closeAllWindows(mainWindow));
/* Addition of delay for checking the output */
System.Threading.Thread.Sleep(4000);
Assert.IsTrue(windowTitle.Contains(expected_win_title), "Title does not match - Test Failed");
The Window handles of the pop-up windows and parent window are below:
Below is the execution snapshot from Visual Studio which indicates that our Selenium Automation tests have passed
As the implementation is written generically, the same implementation can be used for verifying pop-up window handling with any other website.
This article was a part Selenium C# tutorial series, where I've explained how to set up visual studio, handle the implicit wait, handle explicit and fluent waits, and handling alert windows. If you haven’t gone through them, I'd encourage you to go through them!
All in All
Browser windows, including tabs, are identified using Window Handles. These handles are used in conjunction with SwitchTo.Window() Selenium API to handle browser windows, tabs, and pop-up windows. In this Selenium C# tutorial, we had a deep-dive look into all the available scenarios with web browsers.
It’s a wrap! This was all I had to share in this Selenium C# tutorial. If you liked this article feel free to share it with your friends, you can retweet it on twitter or your favorite social media account to help us reach out to more people.
Happy Testing ☺
Published at DZone with permission of Himanshu Sheth. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments