检查按钮是否可用?如果不等5秒再检查一次?

时间:2019-03-18 10:53:39

标签: 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);
}   

对于上下文,这是有问题的按钮元凶。

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

5 个答案:

答案 0 :(得分:2)

您可以使用流利的方式等待。这将检查按钮是否每5秒钟单击一次,持续30秒钟。您可以根据需要调整时间。试试此代码,并给出反馈是否有效。

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

答案 1 :(得分:1)

尝试这种方式。看看是否有帮助。

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



}   

答案 2 :(得分:0)

您可以使用显式等待来等待按钮可单击。它将每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();

请注意,implicitlyWait设置了驱动程序搜索元素的最长时间,它不会延迟脚本。

答案 3 :(得分:0)

我更喜欢这样做,因为它实际上可以使任何布尔条件“等到”。

    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");

我发现隐式等待给我带来了更多的麻烦,而不是值得的。而且我发现显式的selenium等待可能会变得有些冗长,并且它不能满足我在框架中需要的所有内容,因此我做了很多扩展。这是其中之一。注意,我在上面的示例中使用FindElements,因为如果什么也没发现,我不希望引发异常。这应该为您工作。

注意:这是C#,但是对于任何一种语言(尤其是Java)进行修改都应该很容易。如果您的语言不允许这样的扩展,则只需在类中直接调用该方法即可。您需要将其放在静态类中才能起作用。在逻辑上扩展这样的现有类时要小心,因为当其他人试图确定方法的定义位置时,它会使其他人迷惑。

答案 4 :(得分:0)

快速解答

请在下面的代码段中签出,并告知它是否解决了您的问题。

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