Q16 of 37 · Selenium
How do you handle iframes in Selenium WebDriver?
Short answer
Short answer: Switch into the frame with `driver.switchTo().frame(...)` (by element, name, or index) before interacting with elements inside it. Switch back with `defaultContent()` when done. Until you switch in, the frame's DOM is invisible to Selenium.
Detail
An iframe is a separate document embedded in the parent page. Selenium's commands target one document at a time — by default, the top-level document. Anything inside an iframe is unreachable until you switch focus.
Switching in has three flavours:
// 1. By WebElement (most reliable — survives renames)
WebElement frame = driver.findElement(By.cssSelector("iframe[data-test=stripe]"));
driver.switchTo().frame(frame);
// 2. By name or id attribute
driver.switchTo().frame("payment-frame");
// 3. By index (last resort — fragile if frames reorder)
driver.switchTo().frame(0);
Switching out:
driver.switchTo().defaultContent()— back to the top-level document.driver.switchTo().parentFrame()— back one level (useful for nested iframes).
Practical patterns:
Always switch back after frame work. Forgetting leaves the next
findElementlooking inside the wrong context — confusing failures.Wait for the frame, not just the inner element. Use
ExpectedConditions.frameToBeAvailableAndSwitchTo(...)which polls until the frame loads, then switches in:
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.frameToBeAvailableAndSwitchTo(
By.cssSelector("iframe[data-test=stripe]")
));
- Cross-origin iframes (e.g. payment widgets like Stripe Elements) work fine for Selenium-side switching, because the WebDriver protocol bypasses the same-origin policy.
The interview signal: knowing the iframe boundary exists, knowing all three switching strategies, and using element-based switching as the default.
// EXAMPLE
// Wait for the frame and switch in atomically
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.frameToBeAvailableAndSwitchTo(
By.cssSelector("iframe[data-test=stripe-card]")
));
// Now we're inside the iframe — find elements there
driver.findElement(By.cssSelector("[name=cardnumber]"))
.sendKeys("4242424242424242");
// Always switch back when done
driver.switchTo().defaultContent();
driver.findElement(By.cssSelector("[data-test=submit]")).click();