Kann mir jemand erlauben, wie ich Selen warten lassen kann, bis die Seite vollständig geladen ist? Ich möchte etwas Generisches, ich weiß, dass ich WebDriverWait konfigurieren und so etwas wie 'find' aufrufen kann, damit es wartet, aber ich gehe nicht so weit. Ich muss nur testen, ob die Seite erfolgreich geladen wurde, und mit der nächsten Seite fortfahren, um sie zu testen.
Ich habe etwas in .net gefunden, konnte es aber in Java nicht zum Laufen bringen ...
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Irgendwelche Gedanken jemand?
Antworten:
Versuchen Sie diesen Code:
Der obige Code wartet bis zu 10 Sekunden auf das Laden der Seite. Wenn das Laden der Seite die Zeit überschreitet, wird die
TimeoutException
. Sie fangen die Ausnahme und tun Ihre Bedürfnisse. Ich bin nicht sicher, ob das Laden der Seite nach der ausgelösten Ausnahme beendet wird. Ich habe diesen Code noch nicht ausprobiert. Willst du es einfach versuchen.Dies ist eine implizite Wartezeit. Wenn Sie dies einmal festlegen, hat es den Gültigkeitsbereich, bis die Web-Treiber-Instanz zerstört wird.
Weitere Informationen finden Sie in der Dokumentation
WebDriver.Timeouts
.quelle
Ihre vorgeschlagene Lösung wartet nur auf das Signal von DOM
readyState
complete
. Aber Selenium versucht standardmäßig, über die Methodendriver.get()
und auf die (und ein bisschen mehr) beim Laden der Seite zu wartenelement.click()
. Sie blockieren bereits, warten, bis die Seite vollständig geladen ist, und diese sollten in Ordnung sein.Das Problem sind natürlich Weiterleitungen über AJAX-Anforderungen und das Ausführen von Skripten - diese können von Selenium nicht abgefangen werden, es wartet nicht darauf, dass sie beendet werden. Sie können sie auch nicht zuverlässig über abfangen
readyState
- es wartet ein wenig, was nützlich sein kann, aber es signalisiertcomplete
lange bevor der gesamte AJAX-Inhalt heruntergeladen wird.Es gibt keine allgemeine Lösung, die überall und für alle funktionieren würde. Deshalb ist es schwierig und jeder verwendet etwas anderes.
Die allgemeine Regel besteht darin, sich darauf zu verlassen, dass WebDriver seinen Beitrag leistet, dann implizite Wartezeiten verwendet und dann explizite Wartezeiten für Elemente verwendet, die Sie auf der Seite bestätigen möchten. Es können jedoch noch viel mehr Techniken durchgeführt werden. Sie sollten auf Ihrer getesteten Seite diejenige (oder eine Kombination aus mehreren) auswählen, die in Ihrem Fall am besten funktioniert.
Weitere Informationen finden Sie in meinen beiden Antworten dazu:
quelle
element.click()
Anrufe.Dies ist eine funktionierende Java-Version des von Ihnen angegebenen Beispiels:
Beispiel für c #:
quelle
import com.google.common.base.Predicate
Hier ist mein Versuch einer vollständig generischen Lösung in Python:
Zunächst eine generische "Warte" -Funktion (verwenden Sie ein WebDriverWait, wenn Sie möchten, ich finde sie hässlich):
Als nächstes beruht die Lösung auf der Tatsache, dass Selen eine (interne) ID-Nummer für alle Elemente auf einer Seite aufzeichnet, einschließlich des
<html>
Elements der obersten Ebene . Wenn eine Seite aktualisiert oder geladen wird, erhält sie ein neues HTML-Element mit einer neuen ID.Angenommen, Sie möchten auf einen Link mit dem Text "Mein Link" klicken, zum Beispiel:
Für mehr pythonische, wiederverwendbare, generische Hilfsmittel können Sie einen Kontextmanager erstellen:
Und dann können Sie es für so ziemlich jede Selen-Wechselwirkung verwenden:
Ich denke, das ist kugelsicher! Was denken Sie?
Mehr Infos in einem Blogbeitrag dazu hier
quelle
Ich hatte ein ähnliches Problem. Ich musste warten, bis mein Dokument fertig war, aber auch, bis alle Ajax-Anrufe beendet waren. Die zweite Bedingung erwies sich als schwer zu erkennen. Am Ende habe ich nach aktiven Ajax-Anrufen gesucht und es hat funktioniert.
Javascript:
Vollständige C # -Methode:
quelle
document.readyState == 'complete' && jQuery.active == 0
für React?quelle
Für C # NUnit müssen Sie WebDriver in JSExecuter konvertieren und dann das Skript ausführen, um zu überprüfen, ob der Status document.ready vollständig ist oder nicht. Überprüfen Sie den folgenden Code als Referenz:
Dies wartet, bis die Bedingung erfüllt ist oder eine Zeitüberschreitung vorliegt.
quelle
Beim ersten Laden der Seite ist mir aufgefallen, dass das "Maximieren" des Browserfensters praktisch wartet, bis das Laden der Seite abgeschlossen ist (einschließlich der Quellen).
Ersetzen:
Mit:
als verwenden:
Dadurch wird die Seite geladen, bis zur Fertigstellung gewartet, maximiert und darauf konzentriert. Ich weiß nicht warum es so ist, aber es funktioniert.
Wenn Sie auf das Laden der Seite warten möchten, nachdem Sie auf "Weiter" oder einen anderen Auslöser für die Seitennavigation als "Navigieren ()" geklickt haben, erledigt die Antwort von Ben Dyer (in diesem Thread) die Arbeit.
quelle
Schauen Sie sich das Tapisserie- Web-Framework an. Dort können Sie den Quellcode herunterladen .
Die Idee ist, durch das HTML-Attribut des Körpers zu signalisieren, dass die Seite bereit ist. Sie können diese Idee verwenden, um komplizierte Klagefälle zu ignorieren.
Und dann erstellen Sie eine Erweiterung des Selenium-Webdrivers (gemäß Tapisserie-Framework).
Verwenden Sie die Erweiterung ElementIsDisplayed von Alister Scott .
Und schließlich Test erstellen:
quelle
Die Antwort von Ben Dryer wurde auf meinem Computer nicht kompiliert (
"The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait"
).Funktionierende Java 8-Version:
Java 7 Version:
quelle
Ich habe diesen Code ausprobiert und er funktioniert bei mir. Ich rufe diese Funktion jedes Mal auf, wenn ich auf eine andere Seite wechsle
quelle
In Nodejs können Sie es über Versprechen bekommen ...
Wenn Sie diesen Code schreiben, können Sie sicher sein, dass die Seite vollständig geladen ist, wenn Sie zum ...
Wenn Sie diesen Code schreiben, navigieren Sie und Selen wartet 3 Sekunden ...
Aus der Selendokumentation:
this.get (url) → Thenable
Plant einen Befehl zum Navigieren zur angegebenen URL.
Gibt ein Versprechen zurück, das aufgelöst wird, wenn das Dokument vollständig geladen wurde .
Selendokumentation (Nodejs)
quelle
Das Warten auf das Ereignis document.ready ist nicht die vollständige Lösung für dieses Problem, da sich dieser Code noch in einem Race-Zustand befindet: Manchmal wird dieser Code ausgelöst, bevor das Klickereignis verarbeitet wird, sodass er direkt zurückkehrt, da der Browser nicht gestartet wurde Laden Sie die neue Seite noch.
Nach einigem Suchen fand ich auf Obay die Testziege , die eine Lösung für dieses Problem hat. Der c # -Code für diese Lösung lautet ungefähr so:
`Ich feuere diese Methode direkt nach dem driver.navigate.gotourl ab, damit sie so schnell wie möglich einen Verweis auf die Seite erhält. Viel Spass damit!
quelle
Wenn Selenium eine neue Seite mit einem Klick öffnet oder Methoden sendet oder abruft, wartet es normalerweise, bis die Seite geladen ist. Das Problem ist jedoch, dass die Seite, wenn sie einen xhr-Aufruf (Ajax) hat, niemals auf das Laden des xhr wartet Erstellen einer neuen Methode, um ein xhr zu überwachen und auf sie zu warten, wird es das Gute sein.
if $.active == 0
Das ist also kein aktiver xhrs-Aufruf (der nur mit jQuery funktioniert). Für einen Javascript-Ajax-Aufruf müssen Sie eine Variable in Ihrem Projekt erstellen und simulieren.quelle
Sie können eine Logik schreiben, um dies zu handhaben. Ich habe eine Methode geschrieben, die das zurückgibt,
WebElement
und diese Methode wird dreimal aufgerufen, oder Sie können die Zeit verlängern und eine Nullprüfung für hinzufügen.WebElement
Hier ist ein Beispielquelle
Ich habe einen Javascript-Code ausgeführt, um zu überprüfen, ob das Dokument bereit ist. Ich habe viel Zeit beim Debuggen von Selentests für Websites mit clientseitigem Rendering gespart.
}}
quelle
quelle
Wie Rubanov für C # geschrieben hat, schreibe ich es für Java und es ist:
quelle
In Java wird es wie folgt aussehen: -
quelle
return document.readyState == 'loaded' || return document.readyState == 'complete'
Der folgende Code sollte wahrscheinlich funktionieren:
quelle
Wenn Sie eine langsame Seiten- oder Netzwerkverbindung haben, funktioniert wahrscheinlich keine der oben genannten Funktionen. Ich habe sie alle ausprobiert und das einzige, was für mich funktioniert hat, ist auf das letzte sichtbare Element auf dieser Seite zu warten. Nehmen Sie zum Beispiel die Bing-Webseite. Sie haben ein KAMERASymbol (Schaltfläche "Nach Bild suchen") neben der Hauptsuchschaltfläche platziert, das erst sichtbar wird, nachdem die gesamte Seite geladen wurde. Wenn alle das getan haben, müssen wir nur explizit warten, wie in den obigen Beispielen.
quelle
quelle
Hier ist etwas Ähnliches in Ruby:
quelle
Sie können den Thread in den Ruhezustand versetzen, bis die Seite neu geladen wird. Dies ist nicht die beste Lösung, da Sie eine Schätzung benötigen, wie lange das Laden der Seite dauert.
quelle
Ich habe überprüft, ob das Laden der Seite abgeschlossen ist, und arbeite in Selen 3.14.0
quelle
Für die Leute, die warten müssen, bis ein bestimmtes Element auftaucht. (verwendet c #)
Wenn Sie beispielsweise warten möchten, ob im DOM eine class = "error-message" vorhanden ist, tun Sie einfach Folgendes:
Für id wird es dann sein
WaitForElement(driver, By.Id("yourid"));
quelle
Verwenden Sie Angular? Wenn Sie es sind, erkennt der Webdriver möglicherweise nicht, dass die asynchronen Aufrufe beendet wurden.
Ich empfehle Paul Hammants ngWebDriver . Die Methode waitForAngularRequestsToFinish () könnte nützlich sein.
quelle