Browser alerts pause Selenium tests because WebDriver cannot keep clicking or reading the page until the modal dialog is handled. A destructive-button test, confirmation prompt, or login warning can fail when the script tries to inspect the page while the alert still owns the browser focus.

Selenium exposes JavaScript alerts, confirmation dialogs, and prompt dialogs through an Alert object after the driver switches context. Waiting for the alert before reading it prevents a race between the click that opens the dialog and the browser creating the modal.

Use this flow for native browser dialogs created by alert(), confirm(), or prompt(). HTML modal components remain normal page elements, so handle those with locators and waits instead of switch_to.alert.

Steps to handle browser alerts with Selenium:

  1. Create a local alert demo script.
    $ cat > selenium-alert-handle.py <<'PY'
    from pathlib import Path
    from tempfile import TemporaryDirectory
    
    from selenium import webdriver
    from selenium.webdriver.chrome.options import Options
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    
    
    HTML = """<!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Selenium alert demo</title>
      </head>
      <body>
        <button id="delete" onclick="if (confirm('Delete this test record?')) {
          document.getElementById('state').textContent = 'accepted';
        } else {
          document.getElementById('state').textContent = 'dismissed';
        }">Delete test record</button>
        <p id="state">waiting</p>
      </body>
    </html>
    """
    
    
    options = Options()
    options.add_argument("--headless=new")
    
    with TemporaryDirectory() as tmpdir:
        page = Path(tmpdir) / "alert-demo.html"
        page.write_text(HTML, encoding="utf-8")
    
        driver = webdriver.Chrome(options=options)
        try:
            driver.get(page.as_uri())
            driver.find_element(By.ID, "delete").click()
    
            wait = WebDriverWait(driver, 5)
            alert = wait.until(lambda d: d.switch_to.alert)
            message = alert.text
            alert.accept()
    
            state = driver.find_element(By.ID, "state").text
            assert message == "Delete this test record?"
            assert state == "accepted"
    
            print(f"Alert text: {message}")
            print("Alert accepted")
            print(f"Page state: {state}")
        finally:
            driver.quit()
    PY

    The demo uses a local file and a headless Chrome session so the alert behavior can be tested without touching a real application.

  2. Run the script to confirm Selenium reads and accepts the alert.
    $ python3 selenium-alert-handle.py
    Alert text: Delete this test record?
    Alert accepted
    Page state: accepted
  3. Use dismiss() when the test should choose the cancel path.
    alert = wait.until(lambda d: d.switch_to.alert)
    message = alert.text
    alert.dismiss()

    Use accept() for OK or confirm actions, and dismiss() for Cancel on confirmation dialogs.

  4. Type into prompt dialogs before accepting them.
    alert = wait.until(lambda d: d.switch_to.alert)
    alert.send_keys("Selenium")
    message = alert.text
    alert.accept()
  5. Keep the alert wait directly after the action that opens the dialog in the real test.
    driver.find_element(By.CSS_SELECTOR, "button.delete").click()
    alert = wait.until(lambda d: d.switch_to.alert)
    assert alert.text == "Delete this record?"
    alert.accept()

    If a native alert is still open, normal element lookups and clicks can fail until accept() or dismiss() closes it.

  6. Remove the demo script if it was only used to verify the alert flow.
    $ rm selenium-alert-handle.py