J'ai une application web à tester avec Selenium. Il y a beaucoup de JavaScript en cours d'exécution lors du chargement de la page.
Ce code JavaScript n'est pas si bien écrit mais je ne peux rien changer. Donc, attendre qu'un élément apparaisse dans le DOM avec findElement()
method n'est pas une option.
Je souhaite créer une fonction générique en Java pour attendre le chargement d'une page, une solution possible serait:
- exécutez un script JavaScript à partir de WebDriver et stockez le résultat de
document.body.innerHTML
dans une variable chaînebody
. - comparez la
body
variable à la version précédente debody
. s'ils sont identiques, incrémenter un compteurnotChangedCount
sinon misnotChangedCount
à zéro. - attendez un peu (50 ms par exemple).
- si la page n'a pas changé depuis un certain temps (500 ms par exemple)
notChangedCount >= 10
alors sortez de la boucle sinon bouclez au premier pas.
Pensez-vous que c'est une solution valable?
findElement
attend qu'un élément soit disponible, mais parfois l'élément est disponible avant que le code javascript ne soit complètement initialisé, c'est pourquoi ce n'est pas une option.Réponses:
Si quelqu'un connaissait réellement une réponse générale et toujours applicable, elle aurait été mise en œuvre partout il y a longtemps et rendrait nos vies tellement plus faciles.
Il y a beaucoup de choses que vous pouvez faire, mais chacune d'elles a un problème:
Comme l'a dit Ashwin Prabhu, si vous connaissez bien le script, vous pouvez observer son comportement et suivre certaines de ses variables sur
window
oudocument
etc. Cette solution, cependant, n'est pas pour tout le monde et ne peut être utilisée que par vous et uniquement sur un ensemble limité de pages.Votre solution en observant le code HTML et s'il a été ou non modifié depuis un certain temps n'est pas mal (il existe également une méthode pour obtenir le HTML d'origine et non édité directement par
WebDriver
), mais:setTimeout()
) et travaillent encore et encore et pourraient éventuellement changer le HTML à chaque fois qu'ils s'exécutent. Sérieusement, chaque page "Web 2.0" le fait. Même Stack Overflow. Vous pouvez remplacer les méthodes les plus courantes utilisées et considérer les scripts qui les utilisent comme terminés, mais ... vous ne pouvez pas en être sûr.innerHTML
plaisir.Il existe des outils pour vous aider. À savoir Progress Listeners avec nsIWebProgressListener et quelques autres. Le support du navigateur pour cela, cependant, est horrible. Firefox a commencé à essayer de le supporter à partir de FF4 (toujours en évolution), IE a un support de base dans IE9.
Et je suppose que je pourrais bientôt trouver une autre solution défectueuse. Le fait est qu'il n'y a pas de réponse définitive sur le moment de dire "maintenant la page est terminée" à cause des scripts éternels qui font leur travail. Choisissez celui qui vous sert le mieux, mais méfiez-vous de ses lacunes.
la source
Merci Ashwin!
Dans mon cas, je devrais avoir besoin d'attendre une exécution du plugin jquery dans un élément .. spécifiquement "qtip"
basé sur votre indice, cela a parfaitement fonctionné pour moi:
Remarque: j'utilise Webdriver 2
la source
Vous devez attendre que Javascript et jQuery aient fini de se charger. Exécutez Javascript pour vérifier si
jQuery.active
est0
etdocument.readyState
estcomplete
, ce qui signifie que le chargement JS et jQuery est terminé.la source
document.readyState == 'complete' && jQuery.active == 0
fonctionne très bien mais y a-t-il quelque chose comme ça pour React? Puisque ces vérifications n'attraperont toujours pas le chargement des données / composants de réaction?La bibliothèque JS définit / initialise-t-elle une variable bien connue dans la fenêtre?
Si c'est le cas, vous pouvez attendre que la variable apparaisse. Vous pouvez utiliser
((JavascriptExecutor)driver).executeScript(String script, Object... args)
pour tester cette condition (quelque chose comme
window.SomeClass && window.SomeClass.variable != null
:) et renvoyer un booléentrue
/false
.Enveloppez ceci dans un
WebDriverWait
, et attendez que le script reviennetrue
.la source
J'ai eu le même problème. Cette solution fonctionne pour moi à partir de WebDriverDoku:
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
la source
Si tout ce que vous avez à faire est d'attendre que le html sur la page devienne stable avant d'essayer d'interagir avec les éléments, vous pouvez interroger le DOM périodiquement et comparer les résultats, si les DOM sont les mêmes dans le temps d'interrogation donné, vous êtes d'or. Quelque chose comme ça où vous passez dans le temps d'attente maximum et le temps entre les sondages de page avant de comparer. Simple et efficace.
la source
Le code ci-dessous fonctionne parfaitement dans mon cas - ma page contient des scripts Java complexes
Source - Comment attendre que la page soit chargée / prête dans Selenium WebDriver
la source
Deux conditions peuvent être utilisées pour vérifier si la page est chargée avant de trouver un élément sur la page:
L'utilisation de readyState ci-dessous attendra le chargement de la page
Sous JQuery attendra que les données n'aient pas été chargées
Après ces JavaScriptCode, essayez de findOut webElement.
la source
J'ai demandé à mes développeurs de créer une variable JavaScript "isProcessing" à laquelle je peux accéder (dans l'objet "ae") qu'ils définissent lorsque les choses commencent à fonctionner et qu'elles s'affichent lorsque les choses sont terminées. Je l'exécute ensuite dans un accumulateur qui le vérifie toutes les 100 ms jusqu'à ce qu'il en obtienne cinq de suite pour un total de 500 ms sans aucun changement. Si 30 secondes passent, je lance une exception car quelque chose aurait dû se passer d'ici là. C'est en C #.
la source
Pour le faire correctement, vous devez gérer les exceptions.
Voici comment j'attends un iFrame. Cela nécessite que votre classe de test JUnit transmette l'instance de RemoteWebDriver dans l'objet de page:
REMARQUE: vous pouvez voir mon exemple de travail complet ici .
la source
Pour la
nodejs
bibliothèque Selenium, j'ai utilisé l'extrait suivant. Dans mon cas, je cherchais deux objets qui sont ajoutés à la fenêtre, dans cet exemple sont<SOME PROPERTY>
,10000
est le nombre de millisecondes de délai d'attente,<NEXT STEP HERE>
est ce qui se passe après les propriétés se trouvent sur la fenêtre.la source
Vous pouvez écrire une logique pour gérer cela. J'ai écrit une méthode qui renverra le
WebElement
et cette méthode sera appelée trois fois ou vous pouvez augmenter le temps et ajouter une vérification nulle pourWebElement
Voici un exemplela source
Voici mon propre code:
Window.setTimeout ne s'exécute que lorsque le navigateur est inactif.
Donc, appeler la fonction de manière récursive (42 fois) prendra 100 ms s'il n'y a aucune activité dans le navigateur et bien plus encore si le navigateur est occupé à faire autre chose.
En prime, le compteur peut être réinitialisé sur document.readyState ou sur les appels jQuery Ajax ou si des animations jQuery sont en cours d'exécution (uniquement si votre application utilise jQuery pour les appels ajax ...)
...
...
EDIT: Je remarque que executeAsyncScript ne fonctionne pas bien si une nouvelle page se charge et que le test peut cesser de répondre indéfiniment, mieux vaut l'utiliser à la place.
la source
Je ne sais pas comment faire cela mais dans mon cas, le chargement de la fin de la page et le rendu correspondent à FAVICON affiché dans l'onglet Firefox.
Donc, si nous pouvons obtenir l'image favicon dans le navigateur Web, la page Web est entièrement chargée.
Mais comment faire ça ...
la source
Utiliser une attente implicite fonctionne pour moi.
Reportez-vous à cette réponse Selenium c # Webdriver: Attendez que l'élément soit présent
la source
Voici comment je fais:
la source
J'aime votre idée d'interroger le HTML jusqu'à ce qu'il soit stable. Je peux ajouter cela à ma propre solution. L'approche suivante est en C # et nécessite jQuery.
Je suis le développeur d'un projet de test SuccessFactors (SaaS) où nous n'avons aucune influence sur les développeurs ou les caractéristiques du DOM derrière la page Web. Le produit SaaS peut potentiellement changer sa conception DOM sous-jacente 4 fois par an, de sorte que la recherche est en permanence de moyens robustes et performants de tester avec Selenium (y compris NE PAS tester avec Selenium lorsque cela est possible!)
Voici ce que j'utilise pour «page prête». Cela fonctionne dans tous mes propres tests actuellement. La même approche a également fonctionné pour une grande application Web Java interne il y a quelques années, et avait été robuste pendant plus d'un an au moment où j'ai quitté le projet.
Driver
est l'instance WebDriver qui communique avec le navigateurDefaultPageLoadTimeout
est une valeur de timeout en ticks (100ns par tick)Dans ce qui suit, notez l'ordre des attentes dans la méthode
PageReady
(document Selenium prêt, Ajax, animations), ce qui a du sens si vous y réfléchissez:Quelque chose comme votre approche de comparaison DOM pourrait être utilisé entre 1 et 2 pour ajouter une autre couche de robustesse.
la source