Le sélénium waitForElement
Comment puis-je écrire la fonction Selenium pour attendre une table avec juste un identifiant de classe en Python? J'ai du mal à apprendre à utiliser les fonctions de webdriver en Python de Selenium.
11 réponses
Documentation sur le sélénium 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)
les fixations Python de Selenium 2 ont une nouvelle classe de support appelée expected_conditions.py pour faire toutes sortes de choses comme tester si un élément est visible. disponible ici.
NOTE: le fichier ci-dessus est dans le tronc depuis le 12 octobre 2012, mais pas encore dans le dernier téléchargement qui est toujours 2.25. Pour le moment jusqu'à ce qu'une nouvelle version de sélénium soit disponible, vous pouvez simplement sauvegarder ce fichier localement pour le moment et l'inclure dans vos importations comme je l'ai fait dessous.
pour rendre la vie un peu plus simple, vous pouvez combiner certaines de ces méthodes de condition attendue avec le sélénium wait until
logique pour rendre certaines fonctions très pratiques similaires à ce qui était disponible dans le sélénium 1. Par exemple, j'ai mis ceci dans ma classe de base appelée SeleniumTest que toutes mes classes de test de sélénium étendent:
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
vous pouvez alors les utiliser facilement dans vos tests comme:
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')
j'ai fait de bonnes expériences en utilisant:
- fuseau.sommeil(secondes)
- webdriver.Firefox.implicitly_wait(secondes)
Le premier est assez évident - il suffit d'attendre quelques secondes pour certains trucs.
pour tous mes Scripts de sélénium le sleep () avec quelques secondes (de 1 à 3) fonctionne quand je les exécute sur mon ordinateur portable, mais sur mon serveur le temps d'attente a une portée plus large, donc j'utilise aussi implicitly_wait (). J'ai l'habitude d'utiliser implicitly_wait(30), ce qui est vraiment assez.
une attente implicite est de dire à WebDriver de sonder le DOM pendant un certain temps en essayant de trouver un ou plusieurs éléments s'ils ne sont pas immédiatement disponibles. Le réglage par défaut est de 0. Une fois défini, l'attente implicite est définie pour la vie de l'instance de L'objet WebDriver.
j'ai implémenté ce qui suit pour python pour wait_for_condition puisque le pilote Python selenium ne supporte pas cette fonction.
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)
à utiliser comme
Attendre qu'un ExtJS appel Ajax n'est pas en attente:
wait_for_condition("!Ext.Ajax.isLoading()")
une variable Javascript est définie
wait_for_condition("CG.discovery != undefined;")
etc.
Utiliser
<body>
<div id="myDiv">
<table class="myTable">
<!-- implementation -->
</table>
</div>
</body>
... vous pouvez entrer le mot-clé suivant:
Wait Until Page Contains Element //table[@class='myTable'] 5 seconds
a moins que j'ai manqué quelque chose, il n'y a pas besoin de créer une nouvelle fonction pour cela.
au cas où cela aiderait ...
dans L'IDE sélénium, j'ai ajouté ... Commande: waitForElementPresent Cible: / / table[@class= 'pln']
puis J'ai fait Fichier > Exporter TestCase comme python2 (Pilote Web), et il m'a donné ceci ...
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")
Vous pouvez toujours utiliser une courte nuit de sommeil dans une boucle et la passer à votre id de l'élément:
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
espérons que cela aide
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
si Je ne sais pas quelque chose sur la commande selenium, j'utilise selenium web idea RC avec firefox. Vous pouvez choisir et ajouter une commande dans le combobox et quand terminer votre cas de test Après que vous pouvez exporter le code de test langue différente. comme java, ruby, phyton, C#, etc..
solution plus facile:
from selenium.webdriver.common.by import By
import time
while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0:
time.sleep(100)
Vous pouvez modifier cette fonction pour tous les types d'éléments. Celui ci-dessous est juste pour l'élément de classe:
où " driver "est le pilote," element_name "est le nom de la classe que vous recherchez, et" sec " est le nombre maximum de secondes que vous êtes prêt à attendre.
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)