vslat
vslat

Reputation: 95

Selenium webdriver explicit wait

I'm writing some automated tests for using the selenium chrome driver. I trying to write a reusable method that will explicitly wait for elements to appear and then call this method in other classes. Seems pretty straight forward but its not doing what I want it do. Here is the method that I have.

public String waitForElement(String item) {
    WebDriverWait wait = new WebDriverWait(driver,30);
    WebElement element = wait.until(
                        ExpectedConditions.elementToBeClickable(By.id(item)));
    return item;
}

Then I call the method and pass it a parameter like this:

waitForElement("new-message-button");

That doesn't seem to become working, can someone give some insight?

Upvotes: 3

Views: 83820

Answers (7)

prasadraj d
prasadraj d

Reputation: 11

public static void clickOn(WebDriver driver, WebElement locator, int timeout)
 {
        new WebDriverWait(driver,timeout).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(locator));
        locator.click();

    }

Call the above method in the main method then we will get explicitly wait functionality.

Upvotes: 1

user3864935
user3864935

Reputation:

I wrote an explicit wait for my selenium test in the following manner:

I declared my WebElement to be found with an @FindBy annotation added referencing the Id as follows:

@FindBy(how = How.ID, using = "home")
private WebElement home;

Then my method that waits for an element to load was written as follows:

public WebElement isElementLoaded(WebElement elementToBeLoaded) {
    WebDriverWait wait = new WebDriverWait(driver, 15);
    WebElement element = wait.until(ExpectedConditions.visibilityOf(elementToBeLoaded));
    return element;
}

This allowed me to reference any element I was waiting for by name that I had annotated with a find by, regardless of the @FindBy method used.

Upvotes: 0

virender rana
virender rana

Reputation: 62

Just use this method.I hope it will work perfectly.

public void waitForElement(String item) {
    WebDriverWait wait = new WebDriverWait(driver,30);
    WebElement element =  wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("item")));
}

Then call the method :

waitForElement("new-message-button");

Upvotes: 0

anuja jain
anuja jain

Reputation: 1387

You can use Explicit wait or Fluent Wait

Example of Explicit Wait -

WebDriverWait wait = new WebDriverWait(WebDriverRefrence,20);
WebElement aboutMe;
aboutMe= wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("about_me")));

Example of Fluent Wait -

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)                            
.withTimeout(20, TimeUnit.SECONDS)          
.pollingEvery(5, TimeUnit.SECONDS)          
.ignoring(NoSuchElementException.class);    

  WebElement aboutMe= wait.until(new Function<WebDriver, WebElement>() {       
public WebElement apply(WebDriver driver) { 
return driver.findElement(By.id("about_me"));     
 }  
});

Check this TUTORIAL for more details.

Upvotes: 1

Surya
Surya

Reputation: 1

We can develop implicit wait on our own.

Use this code; it should also work the same as implicit wait.

//=== Start of Implicit Wait Statement ===

public void implicit_Wait_ID(String str) throws Exception{

        for(int i=0;i<60;i++){
            try{
                driver.findElement(By.id(str)).isDisplayed();
                break;
            }catch(Exception e){Thread.sleep(2000);

            }   
        }
}
//=== End of Implicit Wait Statement ===    

Use this method by passing the ID value:

public void loginGmail() throws Exception
{
        driver.findElement(By.id("Email")).sendKeys("Mail ID");
        driver.findElement(By.id("next")).click();
        implicit_Wait_ID("Passwd");
        driver.findElement(By.id("Passwd")).sendKeys("Pwd value");
        driver.findElement(By.id("signIn")).click();
}

If it is Xpath, LinkText, just create one of the above methods for all locator types and reuse it n number of times in your script.

Upvotes: 0

catch32
catch32

Reputation: 18622

Your problem is that you passed String to method parameter:

public String waitForElement(String item) {

You have to pass your WebElement, something like:

public boolean visibilityOfElementWait(WebElement webElement) {
    if (webElement != null) {
        try {
            WebDriverWait wait = new WebDriverWait(Driver.getCurrentDriver(), 20);
            wait.until(ExpectedConditions.visibilityOf(wrappedElement));
            highlightElement(webElement);
            return true;
        } catch (Exception e) {
            return false;
        }
    } else
        Logger.logError("PageElement " + webElement.getText() + " not exist");
    return false;
}

public void highlightElement(WebElement element) {
    if (!Config.getProperty(Config.BROWSER).equalsIgnoreCase("ANDROIDHYBRID")) {

        String bg = element.getCssValue("backgroundColor");

        for (int i = 0; i < 4; i++) {
            Driver.getDefault()
                    .executeScript("arguments[0].style.backgroundColor = 'red'", element);
            Driver.getDefault()
                    .executeScript("arguments[0].style.backgroundColor = '" + bg + "'", element);
        }

   //            String highlightElementScript = "arguments[0].style.backgroundColor = 'red';";
   //            Driver.getDefault().executeScript(highlightElementScript, element);
    }
}

Upvotes: 0

drunkel
drunkel

Reputation: 228

I built a package using Selenium and waiting was one of the biggest issues I had. In the end, the methods as you described above wouldn't work. I had to resort to doing a simple implicit wait for any dynamic elements, as described below

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.

Code:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

src

Hope that helps.

Upvotes: -1

Related Questions