Search code examples
python-3.xif-statementselenium-webdrivertry-except

Using if/else under a try method to login, however a successful login throws exception


Here is the snippet of the code I think is having a loop bug. I have been successful in having it retry upon failure or blank entry. But once it logs in, it still keeps trying to login. Could someone take a look?

print(f"The stripped captcha text is: {result}")
time.sleep(1)
if result:
    try:
        driver.find_element(By.XPATH,"//div[@id='app']//div[contains(@class, 'el-input')]//input[@name='captcha']").send_keys(result)
        driver.find_element(By.XPATH,"//div[@id='app']//button[contains(@type,'button')]").click()
        print("Captcha has been entered")
        time.sleep(2)
        login_button = driver.find_element(By.XPATH,"//div[@id='app']//form[@class= 'el-form login-form el-form--label-left']//button[contains(@type,'button')]")
        if login_button:
            #try again by page refresh
            print("Captcha was entered but was wrong, trying again...")
            driver.refresh()
            login_attempt()
        else:
            print("The login attempt worked!")
    except:
        print("Seems to me that you are already logged in, but I will keep repeating this until you solve this loop")
        time.sleep(2)
        login_button = driver.find_element(By.XPATH,"//div[@id='app']//form[@class= 'el-form login-form el-form--label-left']//button[contains(@type,'button')]")
        if login_button:
            #try again by page refresh
            print("Even after being logged in, trying again...this is not right.")
            driver.refresh()
            login_attempt()
        else:
            print("The login attempt may have worked!")
else:
    print("The captcha result was maybe blank.")
    time.sleep(2)
    if login_button:
        #try again by page refresh
        driver.refresh()
        time.sleep(2)
        login_attempt()
    else:
        print("The login attempt worked!")

Sample Output:

Login button was found and variable has been recorded
Login attempt was called by your code
Username and Password were entered
The stripped captcha text is: vyiw4
Captcha has been entered
Captcha was entered but was wrong, trying again...
Login attempt was called by your code
Username and Password were entered
The stripped captcha text is: fhxax
Captcha has been entered
Seems to me that you are already logged in, but I will keep repeating this until you solve this loop
Seems to me that you are already logged in, but I will keep repeating this until you solve this loop

I tried to implement a re-attempt at failure logic, but failed to implement a successful scenario logic. I have no clue how to avoid the code to keep retrying, it is almost as if it skips the below else condition:

else:
    print("The login attempt worked!")

Solution

  • I added a comment but figured I'd add a response to be more clear. I'm assuming this is selenium- if so you should tag it as such. The other assumption I am making is that the login button is not present after a successful login.

    The main issue I see is that you are not handling the element not being present and assuming login_button will always be True/False, but in reality it will throw a NoSuchElementException. Also, it appears that your retry logic is too circular.

    In your example:

    • If captcha is found: try logging in
    • If captcha is not found: try logging in
    • If login appears to be successful: try logging in

    In what scenario would it stop attempting to login?

    Try something like this:

    from selenium.common.exceptions import NoSuchElementException
    
    print(f"The stripped captcha text is: {result}")
    time.sleep(1)
    if result:
        driver.find_element(By.XPATH,"//div[@id='app']//div[contains(@class, 'el-input')]//input[@name='captcha']").send_keys(result)
        driver.find_element(By.XPATH,"//div[@id='app']//button[contains(@type,'button')]").click()
        print("Captcha has been entered")
        time.sleep(2)
        try:
            login_button = driver.find_element(By.XPATH,"//div[@id='app']//form[@class= 'el-form login-form el-form--label-left']//button[contains(@type,'button')]")
            if login_button:
                #try again by page refresh
                print("Captcha was entered but was wrong, trying again...")
                driver.refresh()
                login_attempt()
        except NoSuchElementException:
            print("The login attempt worked!")
    else:
        #further check login status or assume user is already logged in
    

    Also, instead of waiting a fixed 2s you could also utilize selenium's WebDriverWait:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    wait = WebDriverWait(driver, 10)  #10s timeout
    wait.until(EC.visibility_of_element_located((By.XPATH, "XPATH STRING")))
    #continue code