Je travaille sur un Java Selenium-WebDriver. J'ai ajouté
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
et
WebElement textbox = driver.findElement(By.id("textbox"));
car mes applications prennent quelques secondes pour charger l'interface utilisateur. J'ai donc mis 2 secondes d'attente implicite. mais je n'ai pas pu localiser la zone de texte de l'élément
Puis j'ajoute Thread.sleep(2000);
Maintenant ça marche bien. Quel est le meilleur moyen?
Réponses:
Eh bien, il existe deux types d'attente: l'attente explicite et implicite. L'idée de l'attente explicite est
Le concept d'attente implicite est
Vous pouvez obtenir la différence dans les détails ici .
Dans de telles situations, je préférerais utiliser l'attente explicite (
fluentWait
en particulier):fluentWait
La fonction renvoie votre élément Web trouvé. De la documentation surfluentWait
: Une implémentation de l'interface Wait dont le délai d'expiration et l'intervalle d'interrogation peuvent être configurés à la volée. Chaque instance FluentWait définit la durée maximale d'attente d'une condition, ainsi que la fréquence à laquelle vérifier la condition. En outre, l'utilisateur peut configurer l'attente pour ignorer des types spécifiques d'exceptions pendant l'attente, comme NoSuchElementExceptions lors de la recherche d'un élément sur la page. Détails que vous pouvez obtenir iciL'utilisation de
fluentWait
dans votre cas soit la suivante:Cette approche IMHO mieux car vous ne savez pas exactement combien de temps attendre et dans l'intervalle d'interrogation, vous pouvez définir une valeur de temps arbitraire à travers laquelle la présence de l'élément sera vérifiée. Cordialement.
la source
import com.google.common.base.Function;
pasimport java.util.function.Function;
Function
était utilisé. Ce n'était pas évident pour moi au début. Merci d'avoir répondu.driver -> driver.findElement(locator)
. Lorsque vous l'utilisez, vous n'aurez pas du tout besoin d'une instruction d'importation..withTimeout(Duration.ofSeconds(30)).pollingEvery(Duration.ofSeconds(5))
au lieu de:.withTimeout(30, TimeUnit.SECONDS).pollingEvery(5, TimeUnit.SECONDS)
Ce fil est un peu plus ancien, mais je pensais publier ce que je fais actuellement (travail en cours).
Bien que je rencontre toujours des situations où le système est soumis à une charge importante et lorsque je clique sur un bouton d'envoi (par exemple, login.jsp), les trois conditions (voir ci-dessous) reviennent
true
mais la page suivante (par exemple, home.jsp) n'a pas t a encore commencé le chargement.Il s'agit d'une méthode d'attente générique qui prend une liste de ExpectedConditions.
J'ai défini diverses conditions attendues réutilisables (trois sont ci-dessous). Dans cet exemple, les trois conditions attendues incluent document.readyState = 'complete', pas de "wait_dialog" présent et pas de "spinners" (éléments indiquant que des données asynchrones sont demandées).
Seul le premier peut être appliqué de manière générique à toutes les pages Web.
Selon la page, je peux en utiliser un ou tous:
Il existe également des ExpectedConditions prédéfinies dans la classe suivante: org.openqa.selenium.support.ui.ExpectedConditions
la source
Si vous utilisez webdriverJs (node.js),
Le code ci-dessus fait attendre le navigateur pendant 5 secondes après avoir cliqué sur le bouton.
la source
L'utilisation
Thread.sleep(2000);
est une attente inconditionnelle. Si votre test se charge plus rapidement, vous devrez encore attendre. Donc, en principe, utiliserimplicitlyWait
est la meilleure solution.Cependant, je ne vois pas pourquoi
implicitlyWait
cela ne fonctionne pas dans votre cas. Avez-vous mesuré si lefindElement
prend en fait deux secondes avant de lancer une exception. Si tel est le cas, pouvez-vous essayer d'utiliser l'attente conditionnelle de WebDriver comme décrit dans cette réponse?la source
J'aime utiliser des conditions personnalisées. Voici du code en Python:
Chaque fois que vous avez besoin d'attendre, vous pouvez le faire explicitement en vérifiant l'existence d'un certain élément (un tel élément peut varier d'une page à l'autre).
find_elements_by_id
renvoie la liste - vide ou non, il vous suffit de vérifier.la source
le clic semble bloquer? - voici une autre façon d'attendre si vous utilisez WebDriverJS:
Le code ci-dessus attend après avoir cliqué sur le bouton pour que la page suivante se charge, puis saisit la source de la page suivante.
la source
Attendre implicitement et Thread.sleep Les deux sont utilisés pour la synchronisation uniquement ... mais la différence est que nous pouvons utiliser implicitement attendre tout le programme, mais Thread.sleep ne fonctionnera que pour ce code unique ... Ici, ma suggestion est d'utiliser implicitement attendre une fois dans le programme quand chaque fois que votre page Web sera actualisée, cela signifie que vous utilisez Thread.sleep à ce moment-là..il sera beaucoup mieux :)
Voici mon code:
la source
Parfois, l'attente implicite semble être remplacée et le temps d'attente est raccourci. [@ eugene.polschikov] avait une bonne documentation sur les pourquoi. J'ai trouvé dans mes tests et mon codage avec Selenium 2 que les attentes implicites sont bonnes, mais parfois vous devez attendre explicitement.
Il vaut mieux éviter d'appeler directement un thread pour dormir, mais parfois il n'y a pas de bon moyen de le contourner. Cependant, il existe d'autres options d'attente fournies par Selenium qui aident. waitForPageToLoad et waitForFrameToLoad se sont avérés particulièrement utiles.
la source
Attente implicite: pendant l'attente implicite, si le pilote Web ne peut pas le trouver immédiatement en raison de sa disponibilité, le WebDriver attendra l'heure mentionnée et il n'essaiera pas de retrouver l'élément pendant la période spécifiée. Une fois le temps spécifié écoulé, il essaiera de rechercher à nouveau l'élément la dernière fois avant de lancer l'exception. Le paramètre par défaut est zéro. Une fois que nous avons défini une heure, le pilote Web attend la période de l'instance d'objet WebDriver.
Attente explicite: il peut y avoir des cas où un élément particulier prend plus d'une minute à charger. Dans ce cas, vous n'aimez certainement pas définir un temps énorme d'attente implicite, car si vous le faites, votre navigateur attendra la même heure pour chaque élément. Pour éviter cette situation, vous pouvez simplement mettre une heure distincte sur l'élément requis uniquement. En suivant cela, le temps d'attente implicite de votre navigateur serait court pour chaque élément et il serait important pour un élément spécifique.
la source
Parfois, l'attente implicite échoue, disant qu'un élément existe mais ce n'est vraiment pas le cas.
La solution consiste à éviter d'utiliser driver.findElement et à le remplacer par une méthode personnalisée qui utilise implicitement une attente explicite. Par exemple:
Il existe des raisons supplémentaires pour éviter les attentes implicites autres que les échecs sporadiques et occasionnels (voir ce lien ).
Vous pouvez utiliser cette méthode "element" de la même manière que driver.findElement. Par exemple:
Si vous voulez vraiment attendre quelques secondes pour le dépannage ou une autre occasion rare, vous pouvez créer une méthode de pause similaire à ce que propose sélénium IDE:
la source
Réponse : attendez quelques secondes avant que la visibilité des éléments à l'aide de Selenium WebDriver ne passe par les méthodes ci-dessous.
implicitlyWait () : l'instance WebDriver attend le chargement complet de la page. Vous pensez utiliser 30 à 60 secondes pour attendre le chargement complet de la page.
ExplicitlyWait WebDriverWait () : l'instance WebDriver attend le chargement complet de la page.
Remarque : veuillez utiliser ExplicitlyWait WebDriverWait () pour gérer un WebElement particulier.
la source
Utiliser des actions -
Voir la méthode Actions # pause .
la source
Je préfère que le code suivant attende 2 secondes.
la source
est le pire: étant une attente statique, cela ralentira le script de test.
c'est une attente dynamique
Enfin, ce que je suggère est
avec quelques conditions prédéfinies:
la source
Cela m'a aidé, mais l'exception InterruptedException doit être prise en charge. Alors mieux vaut l'entourer d'essayer et d'attraper:
OU
Ajouter une déclaration throws:
Je préférerais le second car on peut alors utiliser
sleep()
autant de fois qu'il le souhaite et éviter la répétitiontry
et lecatch
blocage à chaque fois oùsleep()
a été utilisé.la source