【发布时间】:2015-01-15 22:54:03
【问题描述】:
我有以下代码,它将搜索具有给定类名和文本的元素,直到找到或超时。我不喜欢它在 returnElement == null 时处于开环 30 秒的事实。有没有更有效的方法来做到这一点?注意:它不能仅根据文本找到元素。
#region FindAndWaitForElementListWithClassAndText
public static IWebElement FindAndWaitForElementWithClassAndText(IWebDriver driver, string className, string text, int timeout = 30)
{
if (driver == null)
throw new ApplicationException("No Selenium Driver defined, cannot continue.");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
IWebElement returnElement = null;
wait.Until(a => driver.FindElements(By.ClassName(className)));
//Starts task that times out after specified TIMEOUT_MILLIS
var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
var task = Task.Factory.StartNew(() => searchForElementWtihClassAndText(driver, className, text), token);
if(!task.Wait(TIMEOUT_MILLIS, token))
{
LoggerHelper.ErrorFormat("Could not find element with class and text: {0} :: {1}", className, text);
returnElement = null;
}
returnElement = task.Result;
return returnElement;
}
#endregion
private static IWebElement searchForElementWtihClassAndText(IWebDriver driver, String className, String text)
{
IWebElement returnElement = null;
while (returnElement == null)
{
var theList = driver.FindElements(By.ClassName(className));
if (theList != null && theList.Count > 0)
{
foreach (IWebElement el in theList)
{
if (el.Text.Equals(text, StringComparison.OrdinalIgnoreCase))
{
returnElement = el;
LoggerHelper.InfoFormat("Found Class Name and Text: {0} / {1}", className, text);
}
}
}
}
return returnElement;
}
这是一个示例元素:
<div class="smtListItem smtMessageItem">
<!-- ngIf: message.SentItem -->
<!-- ngIf: !message.SentItem -->
<span class="smtListName ng-binding ng-
scope" data-ng if=
"!message.SentItem">user08 EIGHT</span>
<!-- end ngIf: !message.SentItem -->
...
</div>
【问题讨论】:
-
您是指具有特定类名和文本的元素吗?你能给出具体的html sn-p吗?
-
当然,我添加了一个示例元素。
-
这里的主要问题是您没有正确使用
WebDriverWait。如果您愿意,它可以采用完整的谓词。所以@Saifur 下面的回答会很好。那里有大约 20 行重复。