I am getting the following error while using Selenium in python:
selenium.common.exceptions.StaleElementReferenceException: Message: u\'stale element referen
Beyond the answers here, if you are using ActionChains, and the page has changed, be sure to reinstantiate your ActionChains object (dont reuse an old one), otherwise your ActionChain will be using a stale DOM. I.e. do this;
action_chain = ActionChains(driver)
action_chain.double_click(driver.find_element_by_xpath("//tr[2]/p")).perform()
Or better yet dont use an instantiation;
ActionChains(driver).double_click(driver.find_element_by_xpath("//tr[2]/p")).perform()
This is the python solution for this problem:
def clickAndCatchStaleRefException(locator):
driver = sel2._current_browser()
result = False
attempts = 0
locator = locator[6:]
# This line is optional because sometimes you pass a xpath from a varibles file
# that starts with 'xpath='. This should be omitted otherwise the find_element_by_xpath
# function will throw an error.
# But if you pass an xpath directly you don't need this
while attempts < 2:
try:
driver.find_element_by_xpath(locator).click()
result = True
break
except EC as e:
raise e
finally:
attempts += 1
return result
When webpage got refreshed or switched back from different window or form and trying to access an element user will get staleelementexception.
Use webdriverwait in try --except block with for loop: EX :
driver.find_element_by_id(tc.value).click()
Fix :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.find_element_by_id(tc.value).click()
for i in range(4):
try:
run_test = WebDriverWait(driver, 120).until( \
EC.presence_of_element_located((By.XPATH, "xpath")))
run_test.click()
break
except StaleElementReferenceException as e:
raise e
It means the element is no longer in the DOM, or it changed.
The following code will help you find the element by controlling and ignoring StaleElementExceptions and handling them just like any other NoSuchElementException. It waits for the element to NOT be stale, just like it waits for the element to be present. It also serves as a good example on how to properly wait for conditions in Selenium.
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
my_element_id = 'something123'
ignored_exceptions=(NoSuchElementException,StaleElementReferenceException,)
your_element = WebDriverWait(your_driver, some_timeout,ignored_exceptions=ignored_exceptions)\
.until(expected_conditions.presence_of_element_located((By.ID, my_element_id)))
To better understand the problem, imagine you are inside a for loop and think what happens during the iterations:
I Would like to add one more solution here which is worked for me.
I was trying to access the button in the top menu panel on my webpage after refreshing the content area on the same page, Which gave me the following error,
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <span id="dk1-combobox" class="dk-selected combinationText visibleElements "> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
Then I started to search for the solution to click the stale element on the web page. After two days of thinking and googling, I got a solution.
To access the stale element on the page, first, we need to focus the mouse over the particular section and perform click option
EditReport1 = driver.find_element_by_id('internalTab1')
ActionChains(driver).move_to_element(EditReport1).click(EditReport1).perform()
move_to_element will move the mouse over the stale element which we need to access once we got our control on the element the click operation is successfully performed.
This is worked for me. If anyone finds it working please comment your's as well which will help some other in future.
Thank you
For my python scripts, on quite simple pages, all above mentioned solutions didn't work. I found here -> https://www.softwaretestingmaterial.com/stale-element-reference-exception-selenium-webdriver/ the simplest way for my problem. It's just refreshing before clicking.
driver.refresh()
driver.find_element_by_id('normal').click()
Note: I'm using driver.implicitly_wait(5)
instead of explicit waits but it works in both options.