← Blog

"Selenium Series #9: Handling Windows, Frames, Alerts and Pop-ups"

Real applications open new tabs, embed iframes, and show JavaScript dialogs. Learn to switch windows, interact with iframes, dismiss alerts, and handle authentication pop-ups.

reading now
views
comments

Series Navigation

Part 8: Page Object Model

Part 10: JavaScriptExecutor — Beyond the WebDriver API


Multiple Windows and Tabs

Every browser window/tab has a unique window handle — a string like CDwindow-4F67....

// Get current window handle
String mainWindow = driver.getWindowHandle();
System.out.println("Main window: " + mainWindow);

// Get ALL open window handles
Set<String> allWindows = driver.getWindowHandles();
System.out.println("Total windows: " + allWindows.size());

// Click something that opens a new window/tab
driver.findElement(By.linkText("Open new window")).click();

// Switch to new window
for (String windowHandle : driver.getWindowHandles()) {
    if (!windowHandle.equals(mainWindow)) {
        driver.switchTo().window(windowHandle);
        break;
    }
}

// Now working in the new window
System.out.println("New window title: " + driver.getTitle());
driver.findElement(By.id("newWindowContent")).click();

// Close new window and go back to main
driver.close(); // closes current window
driver.switchTo().window(mainWindow); // go back to main
System.out.println("Back to: " + driver.getTitle());

Utility Method for Window Switching

public void switchToNewWindow(String originalHandle) {
    WebDriverWait wait = new WebDriverWait(driver, 10);

    // Wait for new window to open
    wait.until(driver -> driver.getWindowHandles().size() > 1);

    for (String handle : driver.getWindowHandles()) {
        if (!handle.equals(originalHandle)) {
            driver.switchTo().window(handle);
            return;
        }
    }
    throw new RuntimeException("No new window found");
}

// Usage
String mainHandle = driver.getWindowHandle();
driver.findElement(By.id("popupLink")).click();
switchToNewWindow(mainHandle);
// ... interact with popup
driver.close();
driver.switchTo().window(mainHandle);

Selenium 4 — New Tab / New Window APIs

// Selenium 4 added direct window type control
import org.openqa.selenium.WindowType;

// Open new tab
driver.switchTo().newWindow(WindowType.TAB);
driver.get("https://example.com");

// Open new window
driver.switchTo().newWindow(WindowType.WINDOW);
driver.get("https://other-site.com");

Frames and iFrames

iFrames embed another HTML document inside the page. Selenium cannot interact with elements inside an iframe without switching to it first.

<!-- Main page -->
<h1>Payment Page</h1>
<iframe id="paymentFrame" src="https://payment-provider.com/checkout">
    <!-- Inside iframe -->
    <input type="text" id="cardNumber" placeholder="Card number">
    <input type="text" id="expiry" placeholder="MM/YY">
</iframe>
// Switch to frame by ID or name attribute
driver.switchTo().frame("paymentFrame");

// Switch by index (0-based, order they appear in DOM)
driver.switchTo().frame(0);

// Switch by WebElement reference (most reliable)
WebElement frameElement = driver.findElement(By.id("paymentFrame"));
driver.switchTo().frame(frameElement);

// Now you can interact with iframe content
driver.findElement(By.id("cardNumber")).sendKeys("4111111111111111");
driver.findElement(By.id("expiry")).sendKeys("12/25");

// Go back to main page
driver.switchTo().defaultContent();

// Go up one frame level (if nested frames)
driver.switchTo().parentFrame();

Nested Frames

// Outer frame → Inner frame pattern
driver.switchTo().frame("outerFrame");
driver.switchTo().frame("innerFrame"); // now inside nested frame
// interact with deeply nested content
driver.switchTo().defaultContent(); // back to main page in one step

Waiting for Frame to Load

WebDriverWait wait = new WebDriverWait(driver, 15);

// Wait until frame is available AND switch to it
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("paymentFrame"));

// Now in the frame — interact with content
WebElement cardInput = wait.until(
    ExpectedConditions.visibilityOfElementLocated(By.id("cardNumber"))
);
cardInput.sendKeys("4111111111111111");

JavaScript Alerts

JavaScript has three types of dialog: alert, confirm, and prompt.

// ── alert() ────────────────────────────────────────────────────────────────
// Simple message, only OK button
driver.findElement(By.id("alertBtn")).click();

WebDriverWait wait = new WebDriverWait(driver, 5);
Alert alert = wait.until(ExpectedConditions.alertIsPresent());

String alertText = alert.getText();
System.out.println("Alert message: " + alertText);
alert.accept(); // click OK

// ── confirm() ──────────────────────────────────────────────────────────────
// OK or Cancel
driver.findElement(By.id("confirmBtn")).click();
Alert confirm = wait.until(ExpectedConditions.alertIsPresent());
System.out.println("Confirm: " + confirm.getText());

confirm.accept();  // click OK
// or
confirm.dismiss(); // click Cancel

// ── prompt() ───────────────────────────────────────────────────────────────
// Text input + OK/Cancel
driver.findElement(By.id("promptBtn")).click();
Alert prompt = wait.until(ExpectedConditions.alertIsPresent());

prompt.sendKeys("My input text"); // type into the prompt field
prompt.accept(); // click OK

// Get what was entered (some apps echo it back)
// prompt.dismiss() to click Cancel without submitting

Authentication Pop-ups

Browser-native HTTP authentication dialogs (not HTML) cannot be handled by standard Selenium. Use the URL approach:

// Embed credentials directly in URL
String url = "https://username:password@the-internet.herokuapp.com/basic_auth";
driver.get(url);
// Chrome accepts this and passes credentials automatically

// Verify authentication worked
Assert.assertTrue(
    driver.findElement(By.tagName("p")).getText().contains("Congratulations"),
    "Basic auth should succeed"
);

For more complex authentication scenarios, use ChromeOptions to add an extension that handles the dialog.


Complete Window/Frame Test Example

@Test
public void testWindowAndFrameHandling() {
    WebDriver driver = getDriver();
    driver.get("https://the-internet.herokuapp.com");

    // Test multiple windows
    driver.get("https://the-internet.herokuapp.com/windows");
    String mainHandle = driver.getWindowHandle();
    driver.findElement(By.linkText("Click Here")).click();

    switchToNewWindow(mainHandle);
    Assert.assertEquals(driver.getTitle(), "New Window");
    driver.close();
    driver.switchTo().window(mainHandle);

    // Test iframes
    driver.get("https://the-internet.herokuapp.com/frames");
    driver.findElement(By.linkText("iFrame")).click();
    driver.switchTo().frame("mce_0_ifr");
    WebElement body = driver.findElement(By.cssSelector("body#tinymce"));
    Assert.assertFalse(body.getText().isEmpty(), "iFrame content should be present");
    driver.switchTo().defaultContent();

    // Test alerts
    driver.get("https://the-internet.herokuapp.com/javascript_alerts");
    driver.findElement(By.xpath("//button[text()='Click for JS Alert']")).click();
    Alert alert = new WebDriverWait(driver, 5).until(ExpectedConditions.alertIsPresent());
    Assert.assertEquals(alert.getText(), "I am a JS Alert");
    alert.accept();
}

What's Next

In Part 10 we use JavaScriptExecutor to do things the standard WebDriver API cannot — scrolling, clicking hidden elements, manipulating the DOM, and extracting complex page data.

Discussion

Loading...

Leave a Comment

All comments are reviewed before appearing. No links please.

0 / 1000