我有一个IWebElement(一个div),它包含一半的子元素。我想看看它是否包含子元素,如果是,我想捕获它。我做这样的事情:
IWebElement firstChild;
try
{
firstChild = divElement.FindElement(By.XPath("*"));
}
catch (NoSuchElementException e)
{
// catch and handling...
}
但这有三个方面很慢:
1.使用By.XPath(" *")
2.如果元素不存在则缓慢的FindElement
3. try / catch是一种较慢的机制,我宁愿在项目的现有项上返回布尔值
如何加快检测子元素的速度?
修改
澄清一下:我正在执行的测试运行在带有div的网格上,典型的网格是4 x 16,所以64个字段。我想将此网格转换为DataTable
以将其与预期结果进行比较。将这些字段捕获到数据表总共需要22秒。它的表现并不差,但我想刮掉那些宝贵的秒钟。
更新
我设法通过使用HTML Agility Pack捕获网格来实现。不幸的是(总有一些东西),input
元素的值无法捕获,因为它们是动态设置的。作为一种解决方案,我让HAP返回输入元素的ID并使用FindElement(By.Id(inputId))
捕获值,与其他Selenium选择方法相比,这是非常快的。
总而言之:我设法将捕获时间从大约22秒减少到不到3秒,性能提升超过600%。
答案 0 :(得分:1)
您需要在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;
答案 1 :(得分:1)
在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("*"));
如果您不需要访问匹配元素,则可以从bool
返回FindElementInstant
。
暂时停用隐式等待,FindElements
会立即返回空集合,如果不存在匹配元素,并且在FindElements
内使用FindElement
代替try-catch
来自例外的额外时间。