Ray*_*lus 137 java automated-tests webdriver selenium-webdriver
我希望它只是我,但Selenium Webdriver看起来像是一场彻头彻尾的噩梦.Chrome webdriver目前无法使用,而其他驱动程序则非常不可靠,或者看起来如此.我正在与许多问题作斗争,但这里有一个问题.
随机地,我的测试将失败
"org.openqa.selenium.StaleElementReferenceException: Element is no longer attached 
to the DOM    
System info: os.name: 'Windows 7', os.arch: 'amd64',
 os.version: '6.1', java.version: '1.6.0_23'"
我正在使用webdriver版本2.0b3.我已经看到FF和IE驱动程序发生这种情况.我可以阻止这种情况的唯一方法是Thread.sleep在异常发生之前添加实际调用.这是一个糟糕的解决方法,所以我希望有人可以指出我的错误,这将使这一切变得更好.
jar*_*rib 116
是的,如果您遇到StaleElementReferenceExceptions问题,那是因为您的测试编写得很糟糕.这是竞争条件.请考虑以下情形:
WebElement element = driver.findElement(By.id("foo"));
// DOM changes - page is refreshed, or element is removed and re-added
element.click();
现在,在您单击元素的位置,元素引用不再有效.WebDriver几乎不可能对可能发生这种情况的所有情况做出很好的猜测 - 所以它会抛出手并控制你,因为测试/应用程序作者应该确切地知道可能会发生什么或不会发生什么.你想要做的是明确等待,直到DOM处于你知道事情不会改变的状态.例如,使用WebDriverWait等待特定元素存在:
// times out after 5 seconds
WebDriverWait wait = new WebDriverWait(driver, 5);
// while the following loop runs, the DOM changes - 
// page is refreshed, or element is removed and re-added
wait.until(presenceOfElementLocated(By.id("container-element")));        
// now we're good - let's click the element
driver.findElement(By.id("foo")).click();
presenceOfElementLocated()方法看起来像这样:
private static Function<WebDriver,WebElement> presenceOfElementLocated(final By locator) {
    return new Function<WebDriver, WebElement>() {
        @Override
        public WebElement apply(WebDriver driver) {
            return driver.findElement(locator);
        }
    };
}
你对目前的Chrome驱动程序非常不稳定感到非常正确,你会很高兴听到Selenium主干有一个重写的Chrome驱动程序,其中大部分实现都是由Chromium开发人员完成的.
PS.或者,不是像上面的示例那样明确地等待,而是可以启用隐式等待 - 这样WebDriver将始终循环直到指定的超时等待元素出现:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS)
根据我的经验,明确等待总是更可靠.
aea*_*ron 10
我已经能够使用这样的方法取得了一些成功:
WebElement getStaleElemById(String id) {
    try {
        return driver.findElement(By.id(id));
    } catch (StaleElementReferenceException e) {
        System.out.println("Attempting to recover from StaleElementReferenceException ...");
        return getStaleElemById(id);
    }
}
是的,它只是继续轮询元素,直到它不再被认为陈旧(新鲜?).并没有真正找到问题的根源,但我发现WebDriver在抛出这个异常时可能相当挑剔 - 有时候我会得到它,有时候我没有.或者可能是DOM真的在变化.
所以我不完全同意上面的答案,这必然表明一个写得不好的测试.我已经把它放在新的页面上,我没有以任何方式与之交互过.我认为DOM的表示方式或WebDriver认为陈旧的方式存在一些瑕疵.
Eer*_*ero 10
当AJAX更新处于中途时,我有时会收到此错误.Capybara似乎非常聪明地等待DOM更改(请参阅为什么wait_until已从Capybara中删除 ),但默认等待时间为2秒对我而言根本不够.在_spec_helper.rb_中更改为例如
Capybara.default_max_wait_time = 5