Selenium Webdriver等待元素点击?
我一直在寻找解决方案,但无济于事。我点击了一个按钮,有时需要很长时间才能返回数据,并且驱动程序正在超时,我只是想杀死应用程序。Selenium Webdriver等待元素点击?
我想使用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()方法仅适用于等待元素加载,但出这个时间上点击(),所以它甚至不能找一个元素。
SetScriptTimeout()方法只适用于执行JavaScript,我不这样做。
有谁知道一种方法来做到这一点?
除了prestomanifesto的解决方案,我可以提供一个不太理想的解决方案来解决这个问题。事实证明,它正在抛出一个异常 - 没有响应等等 - - 所以我只是在try catch中包围它,然后等待popup关闭,这似乎工作正常。
你可以在你的循环中替换你想要的任何东西,只要确保把一个计数器放入它就不会永久循环。
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);
}
我使用这个脚本:
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);
}
}
这对我正在做的事不起作用,而对于查找脚本非常有用。谢谢。我最终找到了一个解决方案,并会在发布后发布。新用户无法立即回答自己的解决方案。 – hacket 2012-03-08 14:31:10
我在同一块板上,你是如何修复的?你能分享吗?编辑你的问题和贴上你的解决方案。 – 2012-10-19 20:16:21
而不是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
点击。
这是一个很好的解决方案,不幸的是,发送输入到这个按钮不起作用。不知道为什么... – hacket 2012-03-09 13:36:21
我有时也会发生这种情况,特别是当点击触发jQuery事件时。在这种情况下,我使用'ExecuteScript'来执行点击,类似于:'driver.ExecuteScript(“$(arguments [0])。click()”,elem);'很高兴您现在找到了解决方法。 – prestomanifesto 2012-03-09 17:21:32
试试这个:
WebDriverWait wait = new WebDriverWait(driver , 1000) ;
wait.until(ExcepctedConditions.elementToBeClickable(ById("element"));
元素可以存在,你将被重定向到下一个页面上的任何元素的ID。 一旦页面加载完成,它就会开始执行你的代码。
该问题当处理element.click()时,它会暂停并等待大约30秒,以使.click()方法返回。如果没有,则抛出异常。 – hacket 2012-08-30 15:12:50
RepeatUntil推广使用LINQ LAMBDA方法表达式
拷贝代码到你的项目:
// 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);
注:
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;
}
}
使用此语法调用它的上面的例子中,我们传入一个PageObjectType,但可以将其更改为b类型IWebDriver或事件IWebElement。所有的类型参数都允许你使用它作为你指定类型的扩展方法。
请注意扩展方法的灵活性,因为调用者可以确定集合以及比较器。
我正在努力寻找更好的解决方案,我已经发布在这里,如果你可以看看它http://stackoverflow.com/questions/12967008/webdriverwait-or-implicitlywait-or-explictlywait-nothing-works – 2012-10-19 22:09:07