Why does this block of code functions as so?

35 Views Asked by At

Most of the main code

            driver.get(url)
            usernameelem = driver.find_element(By.XPATH,usernameId) 
            usernameelem.send_keys(username) 
            passwordelem = driver.find_element(By.XPATH,passwordId)
            passwordelem.send_keys(password)
            passwordelem.send_keys(Keys.ENTER)
            try:
                submitbut = driver.find_element(By.XPATH,submit_buttonId)
                submitbut.click()
            except:
                submitbut1 = driver.find_element(By.XPATH,submit_buttonId)
                submitbut1.send_keys(Keys.ENTER) 
            time.sleep(5)

The code am not so sure about:

            try:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click()
            except:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.send_keys(Keys.ENTER) 

This is the only block of code that works, when i try to make it click on the submit button

Any other method such as

                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.send_keys(Keys.ENTER) 

trying to anticipate the error.. or

            try:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click()
            except:
                submit = driver.find_element(By.XPATH,submit_buttonId)
                submit.click() 

literally the same thing but clicking

Doesn't work and will always gives "selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found"

Am not sure how and why its only workable in such a specific order, the submit button is always visible too, and clickable if manual

1

There are 1 best solutions below

3
JeffC On BEST ANSWER

Without seeing the page it's hard to know for sure but it sounds like the page is loaded and then at least a portion of the page is reloaded. This creates the StaleElementException. The stale element is in submit... you've grabbed the element reference from the page and stuffed it into submit. The page then reloads so that submit is no longer pointing at anything (it's reference is stale). The only fix for this is to get the reference again... that's why you're having to call the same line twice, the first time inside a try.

The way to avoid this is to

  1. wait for the element to be present
  2. wait for it to become stale
  3. wait for it to be clickable
  4. click it

It sounds like a lot of work but this procedure should remove a lot of the intermittent (and deterministic) failures in these steps. The code would look like

wait = WebDriverWait(driver, 10)
# define the locator since we're going to use it more than once
submit_locator = (By.XPATH, submit_buttonId)
# wait for the page to load enough that the element exists
submit = wait.until(EC.presence_of_element_located(submit_locator))
# wait for the element to go stale
wait.until(EC.staleness_of(submit))
# now that it's gone stale, now we wait for it to be clickable and click it
wait.until(EC.element_to_be_clickable(submit_locator)).click()