2014-12-09 39 views
2

希望有人能在这个问题上帮助...硒C# - OpenQA.Selenium.StaleElementReferenceException:陈旧的元素参考:元素没有连接到网页文件

我不断收到上述错误消息(见标题)时与级联下拉菜单进行交互。 我已经成功地采用的只有基本的解决方法是“Thread.sleep代码”看看下面的代码提取物:

注我传递下列参数:

属性:ID

attrval:例如ID123456(下拉的ID)

参数:汽车(下拉值,我们想选择)

IWebElement element = findMyElement(attribute, attrval); 
SelectElement selectElement = new SelectElement(element); 
selectElement.SelectByText(parameter); 
// dirty code - needs to be re-written 
Thread.Sleep(500); 
if (new SelectElement(findMyElement(attribute, attrval)).SelectedOption.Text.Equals(parameter)) 
{ 
    return "pass"; 
} 

注2:findMyElement是一个自定义的方法(这里是摘录):

public static IWebElement findMyElement(string attribute, string attrval) 
     { 
      WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); 
      switch (attribute.ToLower()) 
      { 
       case "id": 
        wait.Until(ExpectedConditions.ElementExists(By.Id(attrval))); 
        wait.Until(ExpectedConditions.ElementIsVisible(By.Id(attrval))); 
        return driver.FindElement(By.Id(attrval)); 

正如我在我的代码已经指出的意见是有反正我能避免使用的Thread.Sleep我所知,这是不是一个推荐的方法。

感谢提前:)

+0

什么行引发异常?选择下拉菜单时,您的应用程序中会发生什么?页面是否改变了?任何新元素添加?任何新请求已发送? – Arran 2014-12-09 12:09:15

+0

此处引发异常(不带thread.sleep)if(new SelectElement(findMyElement(attribute,attrval))。SelectedOption.Text.Equals(parameter)) – David 2014-12-09 12:14:41

+0

关于页面本身,因为它是一个级联下拉列表中的可选选项下拉菜单会更新,例如如果我在第一个下拉列表中选择汽车,第二个将询问颜色。在后台注意,当第一个下拉列表中的值已被选中时,页面会回发 – David 2014-12-09 12:34:17

回答

1

它看起来好像第一个下拉元素被从DOM卸载回传,并开始重新加载到DOM一次回传完成时。

当您的代码在回发期间尝试触摸此元素时,会引发StaleElementReferenceException。调用的工作方式是,通过触摸此元素来停止代码一段时间,这段时间恰巧足以让回发完成。

理想的解决方案是确定回发何时完成。

什么谓词只会在回发完成后才返回true?用等待该谓词返回true替换Sleep()

例如如果第二个下拉只在回传出现,则更换Thread.Sleep(500);有:

Func<IWebDriver, bool> predicate = (x) => 
{ 
    try 
    { 
     IWebElement elementThatOnlyAppearsOnPostback = findMyElement(attribute, attrval); 
     return true; 
    } 
    catch (NoSuchElementException) 
    { 
     return false; 
    } 
}; 
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30)); // or whatever timeout you want to set 
wait.Until(predicate); 

如果第二个下拉已经存在,但只有变得与上回发的选项填充,谓切换到:

Func<IWebDriver, bool> predicate = (x) => 
{ 
    SelectElement secondDropDown = new SelectElement(findMyElement(attribute, attrval)); 
    return (secondDropDown.Options.Count > 0); 
} 
相关问题