Handling JavaScript Alerts, Confirms and Prompts in Selenium

๐Ÿ“‹ Table of Contents โ–พ
  1. JavaScript Alerts, Confirms and Prompts
  2. Common Mistakes

Browser-native alert, confirm and prompt dialogs are not part of the DOM โ€” they are operating-system-level popups that Selenium cannot interact with using normal find_element calls. When an alert appears, Selenium must switch to it using driver.switch_to.alert before it can read the text, accept it, dismiss it, or type into it. If your test does not handle the alert, every subsequent Selenium command will throw UnexpectedAlertPresentException because the alert blocks all interaction with the page.

JavaScript Alerts, Confirms and Prompts

There are three types of browser-native dialogs, each requiring slightly different handling.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# driver = webdriver.Chrome()

# โ”€โ”€ Three types of JavaScript dialogs โ”€โ”€

DIALOG_TYPES = {
    "alert()": {
        "js_code": "alert('File saved successfully!')",
        "buttons": "OK only",
        "input_field": False,
        "handling": [
            "alert = driver.switch_to.alert",
            "text = alert.text           # Read: 'File saved successfully!'",
            "alert.accept()              # Click OK",
        ],
    },
    "confirm()": {
        "js_code": "confirm('Are you sure you want to delete?')",
        "buttons": "OK and Cancel",
        "input_field": False,
        "handling": [
            "alert = driver.switch_to.alert",
            "text = alert.text           # Read: 'Are you sure you want to delete?'",
            "alert.accept()              # Click OK (confirm)",
            "# OR",
            "alert.dismiss()             # Click Cancel (reject)",
        ],
    },
    "prompt()": {
        "js_code": "prompt('Enter your name:')",
        "buttons": "OK and Cancel",
        "input_field": True,
        "handling": [
            "alert = driver.switch_to.alert",
            "text = alert.text           # Read: 'Enter your name:'",
            "alert.send_keys('Alice')    # Type into the prompt",
            "alert.accept()              # Click OK (submit)",
            "# OR",
            "alert.dismiss()             # Click Cancel (reject, input ignored)",
        ],
    },
}


# โ”€โ”€ Complete example: handle a confirm dialog โ”€โ”€
def handle_delete_confirmation(driver):
    # Click the delete button that triggers a confirm dialog
    delete_btn = driver.find_element(By.CSS_SELECTOR, "[data-testid='delete-btn']")
    delete_btn.click()

    # Wait for the alert to appear
    WebDriverWait(driver, 5).until(EC.alert_is_present())

    # Switch to the alert
    alert = driver.switch_to.alert

    # Read the alert text
    alert_text = alert.text
    print(f"Alert says: {alert_text}")
    assert "are you sure" in alert_text.lower()

    # Accept the confirmation (click OK)
    alert.accept()

    # After accepting, we are back to the main page
    # Verify the item was deleted
    WebDriverWait(driver, 5).until(
        EC.invisibility_of_element_located((By.CSS_SELECTOR, "[data-testid='item-row']"))
    )


# โ”€โ”€ Handle an unexpected alert โ”€โ”€
def dismiss_any_alert(driver):
    try:
        alert = driver.switch_to.alert
        print(f"Unexpected alert: {alert.text}")
        alert.dismiss()
    except Exception:
        pass  # No alert present โ€” continue normally


for dialog, info in DIALOG_TYPES.items():
    print(f"\n{'='*55}")
    print(f"  {dialog}")
    print(f"{'='*55}")
    print(f"  JS:      {info['js_code']}")
    print(f"  Buttons: {info['buttons']}")
    print(f"  Input:   {'Yes' if info['input_field'] else 'No'}")
    print(f"  Handling:")
    for step in info['handling']:
        print(f"    {step}")
Note: Browser-native dialogs (alert, confirm, prompt) created by window.alert(), window.confirm(), and window.prompt() are fundamentally different from HTML modal dialogs created with <div class="modal">. HTML modals are DOM elements โ€” you interact with them using normal find_element and click. Browser-native dialogs exist outside the DOM โ€” you must use driver.switch_to.alert. If you try to use switch_to.alert on an HTML modal, you get NoAlertPresentException. If you try to use find_element on a native alert, the command is blocked by the alert.
Tip: Always use WebDriverWait(driver, 5).until(EC.alert_is_present()) before calling driver.switch_to.alert. Alerts triggered by button clicks may not appear instantly โ€” JavaScript execution, event handlers, and AJAX calls can introduce a delay. Without the wait, switch_to.alert throws NoAlertPresentException if the alert has not yet appeared.
Warning: Modern web applications rarely use browser-native dialogs because they cannot be styled and they block the entire browser tab. Most “alert-looking” popups are actually HTML modal dialogs. Before using switch_to.alert, inspect the dialog in DevTools โ€” if you can find it in the DOM tree, it is an HTML modal and should be handled with normal find_element. If it does not appear in the DOM, it is a native alert and requires switch_to.alert.

Common Mistakes

Mistake 1 โ€” Using switch_to.alert on HTML modals

โŒ Wrong: A Bootstrap or Material UI modal dialog appears and the test calls driver.switch_to.alert โ€” throws NoAlertPresentException.

โœ… Correct: Inspect the dialog โ€” if it is an HTML element in the DOM, use find_element to interact with its buttons. Only use switch_to.alert for browser-native dialogs created by window.alert().

Mistake 2 โ€” Not waiting for the alert before switching

โŒ Wrong: button.click(); alert = driver.switch_to.alert โ€” fails if the alert has not appeared yet.

โœ… Correct: button.click(); WebDriverWait(driver, 5).until(EC.alert_is_present()); alert = driver.switch_to.alert

🧠 Test Yourself

A JavaScript confirm() dialog asks “Delete this item?” and the test needs to click Cancel. Which code is correct?