Geklickt, aber nicht auf das gemeinte Element
Drei gleiche Schaltflächen, eine Liste mit vier Zeilen mehr, ein Selektor, der gestern funktionierte. Jedes Ziel ist ein CSS-Selektor, also ist jeder Fehler hier ein Selektorfehler.
Das Symptom. Der Klick funktioniert und etwas passiert, aber nicht das Gewollte: die falsche Zeile gelöscht, der falsche Dialog geöffnet, die Aktion auf das falsche Element angewandt.
Es wird kein Fehler gemeldet, denn mechanisch ist nichts schiefgegangen: Dinoer hat geklickt, was Sie angegeben haben. Jedes Ziel ist ein CSS-Selektor; der Fehler liegt also im Selektor.
Ursache 1: mehrere Elemente passen zum Selektor
Eine Seite mit drei „Clone“-Schaltflächen, eine pro Zeile. Dieser Selektor nimmt die erste in Dokumentreihenfolge:
{"type": "cliquer", "selecteur": "button:has-text('Clone')"}
Die Aktion läuft dann auf einer anderen Zeile als gemeint, und nichts in der Antwort weist darauf hin.
Die Lösung: bezeichnen, nicht beschreiben. Ergänzen Sie den Selektor um etwas, das nur diese Zeile hat:
{"type": "cliquer", "selecteur": "button[title='Clone example-two']"}
Ist im Markup nichts eindeutig, kann evaluer das richtige Element über
seinen Inhalt finden, bevor Sie handeln:
{"type": "evaluer",
"script": "Array.from(document.querySelectorAll('tr')).findIndex(tr => tr.textContent.includes('example-two'))"}
Ursache 2: ein Selektor nach Position, und die Position hat sich verschoben
:nth-child() und :nth-of-type() bezeichnen eine Zeile nach ihrem Platz in
der Liste, nicht danach, was sie ist. Kommen zwischen dem Schreiben und dem
Ausführen des Szenarios vier Zeilen über Ihrem Ziel hinzu, verschiebt sich das
Ziel um vier. Ein Szenario, das auf einer Seite mit einer Zeile getestet wurde,
scheitert auf derselben Seite mit fünf: derselbe Selektor, ein anderes
Ergebnis, kein Fehler.
Die Lösung. Kodieren Sie nie eine Position, wo der Inhalt genügt:
{"type": "cliquer", "selecteur": "tr:nth-child(3) button.delete"}
{"type": "cliquer", "selecteur": "tr:has-text('example-two') button.delete"}
Die zweite Fassung funktioniert auch nach einer Änderung der Liste, weil sie die Zeile nach ihrem Inhalt benennt, nicht nach ihrem Platz.
Nach Inhalt erkennen, nicht nach Position
„Die dritte Zeile ist die neueste“ stimmt, bis jemand eine vierte hinzufügt.
Trägt das Ziel etwas, das es kennzeichnet (einen Zeitstempel, einen Slug, eine
Kennung), bauen Sie den Selektor daraus, oder lesen Sie es zuerst mit
evaluer aus und entscheiden Sie anhand des Ergebnisses:
{"type": "evaluer",
"script": "Array.from(document.querySelectorAll('input.chk-item')).map(i => i.value)"}
Kurz gesagt
- Ein Selektor, der mehrere Elemente trifft, nimmt stillschweigend das erste.
:nth-child()und:nth-of-type()brechen, wenn sich die Liste ändert; nehmen Sie einen inhaltsbasierten Selektor, wo immer es einen gibt.evaluerkann ein Element über seinen Inhalt finden, bevor Sie einen Selektor wählen.- Erkennen Sie Ziele an dem, was sie enthalten, nie an ihrem Platz in einer Liste.