How to handle browser alerts with Selenium

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.

Steps to handle browser alerts with Selenium:

  1. Create alert-demo.html with a confirmation dialog and a visible result state.
    alert-demo.html
    <!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>
  2. Start selenium-alert-handle.py with the imports, local page URL, and headless browser options.
    selenium-alert-handle.py
    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")
  3. Complete selenium-alert-handle.py with the confirmation action and fail-capable assertions.
    selenium-alert-handle.py
    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.

  4. Run the completed script from the directory that contains both files.
    $ python3 selenium-alert-handle.py
    Alert text: Delete this test record?
    Alert accepted
    Page state: accepted