Reputation: 115
Please Help!! I want to click on all main menu links for this i have written following code:
html_list = self.driver.find_element_by_xpath("//*[@id='main-navigation']/ul")
items = html_list.find_elements_by_tag_name("li")
for item in items:
item.click()
time.sleep(20)
but it clicked on first menu option Brands and then it failed and gave following error:
exception_class = ErrorInResponseException
if status in ErrorCode.NO_SUCH_ELEMENT:
exception_class = NoSuchElementException
elif status in ErrorCode.NO_SUCH_FRAME:
exception_class = NoSuchFrameException
elif status in ErrorCode.NO_SUCH_WINDOW:
exception_class = NoSuchWindowException
elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
exception_class = StaleElementReferenceException
elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
exception_class = ElementNotVisibleException
elif status in ErrorCode.INVALID_ELEMENT_STATE:
exception_class = InvalidElementStateException
E selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
I am attaching screenshot of the webpage on which I am performing this action.
Upvotes: 1
Views: 96
Reputation: 19979
html_list = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, "//*[@id = 'main-navigation']//li[.//a[not(@data-webtrekk-link-id='header.subnav')]]")))
for i in range(len(html_list)):
time.sleep(3)
html_list = WebDriverWait(driver, 10).until(
EC.presence_of_all_elements_located((By.XPATH, "//*[@id = 'main-navigation']//li[.//a[not(@data-webtrekk-link-id='header.subnav')]]")))
html_list[i].click()
there are many invisible elements , you should use the xpath locator as mentioned to find the element uniquely.
we are using time.sleep because presenceofallelement doesn't wait for all elements but for only first element
Difference between presenceOfElementLocated() and presenceOfAllElementsLocatedBy() is Selenium
Upvotes: 1
Reputation: 287
When you click on element from items, it changes in DOM making it impossible to continue to iterate through items because of StaleElementReference. Inspect elements to see how the structure changes.
I would suggest iterating by index instead of elements
html_list = self.driver.find_element_by_xpath("//*[@id='main-navigation']/ul")
items = html_list.find_elements_by_tag_name("li")
for i, _j in enumerate(items, start=1):
self.driver.find_element_by_xpath("(//*[@id='main-navigation']/ul/li)[{}]".format(i))
time.sleep(20)
Upvotes: 1