pythonpython-3.xselenium-webdriverweb-scrapingselenium-firefoxdriver

How to handle alert prompts in Selenium Python?


I have tried to use Selenium with Python. The script is to get a file from a website over a for loop. The input is provided from an Excel file, which is read and the variables are then passed on to test_getcaf, which then performs the data search function. The following is my Python script.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common import exceptions
from selenium.webdriver.common.alert import Alert
import openpyxl

options = Options()
options.set_preference("browser.download.folderList", 2)
options.set_preference("browser.download.manager.showWhenStarting", False)
options.set_preference("browser.download.dir", "D:\\Path\\Script")
options.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/x-gzip")
driver = webdriver.Firefox(options=options)

def test_getcaf(number, ptype):
    number = str(number)
    ptype = str(ptype)
    driver.switch_to.default_content()
    driver.implicitly_wait(1)
    driver.switch_to.frame("bodyframe")    # switch to selected iframe
    textbox_MobileNo = driver.find_element(by=By.ID, value="txtMobileNo")
    textbox_ptype = driver.find_element(by=By.ID, value="ptype")
    textbox_MobileNo.send_keys(number)
    textbox_ptype.send_keys(ptype)

    try:
        search_button = driver.find_element(By.ID, value="mainTable")
        search_button.click()     #This click can or cannot generate an alter box
        show_button = driver.find_element(By.CSS_SELECTOR, "table#deletelink tbody tr td.view_icon")
        show_button.click()

        return True
    except exceptions.UnexpectedAlertPresentException:
        driver.switch_to.alert.accept()
        return False


wb_obj = openpyxl.load_workbook("D:\\Path\\Book1.xlsx")
sheet_obj = wb_obj.active
row = sheet_obj.max_row+1
column = sheet_obj.max_column+1
# Passing the value to the function
for i in range(2, row):
    Mob_num = sheet_obj.cell(row=i, column=1).value
    Mob_type = sheet_obj.cell(row=i, column=2).value
    Return_messag = test_getcaf(Mob_num,Mob_type)
    sheet_obj.cell(row=i, column=3).value = Return_messag
    wb_obj.save("D:\\Path\\Book1.xlsx")

In the above code, the second line in the try block, when clicked may generate another block or can generate an Alert box. This is a simple Alert box with only "OK" option. But when running the script I am getting errors as selenium.common.exceptions.NoAlertPresentException: Message The following is the error message

selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: None
Message: Dismissed user prompt dialog: Customer details not found with the specified search
Stacktrace:
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:187:5
UnexpectedAlertOpenError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:704:5
GeckoDriver.prototype._handleUserPrompts@chrome://remote/content/marionette/driver.sys.mjs:2832:13


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\Search CAF\CCMS\test_fire.py", line 110, in <module>
    Return_messag = test_getcaf(Mob_num,Mob_type)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "D:\Search CAF\CCMS\test_fire.py", line 74, in test_getcaf
    driver.switch_to.alert.accept()
    ^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\switch_to.py", line 55, in alert
    _ = alert.text
        ^^^^^^^^^^
  File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\common\alert.py", line 59, in text
    return self.driver.execute(Command.W3C_GET_ALERT_TEXT)["value"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 346, in execute
    self.error_handler.check_response(response)
  File "C:\Users\JTOITWB\AppData\Local\Programs\Python\Python311\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 245, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoAlertPresentException: Message: 
Stacktrace:
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:187:5
NoSuchAlertError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:489:5
GeckoDriver.prototype._checkIfAlertIsPresent@chrome://remote/content/marionette/driver.sys.mjs:2803:11
GeckoDriver.prototype.getTextFromDialog@chrome://remote/content/marionette/driver.sys.mjs:2751:8
despatch@chrome://remote/content/marionette/server.sys.mjs:320:40
execute@chrome://remote/content/marionette/server.sys.mjs:291:16
onPacket/<@chrome://remote/content/marionette/server.sys.mjs:264:20
onPacket@chrome://remote/content/marionette/server.sys.mjs:265:9
_onJSONObjectReady/<@chrome://remote/content/marionette/transport.sys.mjs:496:20

I have tried with else and finally options also, but in that, the for loop calling test_getcaf function just jumps the try block and only the else or finally option is called.

I have even tried if driver.switch_to.alert: Also, but that's also not working.

Can anybody tell me what am I doing wrong here?

Screenshot 1 Schreetshot 2


Solution

  • So, well, your case is tricky as far as it needs several "dirty" workarounds.

    Actually, this flow need to be split to 4 cases as far as your resource buggy itself with that alerts.

    So, first of all, Firefox didn't have option that allows such type of alerts, so it couldn't properly handle them. Then, after several seconds after clicking alert, part of buttons are become unresponsive.

    Also, alert is buggy - sometimes is disappears without click, and sometimes - with.

    But if it is not part of coverage, this code would make it work

    #code before
    options.set_preference("dom.disable_beforeunload", True)
    driver = webdriver.Firefox(options=options)
    wait = WebDriverWait(driver, 4)
    
    #another code
    
    def handle_exceptions():
        status = "Cannot be Downloaded"
        try:
            driver.switch_to.default_content()
            driver.switch_to.alert.accept()
            wait.until_not(EC.alert_is_present())
        except exceptions.NoAlertPresentException:
            pass
        return status
    
    def test_getcaf(number, ptype):
        number = str(number)
        ptype = str(ptype)
        driver.switch_to.default_content()
        driver.implicitly_wait(1)
        
        driver.switch_to.frame("bodyframe") 
        textbox_MobileNo = driver.find_element(by=By.ID, value="txtMobileNo")
        textbox_ptype = driver.find_element(by=By.ID, value="ptype")
        textbox_ptype = wait.until(EC.element_to_be_clickable(textbox_ptype))
        textbox_ptype.send_keys(ptype)
        textbox_MobileNo.clear()
        textbox_MobileNo.send_keys(number)
    
        try:
            search_button = driver.find_element(By.ID, value="mainTable")
            search_button.click()
            try:
                wait.until(EC.alert_is_present())
            except exceptions.WebDriverException:
                pass
            show_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "table#deletelink tbody tr td.view_icon")))
            show_button.click()
    
            show_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "table#downloadCafId.btn_latest tbody tr td")))
            show_button.click()
            back_button = driver.find_element(By.CSS_SELECTOR, "table#backbtn.btn_latest tbody tr td")
            back_button.click()
            return "Downloaded"
        except exceptions.UnexpectedAlertPresentException:
            return handle_exceptions()