Multi-window interactions, such as popups, new tabs, and OAuth or payment flows, often break Selenium tests if not handled explicitly. When a test opens a new window or popup, WebDriver does not automatically switch to it.
Without explicitly using the correct window handle, Selenium continues interacting with the original window, causing flaky tests and inconsistent results.
In this article, I will explain how the Selenium window handles work, how to switch between parent and child windows, how to return to the original window, and how to avoid common mistakes that make multi-window tests unreliable.
Handling Multiple Windows in Selenium using Window Handles
A window handle is a unique identifier assigned to every browser window or tab in a Selenium session. WebDriver uses this handle to locate and switch between windows reliably.
A common testing scenario involves opening a new tab or popup, performing actions there, and then returning to the original window. Selenium requires explicit window handle management to ensure WebDriver interacts with the correct browser context.
Since each window has its own handle, you can:
- Switch control to any open window.
- Retrieve all window handles.
- Ensure multi-window workflows are executed without flaky behavior.
Example: Switch Between Parent and Child Windows
import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class WindowHandle_Demo {
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver","Path_to_chromedriver");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
// Load the website
driver.get("https://www.naukri.com/selenium-playground/window-popup-modal-demo ");
// Store the parent window handle
String parent = driver.getWindowHandle();
// Get all window handles
Set<String> allWindows = driver.getWindowHandles();
Iterator<String> iterator = allWindows.iterator();
while(iterator.hasNext()) {
String childWindow = iterator.next();
if(!parent.equals(childWindow)) {
driver.switchTo().window(childWindow);
System.out.println(driver.getTitle());
driver.close();
}
}
// Switch back to parent window
driver.switchTo().window(parent);
}
}Output:
On execution, the script opens multiple child windows, performs the necessary operations, and returns to the parent window.
Opening the Parent Browser Window :
Opening a New Popup Window :


Switching Selenium Control to the Child Window:

Returning Control to the Parent Window :

Difference between getWindowHandle() and getWindowHandles()
Selenium WebDriver provides two key methods to manage multiple browser windows:
| Method | Description | Return Type |
|---|---|---|
| getWindowHandle() | Returns the handle (unique ID) of the current window | String |
| getWindowHandles() | Returns handles of all open windows/tabs | Set<String> |
When to use / Real-world Scenarios:
- Use getWindowHandle() to store the main window before opening popups, new tabs, or SSO/payment flows. Later, switch back to this handle to continue testing the main page.
- Use getWindowHandles() when multiple windows or tabs may open dynamically. For example, clicking a “Help” link that opens a new tab, interacting with it, then closing it and returning to the original window.
Pro tip: Always validate the window after switching (via title, URL, or a key element) instead of assuming order, to avoid flaky tests.
How to switch to a new window in Selenium Webdriver using Java?
To switch to a new window in Selenium WebDriver using Java, follow these steps:
Step-by-Step Code Example:
// Store the current window handle (main window)
String mainWindowHandle = driver.getWindowHandle();
// Perform an action that opens a new window
driver.findElement(By.linkText("Open New Window")).click();
// Get all window handles
Set<String> allWindowHandles = driver.getWindowHandles();
// Iterate through the window handles
for (String handle : allWindowHandles) {
if (!handle.equals(mainWindowHandle)) {
// Switch to the new window
driver.switchTo().window(handle);
break;
}
}
// Now you're in the new window
System.out.println("Title of new window: " + driver.getTitle());
To return to the main window:
driver.switchTo().window(mainWindowHandle);Notes:
- Each window/tab has a unique handle (a String).
- Always store the main window handle before opening a new one.
- Use driver.close() to close the current window and driver.quit() to close all.
Key Multi-Window Automation Scenarios in Selenium
Modern web applications often open multiple windows, tabs, or popups for login, payments, help, or dynamic content. Handling these windows correctly is crucial for reliable automation, especially in CI/CD environments or complex workflows. Below are common real-world scenarios and how to manage them with Selenium.
1. OAuth / SSO Login Popups
Many applications redirect authentication to third-party providers (Google, Microsoft, Okta). The login opens in a separate window or popup. If Selenium interacts with the main window instead, tests fail.
How to switch to the OAuth popup and complete login:
This code demonstrates how to detect the popup, switch control to it, perform login actions, and return to the main application window.
// Store main window handle
String parentWindow = driver.getWindowHandle();
// Click Twitter link
driver.findElement(By.linkText("Follow On Twitter")).click();
// Wait until Twitter window opens
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
// Switch to Twitter popup window
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Verify Twitter page opened
System.out.println("Twitter Window Title: "
+ driver.getTitle());
// Click 'Sign in with Google'
driver.findElement(
By.xpath("//span[text()='Sign in with Google']"))
.click();
// Wait until Google OAuth popup appears
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(3));
// Store Twitter window handle
String twitterWindow = driver.getWindowHandle();
// Switch to Google login popup
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parentWindow)
&& !handle.equals(twitterWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Verify Google popup
System.out.println("Google Login Popup Title: "
+ driver.getTitle());
// select Google account manually
// OR automate email/password if allowed
// Close Google popup
driver.close();
// Switch back to Twitter window
driver.switchTo().window(twitterWindow);
// Close Twitter window
driver.close();
// Return to original parent window
driver.switchTo().window(parentWindow);
System.out.println("Returned to Parent Window");Explanation:
- driver.getWindowHandle() stores the main window.

- driver.getWindowHandles() retrieves all open windows.

- Iteration finds the popup window and switches context.

- After actions are performed, driver.close() closes the popup, and driver.switchTo().window(parentWindow) returns control to the main window.



2. Payment Gateway Windows
Checkout flows often redirect to payment providers in a new tab or popup. Tests must interact with this window without disrupting the main checkout process.
How to switch to the payment popup and complete the transaction:
This snippet shows how to switch to a payment window, perform actions, and return to the main checkout page.
String parentWindow = driver.getWindowHandle();
// Click Place Order
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[text()='Place Order']"))).click();
// Wait until payment window appears
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Perform payment actions
driver.findElement(By.id("name")).sendKeys("ABC");
driver.findElement(By.id("country")).sendKeys("India");
driver.findElement(By.id("city")).sendKeys("BANGLORE");
driver.findElement(By.id("card")).sendKeys("4111111111111111");
driver.findElement(By.id("month")).sendKeys("12");
driver.findElement(By.id("year")).sendKeys("2026");
// Click Purchase
driver.findElement(By.xpath("//button[text()='Purchase']")).click();
driver.close();
driver.switchTo().window(parentWindow);Explanation:
- Store the parent handle before opening the payment popup.

- Switch to the payment window using getWindowHandles().

- Perform payment actions, close the popup, and return to the main window.

- Ensures the checkout test continues without interruption.

3. Help / Documentation Links
Help or documentation links often open new tabs, and tests must verify content without interrupting the main workflow.
How to switch to the help or docs tab and verify content:
This code demonstrates switching to the new tab, verifying key elements, and returning to the original window.
String parentWindow = driver.getWindowHandle();
driver.findElement(By.linkText("Documentation")).click();
// Wait for new tab
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Verify content
System.out.println(driver.getTitle());
driver.close();
driver.switchTo().window(parentWindow);Explanation:
- Store the main window handle first.
- Switch to the new tab using the handles.
- Verify content (title, URL, key elements).
- Close the tab and return to the main window to continue testing.
4. Dynamic Popups or Ads
Some pages trigger unexpected popups or ads based on user behavior or session state. Tests need to detect, handle, or close them dynamically to prevent failures.
How to detect and close dynamic popups in Selenium:
This snippet shows how to switch to any newly opened window, perform necessary actions (or close), and return to the main window.
String parentWindow = driver.getWindowHandle();
// Wait for any new window dynamically
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
// Optional: perform actions or close popup
driver.close();
}
}
driver.switchTo().window(parentWindow);Explanation:
- Detects any unexpected popup window by comparing handles.
- Switch context to the popup for verification or closure.
- Return control to the main window to continue the main test flow.
Common Pitfalls in Window Handling
Even experienced testers often encounter issues when automating multi-window flows. Understanding these pitfalls helps prevent flaky tests and ensures reliable automation.
1. Switching Before the Child Window Opens
Why it fails: If your script tries to switch to a new window before it actually opens, Selenium will throw a NoSuchWindowException. This often happens when new tabs or popups take time to appear.

How to fix it: Use an explicit wait for the number of windows to increase before switching.
String parentWindow = driver.getWindowHandle();
driver.findElement(By.id("open-popup")).click();
// Wait until a new window appears
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
break;
}
}Explanation:
- WebDriverWait ensures the child window is present before switching.
- Prevents NoSuchWindowException and flaky test failures.
2. Assuming Order of Handles
Why it fails: getWindowHandles() returns a Set, which does not guarantee order. Assuming the second handle is always the child window can cause tests to act on the wrong window.
How to fix it: Compare each handle with the stored parent window, or validate by title/URL after switching.
String parentWindow = driver.getWindowHandle();
Set<String> handles = driver.getWindowHandles();
for(String handle : handles) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
if(driver.getTitle().contains("Expected Title")) {
// Correct window found
break;
}
}
}Explanation:
- Always check window identity rather than relying on index or order.
- Ensures tests interact with the intended window.
3. Closing the Wrong Window
Why it fails: Calling driver.close() without switching context may close the parent window by mistake, breaking the rest of the test.
How to fix it: Always switch to the target window first, then close it. Return to the parent afterwards.
String parent = driver.getWindowHandle();
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parent)) {
driver.switchTo().window(handle);
driver.close();
}
}
driver.switchTo().window(parent);Explanation:
- Ensures only child windows are closed.
- The main test continues reliably.
4. Ignoring Browser-Specific Behavior
Why it fails: Popups or new tabs may behave differently across browsers. For example:
- Chrome may block a popup if it’s not triggered by a user click.
- Firefox may load the page title or elements slower, causing Selenium to switch too early and fail.
How to fix it:
- Always test multi-window flows across multiple browsers.
- Use explicit waits for window presence, title, or key elements.
- Avoid Thread.sleep() for synchronization.
String parentWindow = driver.getWindowHandle();
// Wait for new window/tab to appear
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.numberOfWindowsToBe(2));
// Switch to the new window
for(String handle : driver.getWindowHandles()) {
if(!handle.equals(parentWindow)) {
driver.switchTo().window(handle);
// Wait until the expected title or element is visible
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.titleContains("Expected Window Title"));
break;
}
}
// Perform actions on the new window
// ...
driver.close();
driver.switchTo().window(parentWindow);Explanation:
- WebDriverWait ensures the new window exists before switching.
- Nested wait for titleContains ensures the window has fully loaded before interacting.
- Covers Chrome’s popup blocking and Firefox’s slower rendering issues.
Conclusion
Effectively managing multiple windows in Selenium is crucial for automating modern web applications that use popups, new tabs, or third-party flows. By properly capturing window handles, switching context explicitly, and validating window content before performing actions, you can prevent flaky tests and ensure your automation scripts run reliably across browsers.
Following these strategies allows your Selenium tests to navigate complex multi-window scenarios, including OAuth logins, payment gateways, help or documentation tabs, and unexpected popups, without breaking the main workflow or losing test context.




