Sunday, January 22, 2017

WebDriver: Keeping implicit and explicit waits separate using reusable methods



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

      }

No comments:

Post a Comment