3

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?

9
  • it's not waiting for the element to appear. Commented Nov 19, 2013 at 17:28
  • Are you sure that item is what you want to return? When I've written code like this, what I wanted would be what is named element in your code. Commented Nov 19, 2013 at 17:41
  • I tried that didn't work either. Commented Nov 19, 2013 at 17:49
  • Do you definitely only have one item of that ID in the DOM? Also, if you debug the code, does element get found? Commented Nov 19, 2013 at 17:58
  • Well how do you know it doesn't wait? Have you set a breakpoint and debugged it? The code looks fine, I really don't believe it "isn't working" by "not waiting". Does it throw a timeout exception? If so when? After how long? Why are you returning the same string that you are passing in? That makes no sense. Commented Nov 19, 2013 at 18:59

7 Answers 7

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

elementalselenium.com/tips/47-waiting , elementalselenium.com/tips/23-dynamic-pages for detailed and nice clarification between implicit and explicit waits
1
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.

Comments

0

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

Comments

0

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.

Comments

0

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

Comments

0

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.

1 Comment

Correction, this is an example of an Explicit wait, not an implicit wait. Good example.
-1

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.

3 Comments

I tried using that but it wasn't clear how you get the web driver to wait based on a particular element id. For instance can you write that in a method?
As it says above, the implicit wait lasts for the life of the driver element. If you set driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); at the start of your method, the driver will wait for each element it tries to find in that method for 10s.
Gotcha, tried that too, didn't work but thanks for your help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.