2011-10-16 9 views
36

Come si scrive la funzione per il selenio in attesa di una tabella con solo un identificatore di classe in Python? Sto imparando da tempo a imparare a utilizzare le funzioni del webdriver Python di Selenium.Selenium waitForElement

risposta

40

Dal 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

Qualche possibilità che tu possa aggiornare l'url per il documento di selenio pdf? Sembra essere "andato via" –

+1

@ToranBillups: Purtroppo, non sembra più essere sul sito ufficiale. Questa sembra essere una copia di ciò a cui mi riferivo: http://scholar.harvard.edu/files/tcheng2/files/selenium_documentation_0.pdf. Cerca "WebDriverWait". [La documentazione online] (http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#explicit-and-implicit-waits) è simile e probabilmente più aggiornata. – unutbu

+0

Questo funziona perfettamente per me! Grazie. – swdev

7

ho fatto buone esperienze con:

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

La prima è abbastanza evidente - basta aspettare un pochi secondi per alcune cose.

Per tutti i miei script di selenio il sonno() con alcuni secondi (intervallo da 1 a 3) funziona quando li eseguo sul mio portatile, ma sul mio server il tempo di attesa ha una gamma più ampia, quindi uso implicitamente() pure. Di solito uso implicitly_wait (30), che è davvero sufficiente.

un'attesa implicita è dire WebDriver interroga il DOM per un certo periodo di tempo quando si cerca di trovare un elemento o gli elementi se non sono immediatamente disponibili. L'impostazione predefinita è 0. Una volta impostata, l'attesa implicita viene impostata per la durata dell'istanza dell'oggetto WebDriver.

1

Utilizzare Wait Until Page Contains Element con il localizzatore XPath corretto. Ad esempio, dato il seguente codice HTML:

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

... è possibile inserire le seguenti parole chiave:

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

A meno che ho perso qualcosa, non c'è bisogno di creare una nuova funzione per questo.

1

Nel caso in cui questo aiuta ...

Nel Selenio IDE, ho aggiunto ... Comando: waitForElementPresent Obiettivo: // tabella [@ class = 'pln']

Poi ho fatto File> Esporta TestCase Come python2 (Web driver), e mi ha dato questa ...

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

ho implementato quanto segue per Python per wait_for_condition poiché il driver pitone selenio non supporta questa funzione.

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) 

da utilizzare come

Attendere che una chiamata in ExtJS Ajax non è in attesa:

wait_for_condition("!Ext.Ajax.isLoading()") 
è impostato variabile

A Javascript

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

etc.

+0

Woohoo! Funzionava come un campione: 'wait_for_condition (" $(). Active == 0 ")' – mattmc3

1

Si può sempre usare un breve sonno in un ciclo e passarlo vostro elemento id:

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

Questo è esattamente ciò che fa WebdriverWait :) – erm3nda

19

Selenio 2 di binding Python hanno una nuova classe di supporto chiamati expected_conditions .py per fare ogni sorta di cose come testare se un elemento è visibile. E 'available here.

NOTA: il file di cui sopra è nel bagagliaio, come del 12 ottobre 2012, ma non ancora in download più recente che è ancora 2.25. Per il momento fino a quando non verrà rilasciata una nuova versione di Selenium, per ora è sufficiente salvare questo file per ora e includerlo nelle importazioni come ho fatto di seguito.

Per rendere la vita un po 'più semplice, è possibile combinare alcuni di questi metodi previsti con la logica Selenium wait until per rendere alcune funzioni molto utili simili a quelle disponibili in Selenium 1. Ad esempio, inserisco questo nella mia classe base chiamato SeleniumTest che tutte le mie classi di test Selenium estendono:

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 

è quindi possibile utilizzare questi facilmente nei test in questo 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

Speriamo che questo aiuta

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

Se non so qualcosa sul comando del selenio, uso il selenio web idea RC con firefox. È possibile scegliere e aggiungere comandi nella casella combinata e al termine del test case dopo aver esportato il codice di prova in una lingua diversa. come Java, Ruby, Python, C#, ecc ..

0

facile soluzione:

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

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

È possibile modificare questa funzione per tutti i tipi di elementi. Quello sotto è solo per l'elemento di classe:

Dove "driver" è il driver, "nome_elemento" è il nome della classe che si sta cercando e "sec" è la quantità massima di secondi che si desidera attendere.

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)