1

我使用 edge webdriver 在页面 (SPA) 上查找元素,并立即模拟点击。

但是,我收到 OpenQA.Selenium.StaleElementReferenceException: stale element reference: element is not attach to the page document。

如果元素在查找元素和单击之间被 SPA 框架重新呈现,我添加了一些重试逻辑,但仍然出现错误。

IWebElement FirstCell => Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();


void Test()
{
  try 
  {
    FirstCell.Click();
  }
  catch (StaleElementReferenceException)
  {
    FirstCell.Click(); //retry - this should find element againand return new instance
  }
}

请注意,在重试块中,我得到了新的元素引用

4

1 回答 1

0

如此StaleElementReferenceException以及描述by命令的许多其他教程和问题中所述,Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell")您实际上捕获了与传递的定位器匹配的 Web 元素并将对它的引用存储在IWebElement FirstCell.
但是由于网页仍在动态变化,尚未最终构建,因此您存储的引用变得陈旧、陈旧、无效,因为 Web 元素已更改。
这就是为什么通过涉及块FirstCell.Click()内部try你得到StaleElementReferenceException.
尝试在块内包含完全相同的操作catch将再次抛出StaleElementReferenceException,因为您仍然使用已知的无效(陈旧)FirstCell引用。
您可以做些什么来使您的代码工作是在 catch 块中再次获取该元素引用并尝试单击它。
像这样:

IWebElement FirstCell => Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();


void Test()
{
  try 
  {
    FirstCell.Click();
  }
  catch (StaleElementReferenceException)
  {
    FirstCell = Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();
    FirstCell.Click(); //retry - Now this indeed should find element again and return new instance
  }
}

然而,这也不一定会起作用,因为页面可能仍然不完全,最终稳定。
要完成这项工作,您可以循环执行此操作,如下所示:

void Test()
{
  IWebElement FirstCell;
  for(int i=0;i<10;i++){
    try 
    {
      FirstCell = Driver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell").FirstOrDefault();
      FirstCell.Click();
    }
    catch (StaleElementReferenceException)
    {
      System.Threading.Thread.Sleep(200);
    }
  }
}
于 2021-07-27T18:05:36.820 回答