Native browser dialogs interrupt Selenium page interaction because the active WebDriver command must deal with the dialog before it can return to page elements. Tests around deletion buttons, confirmation prompts, or browser warnings can otherwise fail at the next locator or click.
An explicit alert_is_present() wait returns the Alert object only after the browser exposes the dialog. The test can then read its text and call accept() or dismiss() without racing the JavaScript that opened it.
This approach applies to native alert(), confirm(), and prompt() dialogs. A modal drawn with HTML and CSS remains part of the document, so it needs ordinary locators and element waits instead of the alert API.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Selenium alert demo</title> </head> <body> <button id="delete">Delete test record</button> <p id="state">waiting</p> <script> document.getElementById("delete").addEventListener("click", () => { const accepted = window.confirm("Delete this test record?"); document.getElementById("state").textContent = accepted ? "accepted" : "dismissed"; }); </script> </body> </html>
from pathlib import Path from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait PAGE_URL = Path("alert-demo.html").resolve().as_uri() options = Options() options.add_argument("--headless=new")
from pathlib import Path from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait PAGE_URL = Path("alert-demo.html").resolve().as_uri() options = Options() options.add_argument("--headless=new") def handle_confirmation(): driver = webdriver.Chrome(options=options) try: driver.get(PAGE_URL) driver.find_element(By.ID, "delete").click() alert = WebDriverWait(driver, 5).until(EC.alert_is_present()) message = alert.text assert message == "Delete this test record?" alert.accept() state = driver.find_element(By.ID, "state").text assert state == "accepted" print(f"Alert text: {message}") print("Alert accepted") print(f"Page state: {state}") finally: driver.quit() if __name__ == "__main__": handle_confirmation()
accept() chooses OK, while dismiss() chooses Cancel on a confirmation dialog. A prompt() accepts text through send_keys() before accept().
accept() confirms the browser action. Tests against destructive application flows should use disposable records or another isolated test fixture.
$ python3 selenium-alert-handle.py Alert text: Delete this test record? Alert accepted Page state: accepted