Windows and Tabs
Handle multiple browser windows and tabs, switch between them, and manage popup windows.
Selenium 3 & 4 Stable Verified against Selenium 4.48.0
Modern web applications often open new windows or tabs. Selenium can switch between them, but you need to manage window handles explicitly.
Understanding Window Handles
Every browser window/tab has a unique identifier called a “handle.” To interact with a specific window, you must switch to it using its handle.
Basic Window Handle Operations
Selenium 3 & 4 Stable
// Get current window handleString mainWindow = driver.getWindowHandle();System.out.println("Main window: " + mainWindow);
// Get all window handlesSet<String> allWindows = driver.getWindowHandles();System.out.println("Total windows: " + allWindows.size());
// Switch to a different windowfor (String handle : allWindows) { if (!handle.equals(mainWindow)) { driver.switchTo().window(handle); System.out.println("Switched to: " + driver.getTitle()); }}
// Switch back to main windowdriver.switchTo().window(mainWindow);# Get current window handlemain_window = driver.current_window_handleprint(f"Main window: {main_window}")
# Get all window handlesall_windows = driver.window_handlesprint(f"Total windows: {len(all_windows)}")
# Switch to a different windowfor handle in all_windows: if handle != main_window: driver.switch_to.window(handle) print(f"Switched to: {driver.title}")
# Switch back to main windowdriver.switch_to.window(main_window)// Get current window handleconst mainWindow = await driver.getWindowHandle();console.log(`Main window: ${mainWindow}`);
// Get all window handlesconst allWindows = await driver.getAllWindowHandles();console.log(`Total windows: ${allWindows.length}`);
// Switch to a different windowfor (const handle of allWindows) { if (handle !== mainWindow) { await driver.switchTo().window(handle); console.log(`Switched to: ${await driver.getTitle()}`); }}
// Switch back to main windowawait driver.switchTo().window(mainWindow);// Get current window handlestring mainWindow = driver.CurrentWindowHandle;Console.WriteLine($"Main window: {mainWindow}");
// Get all window handlesIList<string> allWindows = driver.WindowHandles;Console.WriteLine($"Total windows: {allWindows.Count}");
// Switch to a different windowforeach (string handle in allWindows){ if (handle != mainWindow) { driver.SwitchTo().Window(handle); Console.WriteLine($"Switched to: {driver.Title}"); }}
// Switch back to main windowdriver.SwitchTo().Window(mainWindow);Opening and Handling New Windows
Handle New Window/Tab
Selenium 3 & 4 Stable
// Store main window before action that opens new windowString mainWindow = driver.getWindowHandle();int windowCountBefore = driver.getWindowHandles().size();
// Click link that opens new windowdriver.findElement(By.linkText("Open in new window")).click();
// Wait for new window to openWebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));wait.until(ExpectedConditions.numberOfWindowsToBe(windowCountBefore + 1));
// Get new window handle and switch to itSet<String> allWindows = driver.getWindowHandles();for (String handle : allWindows) { if (!handle.equals(mainWindow)) { driver.switchTo().window(handle); break; }}
// Now interacting with new windowSystem.out.println("New window title: " + driver.getTitle());driver.findElement(By.id("form-in-new-window")).submit();
// Close new window and return to maindriver.close(); // Closes current window onlydriver.switchTo().window(mainWindow);# Store main window before action that opens new windowmain_window = driver.current_window_handlewindow_count_before = len(driver.window_handles)
# Click link that opens new windowdriver.find_element(By.LINK_TEXT, "Open in new window").click()
# Wait for new window to openwait = WebDriverWait(driver, 10)wait.until(EC.number_of_windows_to_be(window_count_before + 1))
# Get new window handle and switch to itall_windows = driver.window_handlesfor handle in all_windows: if handle != main_window: driver.switch_to.window(handle) break
# Now interacting with new windowprint(f"New window title: {driver.title}")driver.find_element(By.ID, "form-in-new-window").submit()
# Close new window and return to maindriver.close() # Closes current window onlydriver.switch_to.window(main_window)// Store main window before action that opens new windowconst mainWindow = await driver.getWindowHandle();const windowCountBefore = (await driver.getAllWindowHandles()).length;
// Click link that opens new windowawait driver.findElement(By.linkText('Open in new window')).click();
// Wait for new window to openawait driver.wait(async () => { const handles = await driver.getAllWindowHandles(); return handles.length === windowCountBefore + 1;}, 10000);
// Get new window handle and switch to itconst allWindows = await driver.getAllWindowHandles();for (const handle of allWindows) { if (handle !== mainWindow) { await driver.switchTo().window(handle); break; }}
// Now interacting with new windowconsole.log(`New window title: ${await driver.getTitle()}`);await driver.findElement(By.id('form-in-new-window')).submit();
// Close new window and return to mainawait driver.close(); // Closes current window onlyawait driver.switchTo().window(mainWindow);// Store main window before action that opens new windowstring mainWindow = driver.CurrentWindowHandle;int windowCountBefore = driver.WindowHandles.Count;
// Click link that opens new windowdriver.FindElement(By.LinkText("Open in new window")).Click();
// Wait for new window to openWebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));wait.Until(d => d.WindowHandles.Count == windowCountBefore + 1);
// Get new window handle and switch to itforeach (string handle in driver.WindowHandles){ if (handle != mainWindow) { driver.SwitchTo().Window(handle); break; }}
// Now interacting with new windowConsole.WriteLine($"New window title: {driver.Title}");driver.FindElement(By.Id("form-in-new-window")).Submit();
// Close new window and return to maindriver.Close(); // Closes current window onlydriver.SwitchTo().Window(mainWindow);Creating New Windows/Tabs Programmatically (Selenium 4)
Create New Window or Tab
Selenium 4 Stable
// Open new tabdriver.switchTo().newWindow(WindowType.TAB);driver.get("https://example.com/page2");// Now in new tab
// Open new windowdriver.switchTo().newWindow(WindowType.WINDOW);driver.get("https://example.com/page3");// Now in new window# Open new tabdriver.switch_to.new_window('tab')driver.get("https://example.com/page2")# Now in new tab
# Open new windowdriver.switch_to.new_window('window')driver.get("https://example.com/page3")# Now in new window// Open new tabawait driver.switchTo().newWindow('tab');await driver.get('https://example.com/page2');// Now in new tab
// Open new windowawait driver.switchTo().newWindow('window');await driver.get('https://example.com/page3');// Now in new window// Open new tabdriver.SwitchTo().NewWindow(WindowType.Tab);driver.Navigate().GoToUrl("https://example.com/page2");// Now in new tab
// Open new windowdriver.SwitchTo().NewWindow(WindowType.Window);driver.Navigate().GoToUrl("https://example.com/page3");// Now in new windowWindow Helper Class
Reusable Window Manager
Selenium 3 & 4 Stable
public class WindowManager { private WebDriver driver; private WebDriverWait wait;
public WindowManager(WebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, Duration.ofSeconds(10)); }
public String getMainWindow() { return driver.getWindowHandle(); }
public void switchToNewWindow(String mainWindow) { wait.until(d -> d.getWindowHandles().size() > 1);
for (String handle : driver.getWindowHandles()) { if (!handle.equals(mainWindow)) { driver.switchTo().window(handle); return; } } }
public void switchToWindowByTitle(String title) { for (String handle : driver.getWindowHandles()) { driver.switchTo().window(handle); if (driver.getTitle().contains(title)) { return; } } throw new RuntimeException("Window with title '" + title + "' not found"); }
public void switchToWindowByUrl(String urlContains) { for (String handle : driver.getWindowHandles()) { driver.switchTo().window(handle); if (driver.getCurrentUrl().contains(urlContains)) { return; } } throw new RuntimeException("Window with URL containing '" + urlContains + "' not found"); }
public void closeCurrentAndSwitch(String targetWindow) { driver.close(); driver.switchTo().window(targetWindow); }
public void closeAllExcept(String keepWindow) { for (String handle : driver.getWindowHandles()) { if (!handle.equals(keepWindow)) { driver.switchTo().window(handle); driver.close(); } } driver.switchTo().window(keepWindow); }}class WindowManager: def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10)
def get_main_window(self): return self.driver.current_window_handle
def switch_to_new_window(self, main_window): self.wait.until(lambda d: len(d.window_handles) > 1)
for handle in self.driver.window_handles: if handle != main_window: self.driver.switch_to.window(handle) return
def switch_to_window_by_title(self, title): for handle in self.driver.window_handles: self.driver.switch_to.window(handle) if title in self.driver.title: return raise Exception(f"Window with title '{title}' not found")
def switch_to_window_by_url(self, url_contains): for handle in self.driver.window_handles: self.driver.switch_to.window(handle) if url_contains in self.driver.current_url: return raise Exception(f"Window with URL containing '{url_contains}' not found")
def close_current_and_switch(self, target_window): self.driver.close() self.driver.switch_to.window(target_window)
def close_all_except(self, keep_window): for handle in self.driver.window_handles: if handle != keep_window: self.driver.switch_to.window(handle) self.driver.close() self.driver.switch_to.window(keep_window)class WindowManager { constructor(driver) { this.driver = driver; }
async getMainWindow() { return await this.driver.getWindowHandle(); }
async switchToNewWindow(mainWindow) { await this.driver.wait(async () => { const handles = await this.driver.getAllWindowHandles(); return handles.length > 1; }, 10000);
const handles = await this.driver.getAllWindowHandles(); for (const handle of handles) { if (handle !== mainWindow) { await this.driver.switchTo().window(handle); return; } } }
async switchToWindowByTitle(title) { const handles = await this.driver.getAllWindowHandles(); for (const handle of handles) { await this.driver.switchTo().window(handle); const currentTitle = await this.driver.getTitle(); if (currentTitle.includes(title)) { return; } } throw new Error(`Window with title '${title}' not found`); }
async closeCurrentAndSwitch(targetWindow) { await this.driver.close(); await this.driver.switchTo().window(targetWindow); }}public class WindowManager{ private IWebDriver driver; private WebDriverWait wait;
public WindowManager(IWebDriver driver) { this.driver = driver; this.wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); }
public string GetMainWindow() { return driver.CurrentWindowHandle; }
public void SwitchToNewWindow(string mainWindow) { wait.Until(d => d.WindowHandles.Count > 1);
foreach (string handle in driver.WindowHandles) { if (handle != mainWindow) { driver.SwitchTo().Window(handle); return; } } }
public void SwitchToWindowByTitle(string title) { foreach (string handle in driver.WindowHandles) { driver.SwitchTo().Window(handle); if (driver.Title.Contains(title)) { return; } } throw new Exception($"Window with title '{title}' not found"); }
public void CloseCurrentAndSwitch(string targetWindow) { driver.Close(); driver.SwitchTo().Window(targetWindow); }}Common Patterns
OAuth/Login Popup
Handle OAuth Popup
Selenium 3 & 4 Medium
String mainWindow = driver.getWindowHandle();
// Click "Login with Google"driver.findElement(By.id("google-login")).click();
// Wait for and switch to OAuth popupWebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));wait.until(ExpectedConditions.numberOfWindowsToBe(2));
for (String handle : driver.getWindowHandles()) { if (!handle.equals(mainWindow)) { driver.switchTo().window(handle); break; }}
// Complete OAuth in popupdriver.findElement(By.id("email")).sendKeys("user@gmail.com");driver.findElement(By.id("next")).click();// ... continue OAuth flow
// Popup closes automatically after auth, switch backwait.until(ExpectedConditions.numberOfWindowsToBe(1));driver.switchTo().window(mainWindow);main_window = driver.current_window_handle
# Click "Login with Google"driver.find_element(By.ID, "google-login").click()
# Wait for and switch to OAuth popupwait = WebDriverWait(driver, 10)wait.until(EC.number_of_windows_to_be(2))
for handle in driver.window_handles: if handle != main_window: driver.switch_to.window(handle) break
# Complete OAuth in popupdriver.find_element(By.ID, "email").send_keys("user@gmail.com")driver.find_element(By.ID, "next").click()# ... continue OAuth flow
# Popup closes automatically after auth, switch backwait.until(EC.number_of_windows_to_be(1))driver.switch_to.window(main_window)const mainWindow = await driver.getWindowHandle();
// Click "Login with Google"await driver.findElement(By.id('google-login')).click();
// Wait for and switch to OAuth popupawait driver.wait(async () => { const handles = await driver.getAllWindowHandles(); return handles.length === 2;}, 10000);
const handles = await driver.getAllWindowHandles();for (const handle of handles) { if (handle !== mainWindow) { await driver.switchTo().window(handle); break; }}
// Complete OAuth in popupawait driver.findElement(By.id('email')).sendKeys('user@gmail.com');await driver.findElement(By.id('next')).click();// ... continue OAuth flow
// Popup closes automatically after auth, switch backawait driver.wait(async () => { const h = await driver.getAllWindowHandles(); return h.length === 1;}, 10000);await driver.switchTo().window(mainWindow);string mainWindow = driver.CurrentWindowHandle;
// Click "Login with Google"driver.FindElement(By.Id("google-login")).Click();
// Wait for and switch to OAuth popupWebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));wait.Until(d => d.WindowHandles.Count == 2);
foreach (string handle in driver.WindowHandles){ if (handle != mainWindow) { driver.SwitchTo().Window(handle); break; }}
// Complete OAuth in popupdriver.FindElement(By.Id("email")).SendKeys("user@gmail.com");driver.FindElement(By.Id("next")).Click();// ... continue OAuth flow
// Popup closes automatically after auth, switch backwait.Until(d => d.WindowHandles.Count == 1);driver.SwitchTo().Window(mainWindow);Best Practices
- Always store main window before actions that open new windows
- Wait for window count before trying to switch
- Use meaningful identifiers (title, URL) over handles when possible
- Close windows you open to avoid resource leaks
- Return to main window at the end of operations
Next Steps
- iFrames Handling - Switch between frames
- Alerts and Popups - Handle JavaScript dialogs
- Explicit Waits - Wait for window conditions
- Debugging Tips - Troubleshoot window issues
Copy-paste recipes for this topic
- Click a Link That Opens a New Tab and Switch to It
Detect the new window handle after a click, switch to it, do work, and return to the original tab without guessing handle order.