Ich habe eine Webanwendung zum Testen mit Selen. Beim Laden der Seite wird viel JavaScript ausgeführt.
Dieser JavaScript-Code ist nicht so gut geschrieben, aber ich kann nichts ändern. Es findElement()
ist daher keine Option, darauf zu warten, dass ein Element mit der Methode im DOM angezeigt wird.
Ich möchte eine generische Funktion in Java erstellen, um auf das Laden einer Seite zu warten. Eine mögliche Lösung wäre:
- Führen Sie ein JavaScript-Skript von WebDriver aus und speichern Sie das Ergebnis
document.body.innerHTML
in einer Zeichenfolgenvariablenbody
. - Vergleichen Sie die
body
Variable mit der vorherigen Version vonbody
. Wenn sie gleich sind, setzen Sie einen Zähler inkrementieren,notChangedCount
andernfallsnotChangedCount
auf Null. - Warten Sie ein wenig (zum Beispiel 50 ms).
- Wenn sich die Seite einige Zeit nicht geändert hat (z. B. 500 ms),
notChangedCount >= 10
verlassen Sie die Schleife, andernfalls fahren Sie mit dem ersten Schritt fort.
Denken Sie, dass es eine gültige Lösung ist?
findElement
Wartet darauf, dass ein Element verfügbar ist, aber manchmal ist das Element verfügbar, bevor der Javascript-Code vollständig initialisiert wird. Deshalb ist dies keine Option.Antworten:
Wenn jemand tatsächlich eine allgemeine und immer zutreffende Antwort gewusst hätte, wäre sie vor langer Zeit überall umgesetzt worden und würde unser Leben so viel einfacher machen.
Es gibt viele Dinge, die Sie tun können, aber jeder einzelne hat ein Problem:
Wie Ashwin Prabhu sagte, wenn Sie das Skript gut kennen, können Sie sein Verhalten beobachten und einige seiner Variablen verfolgen
window
oderdocument
diese Lösung etc., ist jedoch nicht jedermanns Sache und kann nur von Ihnen und nur auf eine begrenzte Anzahl von verwendet werden Seiten.Ihre Lösung, indem Sie den HTML-Code beobachten und feststellen, ob er seit einiger Zeit geändert wurde oder nicht, ist nicht schlecht (es gibt auch eine Methode , um den ursprünglichen und nicht bearbeiteten HTML-Code direkt von abzurufen
WebDriver
), aber:setTimeout()
) auf und arbeiten immer wieder und können möglicherweise den HTML-Code bei jeder Ausführung ändern. Im Ernst, jede "Web 2.0" -Seite macht es. Gleichmäßiger Stapelüberlauf. Sie könnten die am häufigsten verwendeten Methoden überschreiben und die Skripte, die sie verwenden, als abgeschlossen betrachten, aber ... Sie können nicht sicher sein.innerHTML
Spaß.Es gibt Tools, die Ihnen dabei helfen. Nämlich Progress Listener zusammen mit nsIWebProgressListener und einigen anderen. Die Browserunterstützung hierfür ist jedoch schrecklich. Firefox begann zu versuchen, es ab FF4 zu unterstützen (entwickelt sich noch weiter). IE hat grundlegende Unterstützung in IE9.
Und ich denke, ich könnte bald eine andere fehlerhafte Lösung finden. Tatsache ist - es gibt keine eindeutige Antwort darauf, wann "Jetzt ist die Seite fertig" zu sagen ist, da die immerwährenden Skripte ihre Arbeit erledigen. Wählen Sie diejenige aus, die Ihnen am besten dient, aber achten Sie auf ihre Mängel.
quelle
Danke Ashwin!
In meinem Fall sollte ich auf die Ausführung eines JQuery-Plugins in einem Element warten müssen. Speziell "qtip"
Basierend auf Ihrem Hinweis hat es perfekt für mich funktioniert:
Hinweis: Ich verwende Webdriver 2
quelle
Sie müssen warten, bis Javascript und jQuery vollständig geladen sind. Führen Sie Javascript aus, um zu überprüfen, ob es
jQuery.active
ist0
unddocument.readyState
istcomplete
, was bedeutet, dass das Laden von JS und jQuery abgeschlossen ist.quelle
document.readyState == 'complete' && jQuery.active == 0
funktioniert super, aber gibt es so etwas für React? Da diese Überprüfungen nicht fangen werden, werden noch Reaktionsdaten / Komponenten geladen?Definiert / initialisiert die JS-Bibliothek eine bekannte Variable im Fenster?
In diesem Fall können Sie warten, bis die Variable angezeigt wird. Sie können verwenden
((JavascriptExecutor)driver).executeScript(String script, Object... args)
um auf diese Bedingung zu testen (so etwas wie
window.SomeClass && window.SomeClass.variable != null
:) und einen booleschen Werttrue
/ zurückzugebenfalse
.Wickeln Sie dies in ein
WebDriverWait
und warten Sie, bis das Skript zurückkehrttrue
.quelle
Ich hatte das gleiche Problem. Diese Lösung funktioniert für mich von WebDriverDoku:
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
quelle
Wenn Sie nur warten müssen, bis der HTML-Code auf der Seite stabil ist, bevor Sie versuchen, mit Elementen zu interagieren, können Sie das DOM regelmäßig abfragen und die Ergebnisse vergleichen. Wenn die DOMs innerhalb der angegebenen Abfragezeit identisch sind, sind Sie es golden. So etwas, bei dem Sie die maximale Wartezeit und die Zeit zwischen den Seitenabfragen vor dem Vergleich eingeben. Einfach und effektiv.
quelle
Der folgende Code funktioniert in meinem Fall perfekt - meine Seite enthält komplexe Java-Skripte
Quelle - Warten auf das Laden / Bereitstellen der Seite in Selenium WebDriver
quelle
Zwei Bedingungen können verwendet werden, um zu überprüfen, ob die Seite geladen ist, bevor ein Element auf der Seite gefunden wird:
Bei Verwendung von readyState wird bis zum Laden der Seite gewartet
Unten wartet JQuery, bis keine Daten geladen wurden
Versuchen Sie nach diesen JavaScriptCodes ,Out webElement zu finden.
quelle
Ich habe meine Entwickler gebeten, eine JavaScript-Variable "isProcessing" zu erstellen, auf die ich zugreifen kann (im "ae" -Objekt), die sie festgelegt haben, wenn Dinge ausgeführt werden, und die gelöscht werden, wenn Dinge erledigt sind. Ich führe es dann in einem Akkumulator aus, der es alle 100 ms überprüft, bis es fünf Änderungen hintereinander für insgesamt 500 ms ohne Änderungen erhält. Wenn 30 Sekunden vergehen, werde ich eine Ausnahme auslösen, da bis dahin etwas hätte passieren sollen. Dies ist in C #.
quelle
Um es richtig zu machen, müssen Sie die Ausnahmen behandeln.
So warte ich auf einen iFrame. Dies erfordert, dass Ihre JUnit-Testklasse die Instanz von RemoteWebDriver an das Seitenobjekt übergibt:
HINWEIS: Sie können mein gesamtes Arbeitsbeispiel hier sehen .
quelle
Für die
nodejs
Selenium-Bibliothek habe ich das folgende Snippet verwendet. In meinem Fall war ich für zwei Objekte suchen, der zum Fenster hinzugefügt werden, die in diesem Beispiel sind<SOME PROPERTY>
,10000
ist die Timeout Millisekunden,<NEXT STEP HERE>
ist das, was passiert nach den Eigenschaften auf dem Fenster zu finden sind.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
Hier ist aus meinem eigenen Code:
Window.setTimeout wird nur ausgeführt, wenn der Browser inaktiv ist.
Das rekursive Aufrufen der Funktion (42 Mal) dauert also 100 ms, wenn im Browser keine Aktivität vorhanden ist, und viel mehr, wenn der Browser mit etwas anderem beschäftigt ist.
Als Bonus kann der Zähler bei document.readyState oder bei jQuery Ajax-Aufrufen zurückgesetzt werden oder wenn jQuery-Animationen ausgeführt werden (nur wenn Ihre App jQuery für Ajax-Aufrufe verwendet ...)
...
...
BEARBEITEN: Ich stelle fest, dass executeAsyncScript nicht gut funktioniert, wenn eine neue Seite geladen wird und der Test möglicherweise nicht mehr auf unbestimmte Zeit reagiert. Verwenden Sie diese Option stattdessen besser.
quelle
Ich weiß nicht, wie ich das machen soll, aber in meinem Fall stimmt das Laden und Rendern am Ende der Seite mit FAVICON überein, das auf der Registerkarte Firefox angezeigt wird.
Wenn wir also das Favicon-Bild im Webbrowser erhalten können, ist die Webseite vollständig geladen.
Aber wie geht das?
quelle
Das implizite Warten funktioniert bei mir.
Siehe diese Antwort Selenium c # Webdriver: Warten Sie, bis das Element vorhanden ist
quelle
So mache ich das:
quelle
Ich mag Ihre Idee, den HTML-Code abzufragen, bis er stabil ist. Ich kann das zu meiner eigenen Lösung hinzufügen. Der folgende Ansatz ist in C # und erfordert jQuery.
Ich bin der Entwickler eines SuccessFactors (SaaS) -Testprojekts, bei dem wir keinerlei Einfluss auf die Entwickler oder die Eigenschaften des DOM hinter der Webseite haben. Das SaaS-Produkt kann möglicherweise das zugrunde liegende DOM-Design viermal im Jahr ändern, sodass ständig nach robusten, performanten Testmethoden für Selen gesucht wird (einschließlich NICHT-Tests mit Selen, wo dies möglich ist!).
Folgendes verwende ich für "Seite bereit". Es funktioniert derzeit in allen meinen eigenen Tests. Der gleiche Ansatz funktionierte vor ein paar Jahren auch für eine große interne Java-Web-App und war zu dem Zeitpunkt, als ich das Projekt verließ, über ein Jahr lang robust.
Driver
ist die WebDriver-Instanz, die mit dem Browser kommuniziertDefaultPageLoadTimeout
ist ein Timeout-Wert in Ticks (100 ns pro Tick)Beachten Sie im Folgenden die Reihenfolge der Wartezeiten in der Methode
PageReady
(Selenium document ready, Ajax, animations), die sinnvoll ist, wenn Sie darüber nachdenken:So etwas wie Ihr DOM-Vergleichsansatz könnte zwischen 1 und 2 verwendet werden, um eine weitere Robustheitsebene hinzuzufügen.
quelle