1

I am trying to click a button, but from time to time, I get an Stale element exception:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

even though I use an element_to_be_clickable expected condition to find the element in the DOM. The element is found as my script continues within the else statement, but when I try to click the button - BAM, the element is not attached to the page document. What the hell, selenium?!?!!?

The element I am trying to find is in a page which is newly loaded, i.e. the previous action in the script is the clicking of a button, which then redirects to the page where I am having the described problem.

I am getting the feeling that selenium for python is trash. Else, what am I doing wrong, ffs? An important note, I DO NOT want to introduce any implicit waits such as time.sleep or implicitly_wait! I want my code more flexible than that.

I find the element with the element_to_be_clickable expected condition, but when I try to click it, selenium (sometimes) crashes saying that the element is actually not attached to the DOM. ?! It happens mostly in Google Chrome!

try: casesButton = WebDriverWait(driver,4).until(expc.element_to_be_clickable((By.XPATH, "//i[@class='far fa-flag']")))
except (TimeoutException, ElementNotVisibleException, NoSuchElementException): result = 0; reason = "Cases button not found"
else: casesButton.click()

Crash message:

casesButton.click()
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webelement.py", line 80, in click
self._execute(Command.CLICK_ELEMENT)
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webelement.py", line 633, in _execute
return self._parent.execute(command, params)
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/usr/local/lib/python3.6/dist-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=70.0.3538.77)
(Driver info: chromedriver=2.35.528139 (47ead77cb35ad2a9a83248b292151462a66cd881),platform=Linux 4.15.0-36-generic x86_64)

I expect to be able to click the button, considering that my code enters the else statement.

comvol
  • 11
  • 2

1 Answers1

1

Stale Element means an old element or no longer available element. If the DOM changes then the WebElement goes stale. If we try to interact with an element which is staled then the StaleElementReferenceException is thrown.

Try to use the Fluent Wait, it will help you in avoiding some exceptions such as StaleElementReferenceExcetion, NoSuchElementException etc.,

Try the below code:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import *

# Some driver initialization code goes here
xpath = "//i[@class='far fa-flag']"    
wait = WebDriverWait(driver, 60, poll_frequency=1, ignored_exceptions=[StaleElementReferenceException])
element = wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))
element.click()

If you want to avoid some other exceptions then add that in ignored_exceptions like below:

ignored_exceptions=[StaleElementReferenceException, NoSuchElementException]

I hope it helps...

Ali
  • 1,689
  • 1
  • 5
  • 12