Java 检查按钮是否可用?如果没有,请等待5秒钟,然后再次检查?

Java 检查按钮是否可用?如果没有,请等待5秒钟,然后再次检查?,java,selenium,selenium-webdriver,wait,goto,Java,Selenium,Selenium Webdriver,Wait,Goto,基本上我是想看看现在是否可以点击一个按钮。如果没有,我想再试一次。因此,我需要某种goto函数来返回到代码的前一行。尽管我怀疑我写得非常糟糕,而且本可以做得更容易 try { driver.findElement(By.xpath("//button[@id='btn_ok']")).click(); }catch (Exception e) { driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); }

基本上我是想看看现在是否可以点击一个按钮。如果没有,我想再试一次。因此,我需要某种goto函数来返回到代码的前一行。尽管我怀疑我写得非常糟糕,而且本可以做得更容易

try {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
}catch (Exception e) {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}   
在上下文中,这里是问题的罪魁祸首

<button type="submit" value="ok" name="s1" id="btn_ok" class="green">

试试这种方法。看看是否有帮助

int size=driver.findElements(By.xpath("//button[@id='btn_ok']")).size();
if (size>0)
  {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
  }
  else
  {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    int size1=driver.findElements(By.xpath("//button[@id='btn_ok']")).size();
    if (size1>0)
  {
    driver.findElement(By.xpath("//button[@id='btn_ok']")).click();
  }



}   

您可以使用fluent等待。这将检查按钮在30秒内每5秒可点击一次。你可以根据需要调整时间。尝试此代码并给出反馈,无论它是否有效

 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)                           
                .withTimeout(30, TimeUnit.SECONDS)          
                .pollingEvery(5, TimeUnit.SECONDS)          
                .ignoring(NoSuchElementException.class);
        WebElement clickseleniumlink = wait.until(new Function<WebDriver, WebElement>(){

            public WebElement apply(WebDriver driver ) {
                return driver.findElement(By.xpath("//button[@id='btn_ok']"));
            }
        });
        clickseleniumlink.click();
Wait Wait=new FluentWait(驱动程序)
.带超时(30,时间单位。秒)
.轮询间隔(5,时间单位。秒)
.忽略(NoSuchElementException.class);
WebElement clickseleniumlink=wait.until(新函数(){
公共WebElement应用(WebDriver){
返回driver.findElement(By.xpath(//button[@id='btn\u ok']);
}
});
单击SeleniumLink。单击();

您可以使用显式等待等待按钮可单击。它将每500毫秒测试一次按钮,最长时间为指定时间,直到按钮可点击为止

WebDriverWait wait = new WebDriverWait(driver, 5); // maximum wait time is 5 here, can be set to longer time
WebElement button = wait.until(ExpectedConditions.elementToBeClickable(By.id("btn_ok")));
button.click();

作为旁注,
隐式等待
设置驱动程序搜索元素的最长时间,它不会延迟脚本。

我更喜欢这样,因为它可以将任何布尔条件设置为“等待”

publicstaticvoidwaituntil(此IWebDriver驱动程序,Func条件,浮点超时=10f)
{
浮动计时器=超时;
而(!Condition.Invoke()&&timer>0f){
系统.线程.线程.睡眠(500);
定时器-=0.5f;
}
系统.线程.线程.睡眠(500);
}
driver.waitill(()=>driver.FindElements(By.XPath(“某些XPath…”)).Length==0);
//与正常的硒等待相比,这里有一个特别的好处:能够等待与硒完全无关的事情,但有时仍然是值得等待的事情。
WaitUntil(()=>“数据库中存在某些内容”);
我发现隐式等待给我带来了太多的麻烦。我发现显式selenium等待可能会变得有点冗长,而且它不能在我的框架中涵盖我需要的所有内容,所以我做了很多扩展。下面是其中之一。注意,我在上面的示例中使用FindElements,因为我不希望出现异常如果找不到任何东西就会抛出。这应该对你有用

注意:这是C#,但是对于任何语言(特别是Java)来说,修改它应该不难。如果您的语言不允许这样的扩展,只需在类中直接调用该方法。您需要将其放在静态类中才能起作用。在逻辑中像这样扩展现有类时要小心,因为当其他人试图确定方法的定义位置时,这可能会混淆其他人。

Quick answer 请检查下面的代码,并告知它是否解决了您的问题。

public synchronized boolean clickon按钮变为可点击()时{
boolean buttonClicked=false;
试一试{
List元素=driver.findElements(By.xpath(//button[@id='btn\u ok']);
while(element.size()!=0){
//如果需要执行任何操作来显示按钮,请执行。
element=driver.findElements(By.xpath(//button[@id='btn\u ok']);
如果(element.size()!=0){
wait=新的FluentWait((WebDriver)驱动程序)。带有超时(30,时间单位。秒)。轮询间隔(5,
时间单位(秒);
wait.until(ExpectedConditions.elementtobelickable(driver.findelelement(By.xpath(//button[@id='btn_ok']));
buttonClicked=true;
打破
}
}
}捕获(例外e){
e、 printStackTrace();
}
点击返回按钮;
}

disabled属性如何?检查!它可能会给你一个提示!uhhh,谢谢,M.K.但是按钮在一天中的不同时间不可用。网站每隔几分钟就会添加和删除它。嗨@sergiy,尝试使用FluentWait()通过每5秒忽略NoSuchElementException来检查按钮是否可用?@sergiy为什么要在5秒(这么长)时检查按钮的可用性间隔?总共要检查多少次或多长时间可用?为什么要避免使用定制的、久经考验的WebDriverWait?谢谢,但它说withTimeout不受欢迎,pollingEvery也不受欢迎
    public static void WaitUntil(this IWebDriver driver, Func<bool> Condition, float timeout = 10f)
    {

        float timer = timeout;
        while (!Condition.Invoke() && timer > 0f) {

            System.Threading.Thread.Sleep(500);
            timer -= 0.5f;

        }
        System.Threading.Thread.Sleep(500);

    }

    driver.WaitUntil(() => driver.FindElements(By.XPath("some xpath...").Length == 0);

    //Here is the particular benefit over normal Selenium waits. Being able to wait for things that have utterly nothing to do with Selenium, but are still sometimes valid things to wait for.
    driver.WaitUntil(() => "Something exists in the database");
    public synchronized boolean clickOnButtonWhenItBecomesClickable() {
        boolean buttonClicked=false;
        try {
            List<WebElement> element = driver.findElements(By.xpath("//button[@id='btn_ok']"));

            while(element.size()!=0) {
                // if any action needed to perform to display button, please do it.
                element = driver.findElements(By.xpath("//button[@id='btn_ok']"));
                if(element.size()!=0) {
                    wait = new FluentWait<WebDriver>((WebDriver) driver).withTimeout(30, TimeUnit.SECONDS).pollingEvery(5,
                            TimeUnit.SECONDS);
                    wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath("//button[@id='btn_ok']"))));
                    buttonClicked=true;
                    break;  
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buttonClicked;
    }