查看元素是否包含子元素的最快方法是什么?

本文关键字:元素 方法 是什么 是否 包含 | 更新日期: 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,您可以避免来自异常的额外时间。