我一直在寻找解决方案,但无济于事。我有一个按钮,我点击,有时需要很长时间才能返回数据,并且驱动程序超时并且只是杀死应用程序我想。
我正在尝试使用WebDriverWait类来完成此操作,但Click()方法不能用于我使用它的方式。
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));
bool clicked = wait.Until<bool>((elem) =>
{
elem.Click(); //Doesn't Work
return true;
});
ImplicitlyWait()方法仅用于等待加载元素,但这会在Click()上超时,因此它甚至无法查找元素。
SetScriptTimeout()方法只适用于执行javascript,我没有这样做。
有谁知道这样做的方法?
答案 0 :(得分:11)
试试这个:
WebDriverWait wait = new WebDriverWait(driver , 1000) ;
wait.until(ExcepctedConditions.elementToBeClickable(ById("element"));
元素可以是您重定向到的下一页上的任何元素的ID。 一旦页面完全加载,它将开始执行您的代码。
答案 1 :(得分:5)
而不是Click
您可以尝试使用SendKeys
。与Click
不同,SendKeys
不会在恢复代码执行之前等待页面完成加载。所以你可以这样做:
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0));
elem.SendKeys(Keys.Enter);
wait.Until<bool>((_driver) =>
{
//Check here if results have loaded yet
return true;
});
作为旁注,我非常确定Until
将IWebBrowser
作为输入,而非元素,这就是您无法点击elem
的原因。< / p>
答案 2 :(得分:5)
除了prestomanifesto的解决方案,我可以提供一个不太理想的解决方案来解决这个问题。事实证明它抛出一个异常 - 没有响应等...... - 所以我只是在try catch中包围它然后等待弹出窗口关闭,这似乎工作正常。
你可以在你的循环中替换你想要的任何东西,只要确保放入一个计数器,这样它就不会永远循环。
try
{
element.Click();
}
catch
{
cnt++;
do
{
//wait for whatever
cnt++;
Thread.Sleep(1000);
// Wait for 30 seconds for popup to close
} while (!string.IsNullOrEmpty(browser.CurrentWindowHandle) && cnt < 30);
}
答案 3 :(得分:0)
我使用这个脚本:
private static void waitUntilScriptFoundAndExecute(String script) {
int tries = 0;
boolean found = false;
do {
tries++;
try {
driver.executeScript(script);
found = true;
} catch (NoSuchElementException nse) {
System.out.println("Wait for script NSE (" + tries + ")");
} catch (WebDriverException wde) {
System.out.println("Wait for script WDE (" + tries + ")");
} catch (Exception e) {
System.out.println("Wait for script E (" + tries + ")");
}
// Waiting
if (!found) {
System.out.println("Wait for script Not found (" + tries + ")");
waiting(SCRIPT_WAITING_INTERVAL);
}
} while (!found && tries < MAX_SCRIPT_WAIT_TRIES);
if (!found) {
System.out.println("Script aborted: " + script);
}
}
答案 4 :(得分:0)
使用LINQ Lambda表达式的RepeatUntil扩展方法
将此代码复制到您的项目中:
public static class SeleniumExtensionMethods
{
public static IWebElement RepeatUntil<T>(this T obj,
Func<T, IEnumerable<IWebElement>> func,
Func<IWebElement, bool> compare,
int MaxRetry = 20)
{
//call function to get elements
var eles = func(obj);
IWebElement element = null;
while (element == null && MaxRetry > 0)
{
MaxRetry-=1;
//call the iterator
element = IterateCollection(compare, eles);
if (element == null)
{
Thread.Sleep(500);
//get new collection of elements
eles = func(obj);
}
};
return element;
}
private static IWebElement IterateCollection(
Func<IWebElement, bool> compare,
IEnumerable<IWebElement> eles){
IWebElement element = null;
eles.ToList().ForEach(
ele =>
{
//call the comparator
var found = compare(ele);
if (found) element = ele;
});
return element;
}
}
使用以下语法调用它:
// You can change PageObjectType to IWebDriver or IWebElement so that
// cb is of any type.
var element = cb.RepeatUntil<MyPageObjectType>(
//This is the first function to provide the elements
p => p.FindElements(By.ClassName("TreeNode")),
//This is the comparator
ele => ele.Text == nodeText && ele.Location.Y>YLocation);
注意:在上面的示例中,我们传入一个PageObjectType,但您可以将其更改为IWebDriver类型或事件IWebElement。所有类型参数都允许您将其用作指定类型的扩展方法。
请注意扩展方法的灵活性,因为调用者可以确定集合以及比较器。
答案 5 :(得分:0)
不要使用线程睡眠
public class(IWebDriver driver)
{
this.driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMinutes(1);
wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver,TimeSpan.FromMinutes(1));
}
public void class1()
{
wait.Until(ExpectedConditions.ElementToBeClickable(elem)).Click();
}