C# Selenium Webdriver是否等待元素单击?

C# Selenium Webdriver是否等待元素单击?,c#,selenium,timeout,webdriver,C#,Selenium,Timeout,Webdriver,我一直在寻找解决办法,但没有结果。我有一个按钮,我点击,这是有时需要很长时间才能返回数据,而司机是超时,只是杀死了应用程序,我猜 我正试图使用WebDriverWait类来完成这项工作,但是Click()方法在我使用它的方式中不可用 WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(0, 5, 0)); bool clicked = wait.Until<bool>((elem) => { el

我一直在寻找解决办法,但没有结果。我有一个按钮,我点击,这是有时需要很长时间才能返回数据,而司机是超时,只是杀死了应用程序,我猜

我正试图使用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;
});
WebDriverWait wait=newwebdriverwait(浏览器,新时间跨度(0,5,0));
bool clicked=等待((elem)=>
{
elem.Click();//不起作用
返回true;
});
隐式wait()方法仅用于等待加载元素,但在单击()时超时,因此它甚至无法查找元素

SetScriptTimeout()方法只适用于执行javascript,我没有这样做

有人知道这样做的方法吗?

我使用以下脚本:

  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);
    }
  }
私有静态void waituntlscriptfoundandexecute(字符串脚本){
int=0;
布尔值=false;
做{
尝试++;
试一试{
driver.executeScript(脚本);
发现=真;
}捕获(非接触元素异常nse){
System.out.println(“等待脚本NSE(“+tries+”);
}捕获(WebDriverException wde){
System.out.println(“等待脚本WDE(“+tries+”);
}捕获(例外e){
System.out.println(“等待脚本E(“+tries+”);
}
//等待
如果(!找到){
System.out.println(“等待未找到脚本(“+tries+”);
等待(脚本等待间隔);
}
}而(!found&&trys
您可以尝试使用
发送键,而不是
单击
。与
单击
不同,
发送键
在继续执行代码之前不会等待页面完成加载。所以你可以这样做:

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;
});
WebDriverWait wait=newwebdriverwait(浏览器,新时间跨度(0,5,0));
元素SendKeys(key.Enter);
等待。直到((驱动程序)=>
{         
//检查此处是否已加载结果
返回true;
});

顺便说一句,我很确定
,直到
IWebBrowser
作为输入,而不是元素,这就是为什么你不能点击
elem

除了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);
}
试试看
{
元素。单击();
}
抓住
{
cnt++;
做
{
//等什么
cnt++;
睡眠(1000);
//等待30秒,弹出窗口关闭
}而(!string.IsNullOrEmpty(browser.CurrentWindowHandle)&&cnt<30);
}
试试这个:

WebDriverWait wait = new WebDriverWait(driver , 1000) ;
wait.until(ExcepctedConditions.elementToBeClickable(ById("element"));
元素可以是重定向到的下一页上存在的任何元素的ID。
一旦页面完全加载,它将开始执行您的代码

使用LINQ Lambda表达式的RepeatUntil扩展方法

将此代码复制到项目中:

公共静态类SeleniumExtensionMethods
{
公共静态IWebElement RepeatUntil(此对象,
Func Func,
Func compare,
int MaxRetry=20)
{
//调用函数以获取元素
var eles=func(obj);
IWebElement元素=null;
while(element==null&&MaxRetry>0)
{
MaxRetry-=1;
//调用迭代器
元素=迭代收集(比较,eles);
if(元素==null)
{
睡眠(500);
//获取新的元素集合
eles=func(obj);
}
};
返回元素;
}
私有静态IWebElement迭代收集(
Func compare,
IEnumerable eles){
IWebElement元素=null;
eles.ToList().ForEach(
ele=>
{
//调用比较器
发现的var=比较(ele);
如果(找到)元素=元素;
});
返回元素;
}
}
使用以下语法调用它:

 // 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,以便
//cb是任何类型的。
var元素=cb.REPLATING(
//这是提供元素的第一个函数
p=>p.FindElements(By.ClassName(“TreeNode”),
//这是比较器
ele=>ele.Text==nodeText&&ele.Location.Y>YLocation);
注意:在上面的示例中,我们传入了一个PageObjectType,但您可以将其更改为IWebDriver或event IWebElement类型。所有类型参数都允许您将其用作指定类型的扩展方法

请注意扩展方法的灵活性,因为调用方可以确定集合和比较器。

不要使用线程睡眠

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();
}

这对我正在做的事情不起作用,但对寻找脚本很有用。谢谢我最终找到了一个解决方案,并将在我有能力的时候发布。新用户无法立即回答他们自己的解决方案。我也在同一个板上。你是如何解决的?你能分享吗?编辑您的问题并粘贴您的解决方案。这是一个很好的解决方案,不幸的是,将enter发送到此按钮不起作用。不知道为什么…我有时也会这样,尤其是当点击触发jQuery事件时。在这种情况下,我使用
ExecuteScript
执行单击,类似于:
driver.ExecuteScript($(参数[0]).click(),elem)很高兴见到你