I'm working on a piece of code to automate a login process. The process consists of filling in a username on the first page, clicking a button and proceeding to a second page where I'll fill in pw and press on a second button. The webpage sees a lot of traffic at times and gives a "Try again later..." message after clicking on the first page. To take care of this, I've put in a loop to keep clicking until we move to the next page.
Once I get through to the next page, I'm still in the while loop. However, I was expecting that looking for "Try again later" message would yield a NoSuchElementException and consequently break the loop, but I'm getting a StaleElementReferenceException. I understand that, because I moved on to another page, this "Try again later" element is not in the DOM anymore.
Why is a StaleElementReferenceException raised instead of a NoSuchElementException? If the traffic on the webpage is low, no "Try again later" message is ever generated and the except NoSuchElementException breaks the loop. As soon as the message shows up once, StaleElement. Does Selenium keep track of the references of elements even if we don't store them in a variable? If so, how do we delete it?
I originally tried the except StaleElementReferenceException: to catch this exception. But nothing happens. The code finally clicks through to the next page, but keeps on running the loop, breaking on StaleElementReferenceException (line 4). How do I catch this exception? I've looked through I think all of the related questions, but didn't find a working answer.
EDIT 1
I've know found different examples here on SO where people use except StaleElementReferenceException:
However, It's not working in my code below. The code keeps looping until it manages to pass to the next page, but then breaks on the stale element exception.
while True:
try:
#looking for "try again later" message
WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, "//[@id='uiview']/ui-view/div/div[1]/div[1]/ui-view/div/div[2]/div/div[2]/form/div[3]/p")))
#if it finds the element it clicks the login button.
login_butn_1.click()
print("clicked")
#if logging in works; no "try again later" element, so we can break the loop
except NoSuchElementException:
print("no such element")
break
#Sometimes loading time is too long for "try again later"... message too appear and locating that element times out
#Need to reselect the button to be able to click it
except TimeoutException:
webdriver.ActionChains(self.driver).move_to_element(login_butn_1).click(login_butn_1).perform()
print("time out")
except StaleElementReferenceException:
print("stale element exception")
break