Series Navigation
→ 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.