Oscar Ubillús
Oscar Ubillús

Reputation: 150

Selenium: How can i say to Selenium to wait for a button element?

I have one verification button which have some delay after I click on it (after I click it shows me a grid with elements) and then appears a NEXT button which redirects to the next page. I have this code:

((JavascriptExecutor)driver).executeScript("arguments[0].click()",driver.findElement(By.cssSelector("div#button-verify-wrapper > a")));
Thread.sleep(18000);
driver.findElement(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a")).click();
Thread.sleep(5000);

But I want to procced to click on the NEXT button, after all the grid charge (it takes a while depends on the server at that moment), because the next button just appear after the grid appears.

Are there selenium sentences to do it?

Upvotes: 1

Views: 3451

Answers (2)

robx
robx

Reputation: 3123

I would advocate for the explicit wait, and you can even make it a common method with an explicit wait to be reused. Many interaction with click can have an explicit wait for element to become clickable. Though not recommended, I do understand sometime that Thread.sleep may be the only viable option until a better approach can be implemented.

One is as Saurabh Gaur mention, WebDriverWait. The other similar option, gives a more granular control and customize polling.

Another is FluentWait: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html

// Waiting 30 seconds for an element to be present on the page, checking
   // for its presence once every 5 seconds.
   Wait wait = new FluentWait(driver)
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

   WebElement foo = wait.until(new Function() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.id("foo"));
     }
   });

Note though, that using FluentWait, you can get fooled into thinking you may be able to ignore other class exceptions such as StaleElementReference, and compiler would not complain. StaleElementReference can still occur, same for TimeoutException class.

Upvotes: 0

Saurabh Gaur
Saurabh Gaur

Reputation: 23845

Selenium provides two type of waits as follows :-

  • Explicit wait :-

    An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code. The worst case of this is Thread.sleep(), which sets the condition to an exact time period to wait. There are some convenience methods provided that help you write code that will wait only as long as required. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished. So you should try as :-

    WebDriverWait wait = WebDriverWait(drive, 10);
    wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("div#button-verify-wrapper > a"))).click();
    
    wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a"))).click();
    //Now find further element with WebDriverWait for the process
    
  • Implicit wait :-

    An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

    driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
    
    driver.findElement(By.cssSelector("div#button-verify-wrapper > a"))).click();
    driver.findElement(By.xpath(".//*[@id='select-a-data-source-footer']/div/div/a")).click();
    //Now find further element for the process 
    

Upvotes: 3

Related Questions