Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webdriver implicitWait not working as expected

In webdriver code if i use thread.sleep(20000). It's waiting for 20 seconds, and my code also works fine. To archive the same if i use implicit wait like

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS); 

It's not waiting forcefully for 20 seconds and goes to next steps just in 3 to 4 seconds. and page still loading.

This is wired situation as i am using fluent wait to find some elements. if the elements still loading on the page it does not show error and make the test passed.

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

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

But if i say wrong id it waits for 50 seconds but other test got passed without clicking.. it is not showing any error.

My Question is how I should avoid Thread.sleep() as other selenium methods are not helping me..

like image 795
user2254173 Avatar asked Oct 22 '22 12:10

user2254173


1 Answers

Use below method to wait for a element:

public boolean waitForElementToBePresent(By by, int waitInMilliSeconds) throws Exception
{

    int wait = waitInMilliSeconds;
    int iterations  = (wait/250);
    long startmilliSec = System.currentTimeMillis();
    for (int i = 0; i < iterations; i++)
    {
        if((System.currentTimeMillis()-startmilliSec)>wait)
            return false;
        List<WebElement> elements = driver.findElements(by);
        if (elements != null && elements.size() > 0)
            return true;
        Thread.sleep(250);
    }
    return false;
}

And below method is to wait for page load:

public void waitForPageLoadingToComplete() throws Exception {
    ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            return ((JavascriptExecutor) driver).executeScript(
                    "return      document.readyState").equals("complete");
        }
    };
    Wait<WebDriver> wait = new WebDriverWait(driver, 30);
    wait.until(expectation);
}

Let's assume you are waiting for a page to load. Then call the 1st method with waiting time and any element which appears after page loading then it will return true, other wise false. Use it like,

waitForElementToBePresent(By.id("Something"), 20000)

The above called function waits until it finds the given element within given duration.

Try any of below code after above method

WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));

or

wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));

Update:

public boolean waitForTextFiled(By by, int waitInMilliSeconds, WebDriver wdriver) throws Exception
    {
        WebDriver driver = wdriver;
        int wait = waitInMilliSeconds;
        int iterations  = (wait/250);
        long startmilliSec = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++)
        {
            if((System.currentTimeMillis()-startmilliSec)>wait)
                return false;
            driver.findElement(By.id("txt")).sendKeys("Something");
            String name =  driver.findElement(by).getAttribute("value");

            if (name != null && !name.equals("")){
                return true;
            }
            Thread.sleep(250);
        }
        return false;
    }

This will try entering text in to the text field till given time in millis. If getAttribute() is not suitable in your case use getText(). If text is enetered then it returns true. Put maximum time that u can wait until.

like image 68
user2087450 Avatar answered Oct 28 '22 20:10

user2087450