2011-10-16 20 views
36

¿Cómo escribo la función para que Selenium espere una tabla con solo un identificador de clase en Python? Estoy teniendo un demonio de tiempo aprendiendo a usar las funciones del controlador web Python de Selenium.Selenium waitForElement

Respuesta

40

Desde el Selenium Documentation PDF:

import contextlib 
import selenium.webdriver as webdriver 
import selenium.webdriver.support.ui as ui 

with contextlib.closing(webdriver.Firefox()) as driver: 
    driver.get('http://www.google.com') 
    wait = ui.WebDriverWait(driver,10) 
    # Do not call `implicitly_wait` if using `WebDriverWait`. 
    #  It magnifies the timeout. 
    # driver.implicitly_wait(10) 
    inputElement=driver.find_element_by_name('q') 
    inputElement.send_keys('Cheese!') 
    inputElement.submit() 
    print(driver.title) 

    wait.until(lambda driver: driver.title.lower().startswith('cheese!')) 
    print(driver.title) 

    # This raises 
    #  selenium.common.exceptions.TimeoutException: Message: None 
    #  after 10 seconds 
    wait.until(lambda driver: driver.find_element_by_id('someId')) 
    print(driver.title) 
+3

¿Alguna posibilidad de que pueda actualizar la url para los documentos de selenio pdf? Parece haberse "ido" –

+1

@ToranBillups: Desafortunadamente, ya no parece estar en el sitio oficial. Esto parece ser una copia de lo que me refería: http://scholar.harvard.edu/files/tcheng2/files/selenium_documentation_0.pdf. Busque "WebDriverWait". [La documentación en línea] (http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits) es similar y probablemente esté más actualizada. – unutbu

+0

¡Esto funciona sin problemas para mí! Gracias. – swdev

7

he hecho buenas experiencias usando:

  • time.sleep (segundos)
  • webdriver.Firefox.implicitly_wait (segundos)

El primero es bastante obvio - sólo tiene que esperar una algunos segundos para algunas cosas.

Para todas mis secuencias de comandos de Selenium, la función de suspensión() de unos segundos (de 1 a 3) funciona cuando las ejecuto en mi computadora portátil, pero en mi servidor el tiempo de espera tiene un rango más amplio, así que utilizo implicitly_wait() también. Usualmente uso implicitly_wait (30), que es realmente suficiente.

Una espera implícita es decirle a WebDriver que sondee el DOM durante un cierto período de tiempo cuando intente encontrar un elemento o elementos si no están disponibles de inmediato. La configuración predeterminada es 0. Una vez configurado, la espera implícita se establece para la vida de la instancia del objeto WebDriver.

1

Utilice Wait Until Page Contains Element con el localizador adecuado de XPath. Por ejemplo, dada la siguiente HTML:

<body> 
    <div id="myDiv"> 
    <table class="myTable"> 
     <!-- implementation --> 
    </table> 
    </div> 
</body> 

... puede introducir la siguiente palabra clave:

Wait Until Page Contains Element //table[@class='myTable'] 5 seconds 

A menos que me haya perdido algo, no hay necesidad de crear una nueva función para esto.

1

En caso de que esto ayude ...

En el IDE de selenio, añadí ... Comando: waitForElementPresent Objetivo: // tabla [@ class = 'pln']

Entonces hice archivo> Exportar TestCase Como python2 (web Driver), y me dio esto ...

def test_sel(self): 
    driver = self.driver 
    for i in range(60): 
     try: 
      if self.is_element_present(By.XPATH, "//table[@class='pln']"): break 
     except: pass 
     time.sleep(1) 
    else: self.fail("time out") 
2

he implementado el siguiente para el pitón para wait_for_condition ya que el conductor pitón selenio no admite esta función.

def wait_for_condition(c): 
for x in range(1,10): 
    print "Waiting for ajax: " + c 
    x = browser.execute_script("return " + c) 
    if(x): 
     return 
    time.sleep(1) 

para ser utilizado como

Espera que una llamada ExtJS Ajax no está pendiente:

wait_for_condition("!Ext.Ajax.isLoading()") 
variables

Un Javascript se establece

wait_for_condition("CG.discovery != undefined;") 

etc.

+0

Woohoo! Esto funcionó como un campeón: 'wait_for_condition (" $(). Active == 0 ")' – mattmc3

1

Siempre se puede utilizar un corto sueño en un bucle y pasar su identificación del elemento:

def wait_for_element(element): 
    count = 1 
    if(self.is_element_present(element)): 
      if(self.is_visible(element)): 
       return 
      else: 
       time.sleep(.1) 
       count = count + 1 
    else: 
     time.sleep(.1) 
     count = count + 1 
     if(count > 300): 
      print("Element %s not found" % element) 
      self.stop 
      #prevents infinite loop 
+0

Esto es en esencia lo que hace el WebdriverWait :) – erm3nda

19

selenio de 2 enlaces Python tienen una nueva clase de apoyo llamado expected_conditions .py para hacer todo tipo de cosas, como probar si un elemento es visible. Es available here.

NOTA: el archivo de arriba está en el maletero hasta el 12 de Oct, 2012, pero aún no en la última descarga, que sigue siendo de 2.25. Por el momento hasta que se publique una nueva versión de Selenium, puede guardar este archivo localmente por ahora e incluirlo en sus importaciones como he hecho a continuación.

Para hacer la vida un poco más simple, puede combinar algunos de estos métodos de condición esperados con la lógica Selenium wait until para hacer algunas funciones muy útiles similares a las disponibles en Selenium 1. Por ejemplo, puse esto en mi clase base llamada SeleniumTest la que todas mis clases de prueba selenio se extienden:

from selenium.common.exceptions import TimeoutException 
from selenium.webdriver.common.by import By 
import selenium.webdriver.support.expected_conditions as EC 
import selenium.webdriver.support.ui as ui 

@classmethod 
def setUpClass(cls): 
    cls.selenium = WebDriver() 
    super(SeleniumTest, cls).setUpClass() 

@classmethod 
def tearDownClass(cls): 
    cls.selenium.quit() 
    super(SeleniumTest, cls).tearDownClass() 

# return True if element is visible within 2 seconds, otherwise False 
def is_visible(self, locator, timeout=2): 
    try: 
     ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator))) 
     return True 
    except TimeoutException: 
     return False 

# return True if element is not visible within 2 seconds, otherwise False 
def is_not_visible(self, locator, timeout=2): 
    try: 
     ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator))) 
     return True 
    except TimeoutException: 
     return False 

a continuación, puede utilizar estos con facilidad en sus pruebas de este modo:

def test_search_no_city_entered_then_city_selected(self): 
    sel = self.selenium 
    sel.get('%s%s' % (self.live_server_url, '/')) 
    self.is_not_visible('#search-error') 
1

Esperemos que esto ayuda

from selenium import webdriver 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.support.wait import WebDriverWait 
from selenium.webdriver.common.by import By 


driver = webdriver.Firefox() 
driver.get('www.url.com') 

try: 
    wait = driver.WebDriverWait(driver,10).until(EC.presence_of_element_located(By.CLASS_NAME,'x')) 
except: 
    pass 
0

Si no sé algo sobre selenium command, uso selenium web idea RC con firefox. Puede elegir y agregar un comando en el cuadro combinado y cuando termine su caso de prueba después de que pueda exportar el idioma diferente del código de prueba. como Java, Ruby, Phyton, C#, etc ..

0

fácil solución:

from selenium.webdriver.common.by import By  
    import time 

    while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0: 
     time.sleep(100) 
0

Puede modificar esta función para todo tipo de elementos. El siguiente es solo para el elemento de clase:

Donde "driver" es el controlador, "element_name" es el nombre de clase que está buscando, y "sec" es la cantidad máxima de segundos que está dispuesto a esperar.

def wait_for_class_element(driver,element_name,sec): 

    for i in range(sec):   
     try: 
      driver.find_element_by_class_name(element_name) 
      break 
     except:   
      print("not yet") 
      time.sleep(1)