Skip to main content
SeleniumDecoded

Windows and Tabs

Handle multiple browser windows and tabs, switch between them, and manage popup windows.

Selenium 3 & 4 Stable

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 handle
String mainWindow = driver.getWindowHandle();
System.out.println("Main window: " + mainWindow);
// Get all window handles
Set<String> allWindows = driver.getWindowHandles();
System.out.println("Total windows: " + allWindows.size());
// Switch to a different window
for (String handle : allWindows) {
if (!handle.equals(mainWindow)) {
driver.switchTo().window(handle);
System.out.println("Switched to: " + driver.getTitle());
}
}
// Switch back to main window
driver.switchTo().window(mainWindow);
# Get current window handle
main_window = driver.current_window_handle
print(f"Main window: {main_window}")
# Get all window handles
all_windows = driver.window_handles
print(f"Total windows: {len(all_windows)}")
# Switch to a different window
for handle in all_windows:
if handle != main_window:
driver.switch_to.window(handle)
print(f"Switched to: {driver.title}")
# Switch back to main window
driver.switch_to.window(main_window)
// Get current window handle
const mainWindow = await driver.getWindowHandle();
console.log(`Main window: ${mainWindow}`);
// Get all window handles
const allWindows = await driver.getAllWindowHandles();
console.log(`Total windows: ${allWindows.length}`);
// Switch to a different window
for (const handle of allWindows) {
if (handle !== mainWindow) {
await driver.switchTo().window(handle);
console.log(`Switched to: ${await driver.getTitle()}`);
}
}
// Switch back to main window
await driver.switchTo().window(mainWindow);
// Get current window handle
string mainWindow = driver.CurrentWindowHandle;
Console.WriteLine($"Main window: {mainWindow}");
// Get all window handles
IList<string> allWindows = driver.WindowHandles;
Console.WriteLine($"Total windows: {allWindows.Count}");
// Switch to a different window
foreach (string handle in allWindows)
{
if (handle != mainWindow)
{
driver.SwitchTo().Window(handle);
Console.WriteLine($"Switched to: {driver.Title}");
}
}
// Switch back to main window
driver.SwitchTo().Window(mainWindow);

Opening and Handling New Windows

Handle New Window/Tab
Selenium 3 & 4 Stable
// Store main window before action that opens new window
String mainWindow = driver.getWindowHandle();
int windowCountBefore = driver.getWindowHandles().size();
// Click link that opens new window
driver.findElement(By.linkText("Open in new window")).click();
// Wait for new window to open
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.numberOfWindowsToBe(windowCountBefore + 1));
// Get new window handle and switch to it
Set<String> allWindows = driver.getWindowHandles();
for (String handle : allWindows) {
if (!handle.equals(mainWindow)) {
driver.switchTo().window(handle);
break;
}
}
// Now interacting with new window
System.out.println("New window title: " + driver.getTitle());
driver.findElement(By.id("form-in-new-window")).submit();
// Close new window and return to main
driver.close(); // Closes current window only
driver.switchTo().window(mainWindow);
# Store main window before action that opens new window
main_window = driver.current_window_handle
window_count_before = len(driver.window_handles)
# Click link that opens new window
driver.find_element(By.LINK_TEXT, "Open in new window").click()
# Wait for new window to open
wait = WebDriverWait(driver, 10)
wait.until(EC.number_of_windows_to_be(window_count_before + 1))
# Get new window handle and switch to it
all_windows = driver.window_handles
for handle in all_windows:
if handle != main_window:
driver.switch_to.window(handle)
break
# Now interacting with new window
print(f"New window title: {driver.title}")
driver.find_element(By.ID, "form-in-new-window").submit()
# Close new window and return to main
driver.close() # Closes current window only
driver.switch_to.window(main_window)
// Store main window before action that opens new window
const mainWindow = await driver.getWindowHandle();
const windowCountBefore = (await driver.getAllWindowHandles()).length;
// Click link that opens new window
await driver.findElement(By.linkText('Open in new window')).click();
// Wait for new window to open
await driver.wait(async () => {
const handles = await driver.getAllWindowHandles();
return handles.length === windowCountBefore + 1;
}, 10000);
// Get new window handle and switch to it
const allWindows = await driver.getAllWindowHandles();
for (const handle of allWindows) {
if (handle !== mainWindow) {
await driver.switchTo().window(handle);
break;
}
}
// Now interacting with new window
console.log(`New window title: ${await driver.getTitle()}`);
await driver.findElement(By.id('form-in-new-window')).submit();
// Close new window and return to main
await driver.close(); // Closes current window only
await driver.switchTo().window(mainWindow);
// Store main window before action that opens new window
string mainWindow = driver.CurrentWindowHandle;
int windowCountBefore = driver.WindowHandles.Count;
// Click link that opens new window
driver.FindElement(By.LinkText("Open in new window")).Click();
// Wait for new window to open
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.WindowHandles.Count == windowCountBefore + 1);
// Get new window handle and switch to it
foreach (string handle in driver.WindowHandles)
{
if (handle != mainWindow)
{
driver.SwitchTo().Window(handle);
break;
}
}
// Now interacting with new window
Console.WriteLine($"New window title: {driver.Title}");
driver.FindElement(By.Id("form-in-new-window")).Submit();
// Close new window and return to main
driver.Close(); // Closes current window only
driver.SwitchTo().Window(mainWindow);

Creating New Windows/Tabs Programmatically (Selenium 4)

Create New Window or Tab
Selenium 4 Stable
// Open new tab
driver.switchTo().newWindow(WindowType.TAB);
driver.get("https://example.com/page2");
// Now in new tab
// Open new window
driver.switchTo().newWindow(WindowType.WINDOW);
driver.get("https://example.com/page3");
// Now in new window
# Open new tab
driver.switch_to.new_window('tab')
driver.get("https://example.com/page2")
# Now in new tab
# Open new window
driver.switch_to.new_window('window')
driver.get("https://example.com/page3")
# Now in new window
// Open new tab
await driver.switchTo().newWindow('tab');
await driver.get('https://example.com/page2');
// Now in new tab
// Open new window
await driver.switchTo().newWindow('window');
await driver.get('https://example.com/page3');
// Now in new window
// Open new tab
driver.SwitchTo().NewWindow(WindowType.Tab);
driver.Navigate().GoToUrl("https://example.com/page2");
// Now in new tab
// Open new window
driver.SwitchTo().NewWindow(WindowType.Window);
driver.Navigate().GoToUrl("https://example.com/page3");
// Now in new window

Window 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 popup
WebDriverWait 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 popup
driver.findElement(By.id("email")).sendKeys("user@gmail.com");
driver.findElement(By.id("next")).click();
// ... continue OAuth flow
// Popup closes automatically after auth, switch back
wait.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 popup
wait = 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 popup
driver.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 back
wait.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 popup
await 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 popup
await 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 back
await 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 popup
WebDriverWait 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 popup
driver.FindElement(By.Id("email")).SendKeys("user@gmail.com");
driver.FindElement(By.Id("next")).Click();
// ... continue OAuth flow
// Popup closes automatically after auth, switch back
wait.Until(d => d.WindowHandles.Count == 1);
driver.SwitchTo().Window(mainWindow);

Best Practices

  1. Always store main window before actions that open new windows
  2. Wait for window count before trying to switch
  3. Use meaningful identifiers (title, URL) over handles when possible
  4. Close windows you open to avoid resource leaks
  5. Return to main window at the end of operations

Next Steps