Selenio de Python: esperar hasta que un elemento ya no esté obsoleto?

Tengo una situación en la que quiero esperar hasta que un elemento ya no sea STALE, es decir, hasta que un elemento se conecte al DOM. Las siguientes opciones de espera no funcionan de alguna manera:

self.wait.until(EC.visibility_of_element_located((By.ID, "elementID"))) self.wait.until(EC.presence_of_element_located((By.ID, "elementID"))) 

Su función de espera opuesta está presente, la cual espera hasta que un elemento se vuelva obsoleto, que es:

 self.wait.until(EC.staleness_of((By.ID, "elementID"))) 

Pero quiero que espere hasta que el elemento ya no esté disponible, es decir, hasta que se conecte al DOM. ¿Cómo puedo lograr esta funcionalidad?

EDITAR: hay una solución aquí: aquí, pero estoy buscando otro enfoque mejor si es que hay alguno.

De la documentación :

Estancamiento de :

 class staleness_of(object): """ Wait until an element is no longer attached to the DOM. element is the element to wait for. returns False if the element is still attached to the DOM, true otherwise. """ def __init__(self, element): self.element = element def __call__(self, ignored): try: # Calling any method forces a staleness check self.element.is_enabled() return False except StaleElementReferenceException: return True 

Elemento para hacer clic :

 class element_to_be_clickable(object): """ An Expectation for checking an element is visible and enabled such that you can click it.""" def __init__(self, locator): self.locator = locator def __call__(self, driver): element = visibility_of_element_located(self.locator)(driver) if element and element.is_enabled(): return element else: return False 

Como puede ver, ambos usan el mismo método is_enabled () para realizar la comprobación.

Un elemento obsoleto es una referencia de elemento que ha almacenado que ya no es válida porque la página, parte de la página, o tal vez solo el elemento se actualizó. Un simple ejemplo

 element = driver.find_element_by_id("elementID") # do something that refreshes the page element.click() 

Aquí element.click() lanzará una excepción de elemento obsoleto porque la referencia se almacenó antes de la actualización pero se usó (hizo clic) después de la actualización. En este caso, esa referencia ya no es válida. Una vez que una referencia está obsoleta, nunca se vuelve “inestable” … esa referencia nunca podrá volver a utilizarse. La única forma de solucionarlo es volver a almacenar la referencia.

NOTA: el ejemplo de código no es correcto para .staleness_of() . Toma una referencia de elemento web, no un localizador. Necesitas una referencia existente para esperar a que se apague. Ver los documentos .

Ahora para resolver el problema … debe esperar a que se complete la actualización y luego obtener una nueva referencia .

 element = driver.find_element_by_id("elementID") # do something that refreshes the element self.wait.until(EC.staleness_of(element)) element = self.wait.until(EC.visibility_of_element_located((By.ID, "elementID"))) # do something with element 

En espera de que el elemento se convierta en obsoleto, espera a que se pierda la referencia del elemento, lo que significa que el elemento ha cambiado / actualizado. Una vez que sepamos que el elemento ha cambiado, ahora podemos obtener una nueva referencia a él. En este caso, esperando que el elemento se haga visible. Ahora tenemos una nueva referencia almacenada en nuestra variable que podemos usar sin excepciones de elementos obsoletos.

 WebDriverWait(browser, waitTime).until(EC.presence_of_element_located( (By.XPATH or By.id or w/e you want, " xpath or id name"))) 

Como desea recuperar la propiedad de texto una vez que WebElement ya no esté obsoleto, puede usar lo siguiente:

 wait1 = WebDriverWait(driver, 10) wait1.until(expected_conditions.text_to_be_present_in_element((By.ID, "elementID"), "expected_text1")) 

O

 wait2 = WebDriverWait(driver, 10) wait2.until(expected_conditions.text_to_be_present_in_element_value((By.ID, "elementID"), "expected_text2"))