SeleniumHQ documentation says:
"WARNING:
Do not mix implicit and explicit waits. Doing so can cause unpredictable wait
times. For example setting an implicit wait of 10s and an explicit wait of 15
seconds, could cause a timeout to occur after 20 seconds."
In order to not mix the implicit and
explicit waits, an approach can be taken to implement the reusable methods in
such a way that when an explicit wait is required, the implicit timeout can be
set to 0 and just before coming out of the reusable method setting the implicit
wait back to the default value.
Below is the wrapper class implementing the
reusable method : findElement(SearchContext, by, long)
public class
WebDriverWrapper {
//Setting a
default value of the wait timeout.
public static final long IMPLICITLY_WAIT_TIMEOUT = 3000;
private WebDriver driver;
public
WebDriverWrapper(WebDriver driver) {
this.driver = driver;
}
//Method to let implicit wait to be set on the
basis of the passed parameter //value
public void setTimeout(long seconds) {
driver.manage().timeouts().implicitlyWait(seconds,
TimeUnit.SECONDS);
}
//Set implicitly wait timeout to the
default value
public void setTimeout() {
driver.manage().timeouts().implicitlyWait(IMPLICITLY_WAIT_TIMEOUT, TimeUnit.SECONDS);
}
//Implementing reusable method
FindElement
public WebElement findElement(SearchContext
context, By by, long timeoutSeconds) {
setTimeout(0); //Implicit timeout has
been set to 0
FluentWait<SearchContext> wait = new FluentWait<SearchContext> (context).withTimeout(timeoutSeconds, TimeUnit.SECONDS).ignoring(NotFoundException.class);
WebElement element;
try {
element =
wait.until(elementLocated(by));
} catch (Exception e) {
element = null;
} finally {
setTimeout();//implicit timeout has
been set to default value.
}
return element;
}
//explicitFind() Method
implemented in MyHomepage class
// to demonstrate usage of
findElement method implemented in WebDriverWrapper //class to avoid mixing
implicit and explicit wait.
public boolean explicitFind()
{
if((findElement(getDriver(),
By.id("Submit"), 5000))!=null){
return true;
}
else
return false;
}
//This test uses findElement method
implemented in WebDriverWrapper
class which helps in keeping implicit and
explicit wait separate.
@Test
public void testTimeouts() throws
InterruptedException {
Boolean
val = MyHomepage.explicitFind();
Assert.assertTrue(val);
}