Arik
Arik

Reputation: 71

Try inside finally

I've tested that code. Everthing is ok, including scenarios of incorrect username or password, until it gets to the 'Login Verification' section. There is a problem with the way my try-except-finally is written?

  def Login(userName, userPassword):
        loginURL = baseURL + 'login/'
        feedURL = baseURL + 'feed/'

        logging.info('Opens Login Page')
        driver.get(loginURL)
        sleep(randomTimer)

        try:
            driver.find_element_by_id('username').send_keys(userName)
            driver.find_element_by_id('password').send_keys(userPassword)
            sleep(randomTimer)
            driver.find_element_by_xpath('//button[text()="Sign in"]').click()

        except NoSuchElementException:
            logging.error('Was Not Able To Find The Elements')

        finally:
            # Username or password errors
            if driver.find_element_by_xpath('//div[@id="error-for-username"]') or driver.find_element_by_xpath('//div[@id="error-for-password"]'):
                logging.error('Username or Password Is Incorrect')
            else:
                # Login verification
                try:
                    WebDriverWait(driver, 10).until(driver.current_url == feedURL)
                    logging.info('Logging In Have Succeeded')
                except TimeoutException:
                    logging.error('Logging In Have Failed')

It retuerns the following error:

selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: //div[@id="error-for-username"]

edit:

def Login(userName, userPassword):
    loginURL = baseURL + 'login/'
    feedURL = baseURL + 'feed/'

    logging.info('Opens Login Page')
    driver.get(loginURL)
    sleep(randomTimer)

    try:
        driver.find_element_by_id('username').send_keys(userName)
        driver.find_element_by_id('password').send_keys(userPassword)
        sleep(randomTimer)
        driver.find_element_by_xpath('//button[text()="Sign in"]').click()

    except NoSuchElementException:
        logging.error('Was Not Able To Find The Elements')

    else:
        try:
            if driver.find_elements_by_xpath('//div[@id="error-for-username"]') or driver.find_elements_by_xpath('//div[@id="error-for-password"]'):
                logging.error('Username or Password Is Incorrect')
        except NoSuchElementException:
            pass
        else:
            try:
                WebDriverWait(driver, 10).until(ec.url_to_be(feedURL))
                logging.info('Logging In Have Succeeded')
            except TimeoutException:
                logging.error('Logging In Have Failed')

    finally:
        logging.info('Quiting The Driver')
        driver.quit()

Upvotes: 1

Views: 1014

Answers (2)

Y.Berrama
Y.Berrama

Reputation: 101

The finally is always executed so when the login succeed it will try to get the div with the id "error-for-username" and fail.

Instead you can split the login process into 2 parts and cover all the script with a try..catch :

  1. First part : The login process
  2. Second part : Test if the login succeed (Here it's recommanded to stop the execution of your script if the login failed)

The final code will look like something like this :

    try
        def Login(userName, userPassword):
            loginURL = baseURL + 'login/'
            feedURL = baseURL + 'feed/'

            logging.info('Opens Login Page')
            driver.get(loginURL)
            sleep(randomTimer)

            try:
                driver.find_element_by_id('username').send_keys(userName)
                driver.find_element_by_id('password').send_keys(userPassword)
                sleep(randomTimer)
                driver.find_element_by_xpath('//button[text()="Sign in"]').click()

            except NoSuchElementException:
                logging.error('Was Not Able To Find The Elements')
                # Quit the script
                driver.quit()
                sys.exit()


            try:
            # Username or password errors
                if driver.find_element_by_xpath('//div[@id="error-for-username"]') or driver.find_element_by_xpath('//div[@id="error-for-password"]'):
                    logging.error('Username or Password Is Incorrect')
                    # Quit the script
                    driver.quit()
                    sys.exit()
            except NoSuchElementException:
                #This mean that the login was sucessful
                pass

            WebDriverWait(driver, 10).until(driver.current_url == feedURL)
            logging.info('Logging In Have Succeeded')

    except Exception as e:

        logging.error('An error occured: ' + str(e))
        driver.quit()
        sys.exit()

Upvotes: 0

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

Your use of try/finally is actually wrong. The code in the finally block is always executed (that's the point of this statement), but in your case if the code in the first try block raises a NoSuchElementException, you do not want to proceed further - it just doesn't make sense.

Upvotes: 2

Related Questions