Selenium OpenQA.Selenium.StaleElementReferenceException: 过时的
本文关键字:Selenium 过时 StaleElementReferenceException OpenQA | 更新日期: 2023-09-27 18:33:36
希望有人可以在这个问题上提供帮助...
与级联下拉列表交互时,我不断收到上述错误消息(请参阅标题)。我成功使用的唯一基本修复是"Thread.Sleep"......请参阅下面的代码摘录:
注意我正在传递以下参数:
属性:标识
属性:例如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,因为我知道这不是推荐的方法。
提前致谢:)
看起来第一个下拉元素在回发开始时从 DOM 中卸载,并在回发完成后重新加载到 DOM。
当代码尝试在回发期间触摸此元素时,将引发StaleElementReferenceException
。Sleep()
调用的工作原理是停止代码在一段时间内接触此元素,恰好该时间段足以完成回发。
理想的解决方案是确定回发何时完成。
哪个谓词只有在回发完成后才会返回 true?将Sleep()
替换为等待该谓词返回 true。
例如,如果第二个下拉列表仅出现在回发中,请将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);
}