2016-12-24 60 views
3

我目前正在浏览Django/TDD的书籍,并且遇到了StaleElementReferenceException并被卡住了。我一直在搜索并搜索StackOverflow来解决我的错误,但我一直无法解决它。我的相关代码如下:如何在Selenium中处理这个StaleElementReferenceException?

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()]) 

在代码 “rows_text = row.text” 线在上述代码中发生的错误。在我最初的代码中,它出现在底部的注释掉的self.assertIn语句中。

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> 

原代码书中有我进入被注释掉了(减去一个implicity_wait)。在我以前阅读本书时,代码没有任何问题,但是我一直在不停地收到这个StaleElement错误,并且无法找到一种方法来克服它。任何人有任何建议?

回答

1

首先我想指出,隐含的等待并不是许多人认为的。在你的代码中,它看起来像你正在使用它作为一种睡眠 - 但它远非如此。如果无法找到元素,隐式等待会再次尝试这段时间。如果第一次发现至少一个,则不起作用。设置一次就足够了,然后在整个会话期间对每个元素查找都是有效的。但它不适合用于等待特殊条件。

有什么事发生在这里的是以下(一种竞争状态):

  • 按下Enter键
  • 该网页将被更新之前,驾驶员发现目前市面上所有元素
  • 你试试循环浏览元素,但页面会在同一时间更新,使您以前的发现无效。

这一切都发生在几分之一秒内。

按Enter键后,您可以使用实际的睡眠(不是推荐的解决方案,但为了试验它的效果),或者您可以等待实际操作发生/完成。 (例如,您可以使用一个自定义条件来计算当前的行数,并等待它改变,或者使用一个等待所有请求完成的javascript。)