2016-12-24 1 views
3

Ich gehe gerade durch ein Intro zu Django/TDD Buch und ich habe eine StaleElementReferenceException getroffen und stecken geblieben. Ich habe gegooglt und nach StackOverflow gesucht, um eine Lösung für meinen Fehler zu finden, aber ich konnte es nicht umgehen. Mein entsprechender Code ist wie folgt:Wie mit dieser StaleElementReferenceException in Selen umzugehen?

functional_tests.py

inputbox.send_keys(Keys.ENTER) 
self.browser.implicitly_wait(3) 
table = self.browser.find_element_by_id('id_list_table') 
#rows = table.find_elements_by_tag_name('tr') 
rows_ref = lambda: table.find_elements_by_tag_name('tr') 
#self.browser.implicitly_wait(3) 
foundBuy = False 
for row in rows_ref(): 
    self.browser.implicitly_wait(3) 
    rows_text = row.text 
    if (rows_text == '1: Buy peacock feathers'): 
     foundBuy = True 
     break 
if not (foundBuy): 
    self.fail('Could not find "1: Buy peacock feathers" in rows\' text') 
#self.assertIn('1: Buy peacock feathers', [row.text for row in rows_ref()]) 

Der Fehler tritt in dem obigen Code auf der "rows_text = row.text" Codezeile. In meinem ursprünglichen Code ist es in der auskommentierten Anweisung von self.assertIn am unteren Rand aufgetreten.

home.html

<html> 
    <head> 
     <title>To-Do lists</title> 
    </head> 
    <body> 
     <h1>Your To-Do list</h1> 
     <form method="POST"> 
      <input name="item_text" id="id_new_item" placeholder="Enter a to-do item"/> 
      {% csrf_token %} 
     </form> 
     <table id="id_list_table"> 
      {% for item in items %} 
       <tr><td>{{ forloop.counter }}: {{ item.text }}</td></tr> 
      {% endfor %} 
     </table> 
    </body> 
</html> 

Der ursprüngliche Code das Buch mich (minus ein implicity_wait) betreten hat, wird als Kommentar gekennzeichnet. In meiner vorherigen Zeit, die durch dieses Buch ging, funktionierte der Code nicht, aber ich habe diesen StaleElement-Fehler nonstop bekommen und kann keinen Weg finden, darüber hinwegzukommen. Hat jemand irgendwelche Vorschläge?

Antwort

1

Zunächst möchte ich darauf hinweisen, dass das implizite Warten nicht das ist, was viele Leute denken. In Ihrem Code sieht es so aus, als würden Sie es als eine Art Schlaf benutzen - aber es ist weit davon entfernt. Implizite Wartezeit versucht einfach erneut für diese Anzahl von Sekunden, wenn es kein Element finden kann. Wenn es beim ersten Mal mindestens eins findet, hat es keine Wirkung. Es reicht aus, es einmal festzulegen, und dann ist es für jede Elementsuche während der gesamten Sitzung gültig. Es ist jedoch nicht geeignet, um auf besondere Bedingungen zu warten.

Was hier zu geschehen scheint, ist die folgende (eine Art Race Condition):

  • Sie die Eingabetaste drücken
  • Bevor die Seite aktualisiert werden würde, findet der Fahrer alle aktuell verfügbaren Elemente
  • Sie versuchen, Durchlaufen der Elemente, aber die Seite wird in der Zwischenzeit aktualisiert, wodurch Ihre vorherigen Ergebnisse ungültig werden.

Dies alles geschieht in einem Bruchteil einer Sekunde.

Sie können einen tatsächlichen Ruhezustand verwenden, nachdem Sie die Eingabetaste gedrückt haben (keine empfohlene Lösung, aber für das Experimentieren funktioniert es) oder Sie können warten, bis die eigentliche Aktion ausgeführt wird. (Sie können z. B. eine benutzerdefinierte Bedingung verwenden, die die aktuelle Anzahl der Zeilen zählt und wartet, bis sie sich ändert, oder ein JavaScript verwenden, das wartet, bis alle Postanforderungen abgeschlossen sind.)

Verwandte Themen