问题
So I'm getting this error every so often when running the exact same test.
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
(Session info: chrome=69.0.3497.100)
(Driver info: chromedriver=2.41.578706 (5f725d1b4f0a4acbf5259df887244095596231db),platform=Mac OS X 10.12.6 x86_64)
The only problem is that it seems to happen inconsistently to different areas of the code. It's when trying to access DOM elements, like a search field, of my ReactJS page. I'm running this through ROBOT Automation Framework, using a mix of the SeleniumLibrary and a custom library.
I've read that it's simply as it sounds, the xPath as become outdated on the DOM, but that doesn't help me figure out why it's an inconsistent error happening almost anywhere at any point.
EDIT: It seems to be happening in this:
def filter_modality(self, filter):
filter_value = '//span[@title="{}"]//parent::li'.format(filter)
self.selib.click_element(filter_locator)
self.selib.wait_until_page_contains_element('//*[@class="multi-selector-options open"]')
self.selib.wait_until_element_is_visible(filter_value)
self.selib.click_element(filter_value )
self.selib.wait_until_page_contains_element('//div...[@class="option selector-item active"]',
error=("Could not select filter: {}".format(filter_value )))
#I get the stale element message from or after executing this click_element
self.selib.click_element(filter_locator)
self.selib.wait_until_page_does_not_contain_element('//*[@class="multi-selector-options open"]',
error="Filter dropdown did not disappear after selection")
回答1:
The exception comes when SE has found an element, but shortly afterwards something (a JS function) has changed it - removed from/rearranged it in the DOM, or changed its attributes significantly, so it's no longer tracked as the same element.
This comes for the fact that SE builds an internal cache of the DOM, which may become desynchronized from the actual one; thus the name "stale" - the el. is cached in some state, but its actual form is now different.
The issue is that common, that there is a specific SO tag for it - https://stackoverflow.com/questions/tagged/staleelementreferenceexception (I myself was surprised from this).
The common solutions are:
- sleep for some seconds before an event you know will cause the issue
- re-get an element before its usage (if you store a reference to it in a
WebElement
object, not really the case with robotframework) - have a rertry mechanism on working with an element that you know may cause the execution
- swallow the exception and move along (I've done it in a few places, where the element was just a confirmation an operation was executed - it has been shown/found by SE once, afterwards I don't care is it changed in the DOM)
来源:https://stackoverflow.com/questions/52857478/selenium-python-script-invalidelementstateexception