Warum klickt der Webdriver auf ein anderes Element?

1 Antwort

Vom Beitragsersteller als hilfreich ausgezeichnet

Ich denke, es hat mit der Positionierung und Sichtbarkeit des Elements zutun. Wenn du dir das Element einmal im Webinspektor genau anschaust, siehst du, dass es verrückt und in seiner Größe verändert wurde.

input[type="radio"] {
  position: absolute !important;
  top: 44px;
  left: 50px;
  height: 1px;
  width: 1px;
  border: 0;
  clip: rect(0, 0, 0, 0);
}

Das clip-Property beschreibt den Sichtbarkeitsbereich des Radiobuttons. Der liegt also bei 0. Ich würde also erst einmal den Wert neu setzen:

driver.execute_script("document.getElementById('paypal').style.clip='initial'")

Und danach via ActionChains zum Element scrollen, um anschließend den Klick durchzuführen.

element = driver.find_element_by_id("paypal")
action = ActionChains(driver)
action.move_to_element(element).click().perform()

Import für ActionChains:

from selenium.webdriver.common.action_chains import ActionChains

Zu deinen anderen Fragen:

Da wird gewartet, bis das Element sichtbar wird( Was heiß das dann schon wieder? )

Das, was dort steht. Das Eingabefeld (auffindbar anhand des Selektors input[name='paypal-email-2']) wird erst mit Klick auf den Button sichtbar. So lange kann also auch kein Text hineingeschrieben werden. Die Zeit zwischen Klick und Änderung der Sichtbarkeit wird halt abgewartet. Es ist ein asynchroner Prozess.

In anderen Fällen könnte die Zeitdifferenz noch unbestimmter sein, weil das Element bspw. mit einer kleinen Animation eingeführt wird oder die Webseite erst eine Datenanfrage an den Server sendet, um je nach Response so ein Feld mit bestimmten Daten zu füllen o.ä..

und offensichtlich wird nicht der Radiobutton, sondern das span Element angeklickt. Warum funktioniert das dann?

Das wird durch das Event-Handling des Browsers begünstigt (wenn es dich ganz konkret interessiert: Siehe Capturing & Bubbling, ich hatte den Ablauf hier auch schon einmal erklärt). Das span-Element liegt in einem label:

<label ...>
  <input type="radio" id="paypal" ...>
  <span ...>PayPal-Konto</span>
</label>

Durch den Klick auf das span-Element, wird das click-Event irgendwann auch auf dem label-Element ausgelöst. Hinzu kommt eine zweite Besonderheit: Ein label-Element kann sich an ein Formularfeld (wie input, textarea, ...) binden. Entweder, indem es mit einem for-Attribut auf die ID des Elements zeigt oder indem es dieses umspannt. Die Bindung bewirkt, dass bei Klick auf das Label das verknüpfte Formularfeld aktiviert wird. Bei einem einfachen Eingabefeld würde dieses fokussiert werden (sodass der Nutzer direkt hineinschreiben kann), bei einem Radiobutton (wie hier) oder einer Checkbox würde eine Selektion stattfinden.

Zuletzt noch eine Anmerkung bzgl. der technischen Umsetzung dieser Seite, damit keine Missverständnisse auftreten. Das span-Element besitzt dort zwar auch ein for-Attribut, was aber falsch ist. Es stellt auch nicht die erwähnte Bindung her, wie bei einem Label.

Wenn ich so weiter über Markup und CSS schaue, sehe ich noch weitere Fehler (z.B. doppelte IDs oder Elemente, die nicht mehr zum Webstandard gehören). Es kann also durchaus sein, dass du wegen dieser fehlerhaften Umsetzungen nochmal auf Probleme stößt.


Regex20921518 
Beitragsersteller
 31.07.2021, 10:23

Wow, danke für die "riesen Antwort"! Noch einmal zum Verständnis: Der Radio Button ist sozusagen nicht sichtbar. Wenn ich jetzt selbst klicke, wird aber etwas ausgelöst. Es gibt also irgendwo im Skript einen Eventlistener, der bei einem Klick das Textfeld erscheinen lässt?! Da "clip" 0 für den Radio Button ist, kann man selbst den Button nicht auslösen, durch das Klicken auf Span, welches das Event dann im DOM weitergibt, erreicht das Ereignis aber auch den R.Button und der Eventlistener wird getriggert?! LG

0
regex9  31.07.2021, 10:30
@Regex20921518

Genau.

Denke am besten immer die Motivation von Selenium, eine Testtool zu sein, welches echte Anwendungsfälle von Nutzern nachbilden soll. Insofern kann es, genauso wie ein normaler Nutzer, nur mit sichtbaren Elementen interagieren.

1
Regex20921518 
Beitragsersteller
 31.07.2021, 22:21
@regex9

Gut, also hängt es so zusammen wie von mir veschrieben?!

0