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()
MethodBehaviour
accept()Presses OK
dismiss()Presses Cancel, or closes the dialog
send_keys()Types into a prompt; invalid on alert and confirm
textThe 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 top
  • switch_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 first
  • driver.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_handles before 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 new

The 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.

Common element interactions Advanced user actions with ActionChains

Last refreshed 2026-09-18.