Selenium appears to be ignoring waits and running over itself
I'm using Selenium with Python (Chrome driver) to iterate through a list of terms, search them on my site, and grab some text.
However, I'm finding that the script is not properly waiting, and is entering terms before the previous search has had time to process, leading to a bunch of terms being pasted at once. I doubt the issue is selenium being broken, and is more likely just my misunderstanding, but I've tried every type of wait I could think of that would help.
Here is the code that handles the selenium stuff. There is another function that initializes the Chrome driver and then just calls the function below for each term.
def searchTerm(driver, term): # searching term argument on the page, returns specific text
wait = WebDriverWait(driver, 10)
try:
element = wait.until(EC.presence_of_element_located((By.ID, "search-box"))) # wait until element is present in page (not necessarily visible)
element.clear() #clear any pre-existing text
element.send_keys(term) #send string arugment term into search box
wait.until(EC.text_to_be_present_in_element_value((By.ID, "search-box"), term)) #double check term is actually in search box
element.send_keys(Keys.ENTER) #press enter to search
wait.until(EC.text_to_be_present_in_element_value((By.ID, "search-box"), "")) #on this site, search box contents are emptied when search is performed. check box is empty as means of verifying page has loaded. this probably isn't necessary
element = wait.until(EC.presence_of_element_located((By.XPATH,"//*[@class='target-text-class']",))) #verify the text we want is present
return element.text #return the text
except Exception as er:
print(er)
return "ERROR"`
It often throws a StaleReferenceException on the send_keys(term), which confused me as the lines before it that verify the element is present do not throw any error. I've tried removing some portion of the wait and tried adding more, but the result is the same.
A
StaleReferenceExceptionhappens when the element changes between the time it was found, and the next time you try to interact with, or read a value from, it. I always recommend finding the element right before interacting with it. In this situation, that would bedriver.find_element(By.ID, "search-box").send_keys(term)