为什么我在刚刚通过 Driver.FindElementsByCssSelector() 检索到的元素上得到 StaleElementReferenceException;



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

然而,我得到OpenQA.Selenium.StaleElementReferenceException:陈旧的元素引用:元素不附加到页面文档。

如果在查找元素和单击之间由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
}
}

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

正如这里所描述的,在许多其他教程和问题中描述的StaleElementReferenceExceptionbyDriver.FindElementsByCssSelector(".simple-grid .sg-row>.sg-cell")命令,您实际上捕获了与传递的定位器匹配的web元素,并在IWebElement FirstCell中存储了对它的引用。
但是由于web页面仍在动态变化,尚未最终构建,稍后您存储的引用变得陈旧,旧的,由于web元素更改而无效。
这就是为什么通过在try块中涉及FirstCell.Click(),您将获得StaleElementReferenceException.
试图在catch块中涉及绝对相同的操作将再次抛出StaleElementReferenceException,因为您仍然使用已经被称为无效(陈旧)的FirstCell引用。
你能做的就是获取元素引用再次在捕捉块里面,试着点击它。
像这样:

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);
}
}
}

相关内容

  • 没有找到相关文章

最新更新