gpt4 book ai didi

java - WebElements 列表中的 Selenium Web Driver Stale Reference 异常

转载 作者:行者123 更新时间:2023-11-30 10:54:04 24 4
gpt4 key购买 nike

我在 selenium 页面上定义了一个属性列表,例如:

public IEnumerable<MyItem> MyList =>
webDriverInstance.FindListElementsWithWait<MyItem>(By.ClassName("my-item"));

其中 FindListElementsWithWait 是一个扩展方法:

public static IEnumerable<T> FindListElementsWithWait<T>(this IWebDriver driver, By locator, int timeOutMilliseconds = 10000)
{
var elements = new List<T>();
var wait = new WebDriverWait(driver, TimeSpan.FromMilliseconds(timeOutMilliseconds));
wait.Until(d =>
{
try
{
elements = d.FindElements(locator).Select(x => (T)Activator.CreateInstance(typeof(T), x)).ToList();
return true;
}
catch (TargetInvocationException)
{
return false;
}
}
);

return elements;
}

这是利用 WebDriverWait 而不是 Thread.Sleep。由于这是一个列表,因此每个 MyItem 都没有唯一的定位器。这种方法有效,但有一些怪癖。

  • 依赖于MyItem的构造函数(扩展方法示例中的T)抛出异常(StaleElementReferenceException)
  • 这意味着将属性初始化放在 MyItem 的构造函数中

例如:

public class MyItem
{
public string Name { get; private set; }

public MyItem(IWebElement webElement)
{
Name = webElement.FindElement(By.TagName("H4")).Text;
}
}

这行得通,但我遇到的问题是,如果我在 MyItem 上有最初不在元素上的其他属性。例如,如果我改变了一些状态,现在出现了一个取消按钮。如果我在构造函数中初始化了取消按钮,那么它将抛出 NoSuchElementException 并在页面加载时失败。我可以通过为新的 Cancel 按钮属性提供一个 getter 主体来解决这个问题。但这是在生产/推广脆弱的测试。

有没有人找到一种干净的方法来更新/刷新列表中的陈旧 WebElement,其中没有用于陈旧 WebElement 的唯一定位器?

最佳答案

好的,所以这是 javascript 中的竞争条件,其中 webdriver 在 AJAX 请求完成之前执行操作。 @JeffC 提出了一个很好的观点,即在对 Web 元素执行某些操作之前使用驱动程序拉取 Web 元素,尤其是列表。

在我的特殊情况下,我从列表中删除了一个元素。因此,如果您收到 StaleElementReferenceException 并从 View 中删除一个元素,那么这可能对您有用:

  • 确保您使用网络驱动程序来获取网页上的最新元素。因此,如果您要更改页面状态,请确保通过使用 webdriver 再次定位它们来刷新您的元素
  • 如果您仍然收到异常,则可能是 javascript 中存在竞争条件。因此,在对网络元素引用采取行动之前,请确保您正在等待任何动画/ajax 请求完成。

我发现以下文章对解决这个问题很有帮助:https://bocoup.com/weblog/a-day-at-the-races

关于java - WebElements 列表中的 Selenium Web Driver Stale Reference 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33785591/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com