pythonseleniumerror-handlingwaitstaleelementreferenceexception

How to get around the StaleElementReferenceException with ignored_exceptions?


So I am having a little difficulty with selenium automated testing.

I have a "next" button to click after filling in some fields, however, I get a "selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document"

I have tried an explicit wait, ignoring this exception, however, it doesn't work.

from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException

ignored_exceptions=(NoSuchElementException,StaleElementReferenceException)
your_element = WebDriverWait(driver, 30, ignored_exceptions=ignored_exceptions).until(expected_conditions.presence_of_element_located((By.ID, 'c8')))

driver.find_element(By.ID, 'c8').click()

This doesn't work. It keeps throwing the error!

BUT!

If I add a time.sleep(0.5), then it will click the button.

from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException

time.sleep(0.5)
driver.find_element(By.ID, 'c8').click()

Now I know its bad practice to use time.sleep(), and I of course do want to use explicit waits for this, however, it's just not working for me.

I also tried an implicit wait, however, this literally just waits for the entire time that I set it to wait for, and then the next button can be clicked. I want to rather have the next button clicked as soon as it is able to be clicked.

Can anyone assist me here?


Solution

  • To locate the clickable element instead of presence_of_element_located() you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following locator strategy:

    from selenium.common.exceptions import NoSuchElementException
    from selenium.common.exceptions import StaleElementReferenceException
    
    ignored_exceptions=(NoSuchElementException,StaleElementReferenceException)
    your_element = WebDriverWait(driver, 30, ignored_exceptions=ignored_exceptions).until(expected_conditions.element_to_be_clickable((By.ID, 'c8')))
    
    driver.find_element(By.ID, 'c8').click()