Alerts, frames and windows
Handle native dialogs, move between frames and back, and track the tab you actually want - plus the stale element error that follows all three.
Native dialogs
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
wait = WebDriverWait(driver, 10)
driver.find_element(By.ID, "delete").click()
alert = wait.until(EC.alert_is_present())
print(alert.text) # readable, not typable
alert.accept() # OK
# a confirm dialog
driver.find_element(By.ID, "discard").click()
wait.until(EC.alert_is_present()).dismiss()
# a prompt: type first, then accept
prompt = wait.until(EC.alert_is_present())
prompt.send_keys("renamed.txt")
prompt.accept()| Method | Behaviour |
|---|---|
accept() | Presses OK |
dismiss() | Presses Cancel, or closes the dialog |
send_keys() | Types into a prompt; invalid on alert and confirm |
text | The dialog's message, read-only |
⚠️
An unhandled dialog blocks every subsequent command and produces
UnexpectedAlertPresentException from an unrelated line. If a test fails with that error, look for a dialog opened by an earlier step rather than at the line the traceback names.Frames and iframes
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
# by element - the most robust route
frame = wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "payment")))
card = driver.find_element(By.NAME, "cardnumber")
card.send_keys("4242424242424242")
# back to the top document
driver.switch_to.default_content()
# index and name also work
driver.switch_to.frame(0)
driver.switch_to.frame("checkout-frame")
driver.switch_to.parent_frame() # one level up, not to the topswitch_to.default_content()leaves every frame;parent_frame()goes up exactly one level.- Switching invalidates nothing directly, but elements found before the switch become stale once the document context changes.
- A payment iframe from a third party is a good reason to make the frame locator a constant - it is the kind of thing that gets renamed without warning.
- Always return to the default content when the frame interaction ends, or the next locator silently searches the wrong document.
Windows and tabs
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
original = driver.current_window_handle
driver.find_element(By.LINK_TEXT, "Open invoice").click()
# wait for the new handle rather than sleeping
WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
new_handle = [h for h in driver.window_handles if h != original][0]
driver.switch_to.window(new_handle)
assert "invoice" in driver.current_url
print(driver.title)
driver.close() # closes the current tab only
driver.switch_to.window(original) # back to the firstdriver.close()closes one window;driver.quit()ends the session and closes all of them.- Handle order is not guaranteed. Identify the window by matching its URL or title, not by its position in the list.
- Opening a tab in the same browser still gives a new handle, so this path is the same for popups and in-page tabs.
- Snapshot
window_handlesbefore the action that opens the new window, so you can tell which one is new.
# a helper worth keeping
def switch_to_new_window(driver, before, timeout=10):
WebDriverWait(driver, timeout).until(
lambda d: len(d.window_handles) > len(before)
)
new = [h for h in driver.window_handles if h not in before][0]
driver.switch_to.window(new)
return newThe stale element error that follows a frame or window switch is not a wait problem. The reference belongs to a document that is no longer current, so waiting longer cannot fix it - re-locate the element after the switch.
FAQ
Why can I not find an element that is clearly on the page?
Check for an iframe first. Locators only search the current document context, so an element inside a frame is invisible until you switch into it. This is the single most common cause of a confident but failing locator.
How do I handle a browser dialog that is not a JavaScript alert?
You cannot. Native dialogs such as a print or file picker are outside the page and outside WebDriver's reach - they need to be avoided by using the underlying API or by disabling the feature via browser options.
Related
Common element interactions Advanced user actions with ActionChains
Last refreshed 2026-09-18.