Im Gegensatz zu der derzeit akzeptierten Antwort gibt es für PhantomJS nichts Spezielles, wenn es um den Unterschied zwischen dem Klicken von WebDriver und dem Ausführen in JavaScript geht.
Der Unterschied
Der wesentliche Unterschied zwischen den beiden Methoden ist allen Browsern gemeinsam und kann ziemlich einfach erklärt werden:
WebDriver: Wenn WebDriver den Klick ausführt, versucht es so gut wie möglich zu simulieren, was passiert, wenn ein realer Benutzer den Browser verwendet. Angenommen, Sie haben ein Element A, bei dem es sich um eine Schaltfläche mit der Aufschrift "Click me" handelt, und ein Element B, bei dem es sich um ein div
transparentes Element handelt, dessen Abmessungen jedoch zIndex
so festgelegt sind, dass es A vollständig abdeckt. Anschließend weisen Sie WebDriver an, auf A zu klicken. WebDriver wird darauf klicken simuliert den Klick , so dass B den Klick erhält zuerst . Warum? Da B A abdeckt und ein Benutzer versuchen würde, auf A zu klicken, würde B zuerst das Ereignis erhalten. Ob A schließlich das Klickereignis erhalten würde oder nicht, hängt davon ab, wie B das Ereignis behandelt. In jedem Fall ist das Verhalten mit WebDriver in diesem Fall das gleiche wie wenn ein realer Benutzer versucht, auf A zu klicken.
JavaScript: Nehmen wir nun an, Sie verwenden JavaScript A.click()
. Diese Klickmethode reproduziert nicht, was wirklich passiert, wenn der Benutzer versucht, auf A zu klicken. JavaScript sendet das click
Ereignis direkt an A, und B erhält kein Ereignis.
Warum funktioniert ein JavaScript-Klick, wenn ein WebDriver-Klick nicht funktioniert?
Wie oben erwähnt, versucht WebDriver so gut wie möglich zu simulieren, was passiert, wenn ein echter Benutzer einen Browser verwendet. Tatsache ist, dass das DOM Elemente enthalten kann, mit denen ein Benutzer nicht interagieren kann, und WebDriver Ihnen nicht erlaubt, auf diese Elemente zu klicken. Neben dem erwähnten überlappenden Fall bedeutet dies auch, dass unsichtbare Elemente nicht angeklickt werden können. Ein häufiger Fall, den ich bei Fragen zum Stapelüberlauf sehe, ist jemand, der versucht, mit einem GUI-Element zu interagieren, das bereits im DOM vorhanden ist, aber erst sichtbar wird, wenn ein anderes Element manipuliert wurde. Dies passiert manchmal bei Dropdown-Menüs: Sie müssen zuerst auf die Schaltfläche klicken, um das Dropdown-Menü aufzurufen, bevor ein Menüelement ausgewählt werden kann. Wenn jemand versucht, auf den Menüpunkt zu klicken, bevor das Menü sichtbar ist,Wenn die Person dann versucht, dies mit JavaScript zu tun, funktioniert dies, da das Ereignis unabhängig von der Sichtbarkeit direkt an das Element übermittelt wird.
Wann sollten Sie JavaScript zum Klicken verwenden?
Wenn Sie Selen zum Testen einer Anwendung verwenden , lautet meine Antwort auf diese Frage "fast nie". Im Großen und Ganzen sollte Ihr Selenium-Test reproduzieren, was ein Benutzer mit dem Browser tun würde. Nehmen Sie das Beispiel des Dropdown-Menüs: Ein Test sollte zuerst auf die Schaltfläche klicken, die das Dropdown-Menü aufruft, und dann auf den Menüpunkt klicken. Wenn es ein Problem mit der GUI gibt, weil die Schaltfläche unsichtbar ist oder die Menüelemente oder ähnliches nicht angezeigt werden, schlägt Ihr Test fehl und Sie haben den Fehler erkannt. Wenn Sie mit JavaScript herumklicken, können Sie diese Fehler nicht durch automatisierte Tests erkennen.
Ich sage "fast nie", weil es Ausnahmen geben kann, in denen es sinnvoll ist, JavaScript zu verwenden. Sie sollten jedoch sehr selten sein.
Wenn Sie Selenium zum Scraping von Websites verwenden , ist es nicht so wichtig, zu versuchen, das Benutzerverhalten zu reproduzieren. Die Verwendung von JavaScript zur Umgehung der GUI ist daher weniger problematisch.
click
odersendKeys
funktionierten WebDriver-Methoden - aber nicht immer. Es gab kein Lokalisierungsproblem oder eine andere Ausnahme, der Testfall ging einfach nicht weiter. Die Protokollierung zeigte, dass die Aktion ausgeführt wurde. Manchmal hat die VerwendungAction
geholfen. Wenn ich manuell auf das Element geklickt habe (nachdem der Testfall gestoppt wurde), hat alles gut funktioniert. Also haben wir bei diesen Gelegenheiten zu Raw JS gewechselt. Ich habe in den letzten 2 Jahren nicht mehr mit AngularJS gearbeitet, daher könnte es jetzt besser werden.Der vom Treiber ausgeführte Klick versucht, das Verhalten eines realen Benutzers so nah wie möglich zu simulieren, während das JavaScript
HTMLElement.click()
die Standardaktion für dasclick
Ereignis ausführt , auch wenn das Element nicht interaktiv ist.Die Unterschiede sind:
Der Treiber stellt sicher, dass das Element sichtbar ist, indem er es in die Ansicht scrollt und überprüft, ob das Element interaktiv ist .
Der Fahrer wird einen Fehler auslösen:
disabled
isttrue
)pointer-events
istnone
)Ein JavaScript
HTMLElement.click()
führt immer die Standardaktion aus oder schlägt bestenfalls stillschweigend fehl, wenn das Element deaktiviert ist.Vom Fahrer wird erwartet, dass er das Element scharfstellt, wenn es fokussierbar ist.
Ein JavaScript
HTMLElement.click()
wird nicht.Es wird erwartet, dass der Treiber alle Ereignisse (Mausbewegung, Mausbewegung, Mouseup, Klicken, ...) wie ein echter Benutzer ausgibt.
Ein JavaScript
HTMLElement.click()
gibt nur dasclick
Ereignis aus. Die Seite basiert möglicherweise auf diesen zusätzlichen Ereignissen und verhält sich möglicherweise anders, wenn sie nicht ausgegeben werden.Dies sind die Ereignisse, die der Treiber für einen Klick mit Chrome ausgibt:
Und dies ist das Ereignis, das mit einer JavaScript-Injektion ausgegeben wird:
Das von einem JavaScript
.click()
ausgegebene Ereignis ist nicht vertrauenswürdig und die Standardaktion kann möglicherweise nicht aufgerufen werden:https://developer.mozilla.org/en/docs/Web/API/Event/isTrusted
https://googlechrome.github.io/samples/event-istrusted/index.html
Beachten Sie, dass einige Treiber immer noch nicht vertrauenswürdige Ereignisse generieren. Dies ist bei PhantomJS ab Version 2.1 der Fall.
Das von einem JavaScript
.click()
ausgegebene Ereignis hat nicht die Koordinaten des Klicks .Die Eigenschaften
clientX, clientY, screenX, screenY, layerX, layerY
sind auf gesetzt0
. Die Seite kann sich auf sie verlassen und sich möglicherweise anders verhalten.Es mag in Ordnung sein, ein JavaScript
.click()
zu verwenden, um einige Daten zu verschrotten, aber es befindet sich nicht in einem Testkontext. Es macht den Zweck des Tests zunichte, da es das Verhalten eines Benutzers nicht simuliert. Wenn also der Klick des Treibers fehlschlägt, kann ein echter Benutzer höchstwahrscheinlich auch nicht denselben Klick unter denselben Bedingungen ausführen.Das Zielelement ist aufgrund einer Verzögerung oder eines Übergangseffekts noch nicht sichtbar / interaktiv.
Einige Beispiele :
https://developer.mozilla.org/fr/docs/Web (Dropdown-Navigationsmenü) http://materializecss.com/side-nav.html (Dropdown-Seitenleiste)
Workarrounds:
Fügen Sie einen Kellner hinzu, um auf die Sichtbarkeit, eine Mindestgröße oder eine stabile Position zu warten:
Versuchen Sie erneut zu klicken, bis dies erfolgreich ist:
Fügen Sie eine Verzögerung hinzu, die der Dauer der Animation / des Übergangs entspricht:
Das Zielelement wird von einem schwebenden Element abgedeckt, sobald es in die Ansicht gescrollt wurde:
Der Treiber scrollt das Element automatisch in die Ansicht, um es sichtbar zu machen. Wenn die Seite ein schwebendes / klebriges Element enthält (Menü, Anzeigen, Fußzeile, Benachrichtigung, Cookie-Richtlinie usw.), wird das Element möglicherweise abgedeckt und ist nicht mehr sichtbar / interaktiv.
Beispiel: https://twitter.com/?lang=de
Problemumgehungen:
Stellen Sie die Größe des Fensters auf ein größeres ein, um das Scrollen oder das schwebende Element zu vermeiden.
Bewegen Sie den Mauszeiger über das Element mit einem negativen
Y
Versatz und klicken Sie darauf:Scrollen Sie das Element vor dem Klicken in die Mitte des Fensters:
Blenden Sie das schwebende Element aus, wenn es nicht vermieden werden kann:
quelle
HINWEIS: Nennen wir "Klicken" den Endbenutzer-Klick. 'js click' ist ein Klick über JS
Hierfür gibt es zwei Fälle:
I. Wenn Sie PhamtomJS verwenden
Dann ist dies das bekannteste Verhalten von
PhantomJS
. Einige Elemente können beispielsweise manchmal nicht angeklickt werden<div>
. Dies liegt daran, dassPhantomJS
das Original ursprünglich für die Simulation der Browser-Engine erstellt wurde (wie anfängliches HTML + CSS -> Berechnen von CSS -> Rendern). Es bedeutet jedoch nicht, als Endbenutzer (Anzeigen, Klicken, Ziehen) mit ihm zu interagieren. DaherPhamtomJS
wird die Interaktion mit Endbenutzern nur teilweise unterstützt.WARUM FUNKTIONIERT JS CLICK? Bei jedem Klick handelt es sich um einen mittleren Klick. Es ist wie eine Waffe mit 1 Lauf und 2 Abzügen . Eine aus dem Ansichtsfenster, eine aus JS. Da
PhamtomJS
große in dem Motor zu simulieren - Browser, ein JS Klick sollte perfekt funktionieren.II. Der Event-Handler von "click" musste in der schlechten Zeit binden.
Zum Beispiel haben wir eine
<div>
-> Wir rechnen
-> dann binden wir das Ereignis des Klickens an das
<div>
.-> Plus mit einer schlechten Codierung des Winkels (z. B. wenn der Zyklus des Oszilloskops nicht richtig gehandhabt wird)
Wir können mit dem gleichen Ergebnis enden. Klicken funktioniert nicht, da WebdriverJS versucht, auf das Element zu klicken, wenn es keinen Klickereignishandler hat.
WARUM FUNKTIONIERT JS CLICK? Js Klick ist wie das direkte Einfügen von js in den Browser. Möglich mit 2 Möglichkeiten,
Die Faust ist über die devtools-Konsole (ja, WebdriverJS kommuniziert mit der devtools-Konsole).
Zweitens wird ein
<script>
Tag direkt in HTML eingefügt.Für jeden Browser ist das Verhalten unterschiedlich. Unabhängig davon sind diese Methoden komplizierter als das Klicken auf die Schaltfläche. Click verwendet das, was bereits vorhanden ist (Endbenutzer klicken), js click geht durch die Hintertür.
Und für js Klick scheint eine asynchrone Aufgabe zu sein. Dies hängt mit einem etwas komplexen Thema zusammen: " Browser-asynchrone Task- und CPU-Task-Planung " (lesen Sie es vor einiger Zeit und finden Sie den Artikel nicht wieder). Kurz gesagt, dies führt meistens dazu, dass js click auf einen Zyklus der Taskplanung der CPU warten muss und nach dem Binden des Klickereignisses etwas langsamer ausgeführt wird. (Sie konnten diesen Fall kennen, als Sie das Element manchmal anklickbar fanden, manchmal nicht.)
=> Wie oben erwähnt, bedeuten beide für einen Zweck, aber über die Verwendung des Eingangs:
=> Für die Leistung ist es schwer zu sagen, da es auf Browsern beruht. Aber allgemein:
=> Nachteile:
PS, wenn Sie nach einer Lösung suchen.
browser.wait()
( überprüfen Sie dies für weitere Informationen )(Ich möchte es kurz machen, bin aber schlecht gelandet. Alles, was mit Theorie zu tun hat, ist kompliziert zu erklären ...)
quelle