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.

38
demandé sur Mohsin Awan 2011-10-16 05:33:11

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)
44
répondu unutbu 2012-01-14 10:05:29

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')
19
répondu Dave Koo 2017-07-31 07:08:55

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.

7
répondu naeg 2011-10-16 12:55:45

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.

2
répondu Deven Kalra 2011-11-08 07:23:37

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.

1
répondu jro 2011-10-17 07:58:16

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")
1
répondu jcfollower 2011-10-17 20:46:41

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
1
répondu TheDawg 2012-02-22 00:27:45

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
1
répondu John LeComte 2018-03-03 01:53:12

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..

0
répondu onder.diri 2017-02-16 07:30:14

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)
0
répondu Ben 2017-09-24 17:34:12

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)
0
répondu Diego Orellana 2017-10-16 23:17:37