希望有人可以帮助解决这个问题...
在与级联下拉菜单进行交互时,我一直收到上述错误消息(请参阅标题)。 我成功使用的唯一基本修复是" Thread.Sleep" ...请参阅下面的代码摘录:
注意我传递了以下参数:
属性:ID
attrval:例如ID123456(下拉列表的ID)
参数:Car(我们想要选择的下拉值)
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 :(得分:1)
看起来好像第一个下拉元素在回发开始时从DOM中卸载,并在回发完成后重新加载到DOM。
当您的代码在回发期间尝试触摸此元素时,会抛出StaleElementReferenceException
。 Sleep()
调用的工作方式是暂停代码触摸此元素一段时间,这段时间恰好足以让回发完成。
理想的解决方案是确定回发何时完成。
一旦回发完成,什么谓词才会返回true?将Sleep()
替换为等待该谓词返回true。
e.g。如果第二个下拉菜单仅显示在回发上,请将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);
}