我正在使用Chrome网络驱动程序,因为Firefox webdriver似乎在我的Windows PC上出现问题。
我的Django功能测试在我去度假之前工作得很好,但现在他们正在抛出各种错误。
有时候,当我试图在页面上找到一个元素时,我得到了:
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
其他时候,尝试验证网址失败,因为Selenium似乎正在读取上一页的网址。失败点似乎在不同运行之间发生变化,换句话说,测试的某些部分可以在执行之间交替成功和不成功。但是,使用.click()
后,似乎总会出现此问题。
在观看浏览器时,Selenium似乎成功导航到该页面,因此我认为它只是在浏览器中存在之前过快地查找项目。
将implicitly.wait()
添加到我的setUpClass似乎没有帮助,但我可能使用它错了。
我尝试了来自Harry Percival's site的有希望的想法(下面),但Selenium只是在坐在被告知要等待的页面上时超时。
from contextlib import contextmanager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import \
staleness_of
class MySeleniumTest(SomeFunctionalTestClass):
# assumes self.browser is a selenium webdriver
@contextmanager
def wait_for_page_load(self, timeout=30):
old_page = self.browser.find_element_by_tag_name('html')
yield
WebDriverWait(self.browser, timeout).until(
staleness_of(old_page)
)
def test_stuff(self):
# example use
with self.wait_for_page_load(timeout=10):
self.browser.find_element_by_link_text('a link')
# nice!
还有其他人处理过此事吗?我应该遵循这个问题的正确方法是什么?
编辑: 发布的解决方案非常出色,并且真正清理了我的代码,因为我能够简单地将.click()添加到被调用的函数中,就像所描述的那样。
以下是帮助我自定义此文档的文档:
Documentation for the syntax for By for modification purposes.
Documentation for Selenium's Expected Conditions
注意:我使用的是术语"浏览器"代替司机,我认为这是最初让我失望的原因。
答案 0 :(得分:2)
wait_for_page_load必须是生成器吗?我想它会在没有等待的情况下回归!这就是为什么你的测试很不稳定的原因。有时,当你调用find_element_by_link_text时,元素会被加载。
我成功地使用了这种方法:
from selenium.webdriver.support import expected_conditions as EC
def wait_for_element(self, elm, by = 'id', timeout=10) :
wait = WebDriverWait(self.driver, timeout)
if by == 'id' :
element = wait.until(EC.element_to_be_clickable((By.ID,elm)))
return self.driver.find_element_by_id(elm)
elif by == 'link':
wait.until(EC.element_to_be_clickable( (By.LINK_TEXT,elm)))
return self.driver.find_element_by_link_text(elm)
# by tag, by css etc etc goes here.
我将此方法称为dom元素的显着ID,该元素应在页面可以与之交互之前显示。返回的元素可以直接交互。