查看元素是否包含子元素的最快方法是什么?
本文关键字:元素 方法 是什么 是否 包含 | 更新日期: 2023-09-27 18:15:57
我有一个IWebElement(一个div),其中一半的时间包含子元素。我想看看它是否包含子元素,如果包含,我想捕获它。我这样做:
IWebElement firstChild;
try
{
firstChild = divElement.FindElement(By.XPath("*"));
}
catch (NoSuchElementException e)
{
// catch and handling...
}
但是这在三个方面是缓慢的:
1. By.XPath("*")
的使用2. 在元素不存在的情况下缓慢查找元素
3.try/catch是一种较慢的机制,我更希望对存在的项
如何加快这种检测子元素的方式?
编辑:
澄清一下:我正在执行的测试运行在带有div的网格上,一个典型的网格是4 x 16,所以有64个字段。我想把这个网格转换成DataTable
来和预期结果进行比较。将这些字段捕获到数据表总共需要22秒。它的性能不是很差,但我想把那些宝贵的时间缩短。
更新:
我通过使用HTML敏捷包捕获网格来做到这一点。不幸的是(总有一些事情),input
元素的值不能被捕获,因为它们是动态设置的。作为一种解决方案,我让HAP返回输入元素的id,并使用FindElement(By.Id(inputId))
捕获值,这与其他Selenium选择方法相比非常快。
长话短说:我设法将捕获时间从大约22秒减少到不到3秒,性能提高了600%以上。
您需要在XPath前面添加.
以便在后代中进行搜索:
var elems = divElement.FindElements(By.XPath("(.//*)[1]"));
IWebElement firstChild = elems.Count > 0 ? elems[0] : null;
作为一种选择,你可以使用CSS选择器。它可能会稍微快一点:
var elems = divElement.FindElements(By.CssSelector("*"));
IWebElement firstChild = elems.Count > 0 ? elems[0] : null;
在ISearchContext
上创建一个这样的扩展方法:
public static IWebElement FindElementInstant(this ISearchContext context, By by)
{
Driver.Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.Zero);
var matchingElement = context.FindElements(by).FirstOrDefault();
Driver.Instance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(/* whatever your implicit wait is normally */));
return matchingElement;
}
使用:var firstChild = divElement.FindElementInstant(By.XPath("*"));
如果不需要访问匹配的元素,可以直接从FindElementInstant
中返回bool
。
通过暂时禁用隐式等待,如果没有匹配的元素存在,FindElements
将立即返回一个空集合,并且通过在try-catch
中使用FindElements
而不是FindElement
,您可以避免来自异常的额外时间。