select_by_value - Python Selenium WebDriver. Escribiendo mi propia condición esperada
webelement selenium python (3)
De acuerdo con la documentación :
WebDriverWait llama por defecto a ExpectedCondition cada 500 milisegundos hasta que vuelva a funcionar correctamente. Un retorno exitoso es para el tipo ExpectedCondition es booleano return true o no es un valor de retorno nulo para todos los demás tipos de ExpectedCondition.
El hecho de que obtenga la misma URL varias veces si comenta la espera personalizada debería darle una pista.
En __call__()
siempre devuelve False
ya que las URL nunca cambian. Como regresas False
, la TimeoutException
prevista nunca se cumple y obtienes la TimeoutException
.
Entonces, redefina la lógica de ExpectedCondition o pruebe un caso diferente.
Estoy tratando de escribir mi propia condición esperada. Lo que necesito ... Tengo un iframe. y también tengo una imagen. Quiero continuar el proceso cuando la imagen de scr cambie. Lo que hice:
class url_changed_condition(object):
''''''
Checks whether url in iframe has changed or not
''''''
def __init__(self, urls):
self._current_url, self._new_url = urls
def __call__(self, ignored):
return self._current_url != self._new_url
y luego en el código que tengo:
def process_image(self, locator, current_url):
try:
WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.TAG_NAME, u"iframe")))
iframe = self.driver.find_element(*locator)
if iframe:
print "Iframe found!"
self.driver.switch_to_frame(iframe)
WebDriverWait(self.driver, 10).until(ec.presence_of_element_located((By.XPATH, u"//div")))
# WebDriverWait(self.driver, 10).until(
# url_changed_condition(
# (current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))))
img_url = self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src")
print img_url
self.search_dict[self._search_item].append(img_url)
self.driver.switch_to_default_content()
except NoSuchElementException as NSE:
print "iframe not found! {0}".format(NSE.msg)
except:
print "something went wrong"
import traceback
import sys
type_, value_, trace_ = sys.exc_info()
print type_, value_
print traceback.format_tb(trace_)
finally:
return current_url
Este código funciona, pero devuelve la misma url varias veces. El problema es cuando url_changed_condition
que cae con TimeoutException
en
(current_url, self.driver.find_element(By.XPATH, u"//a/img").get_attribute(u"src"))
La línea debajo funciona bien ... No lo entiendo.
Usando la técnica descrita por @alecxe, pero modificada ligeramente para hacer frente a las condiciones esperadas que aceptan un elemento en lugar de un localizador : (En este caso, dado que no hay selenium.webdriver.support.expected_conditions.invisibility_of(element)
, estoy esperando el método is_displayed()
para señalar False)
class wait_for_element_to_be_invisible(object):
def __init__(self, element):
self.element = element
def __call__(self, driver):
return not(self.element.is_displayed())
def test_collapsible_blocks_expand_or_collapse(self):
self.browser.get(self.server_url+''/courses/1/'')
shadables = self.browser.find_elements_by_class_name(''shade'')
for shadable in shadables:
## parent, then sibling element (*)
shady_bit = shadable.find_element_by_xpath(''../following-sibling::*'')
element = WebDriverWait(self.browser, 10).until(
EC.visibility_of(shady_bit))
shadable.click()
element = WebDriverWait(self.browser, 10).until(
self.wait_for_element_to_be_invisible(shady_bit))
El fragmento de HTML con los bits relevantes del DOM es:
<h4 class="shadable"><span class="shade" title="Show/Hide">↓</span>
<a href="/link/to/uri">Title of Section</a>
</h4>
<article class="abstract">
<p>Descriptive part which is shadable
</p>
</article>`
Parece que este tema omite un ejemplo de una condición esperada personalizada .
En realidad es bastante fácil. En primer lugar, ¿qué es una condición esperada en enlaces de selenio Python ?
- es una
class
nuevo estilo (basada en elobject
) - tiene
__call__()
método mágico definido que devuelve un valor booleano
Hay un gran conjunto de clases de condiciones esperadas incorporadas .
Vamos a trabajar con el ejemplo. Digamos que queremos esperar hasta que el texto de un elemento comience con el texto deseado :
from selenium.webdriver.support import expected_conditions as EC
class wait_for_text_to_start_with(object):
def __init__(self, locator, text_):
self.locator = locator
self.text = text_
def __call__(self, driver):
try:
element_text = EC._find_element(driver, self.locator).text
return element_text.startswith(self.text)
except StaleElementReferenceException:
return False
Uso:
WebDriverWait(driver, 10).until(wait_for_text_to_start_with((By.ID, ''myid''), "Hello, World!"))