Package wtbox.util

Source Code of wtbox.util.WaitTool

package wtbox.util;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;


/**
* Wait tool class.  Provides Wait methods for an elements, and AJAX elements to load. 
* It uses WebDriverWait (explicit wait) for waiting an element or javaScript. 
*
* To use implicitlyWait() and WebDriverWait() in the same test,
* we would have to nullify implicitlyWait() before calling WebDriverWait(),
* and reset after it.  This class takes care of it.
*
*
* Generally relying on implicitlyWait slows things down
* so use WaitTool�s explicit wait methods as much as possible.
* Also, consider (DEFAULT_WAIT_4_PAGE = 0) for not using implicitlyWait
* for a certain test.
*
* @author Chon Chung, Mark Collin, Andre, Tarun Kumar
*
* @todo check FluentWait -- http://seleniumsimplified.com/2012/08/22/fluentwait-with-webelement/
*
* Copyright [2012] [Chon Chung]
*
* Licensed under the Apache Open Source License, Version 2.0 
* http://www.apache.org/licenses/LICENSE-2.0
*
*/
public class WaitTool {

  /** Default wait time for an element. 7  seconds. */
  public static final int DEFAULT_WAIT_4_ELEMENT = 7;
  /** Default wait time for a page to be displayed.  12 seconds. 
   * The average webpage load time is 6 seconds in 2012.
   * Based on your tests, please set this value.
   * "0" will nullify implicitlyWait and speed up a test. */
  public static final int DEFAULT_WAIT_4_PAGE = 12;


 

  /**
    * Wait for the element to be present in the DOM, and displayed on the page.
    * And returns the first WebElement using the given method.
    *
    * @param WebDriver  The driver object to be used
    * @param By  selector to find the element
    * @param int  The time in seconds to wait until returning a failure
    *
    * @return WebElement  the first WebElement using the given method, or null (if the timeout is reached)
    */
  public static WebElement waitForElement(WebDriver driver, final By by, int timeOutInSeconds) {
    WebElement element;
    try
      //To use WebDriverWait(), we would have to nullify implicitlyWait().
      //Because implicitlyWait time also set "driver.findElement()" wait time. 
      //info from: https://groups.google.com/forum/?fromgroups=#!topic/selenium-users/6VO_7IXylgY
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
       
      WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
      element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
     
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return element; //return the element 
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
 
 
 
 

  /**
    * Wait for the element to be present in the DOM, regardless of being displayed or not.
    * And returns the first WebElement using the given method.
    *
    * @param WebDriver  The driver object to be used
    * @param By  selector to find the element
    * @param int  The time in seconds to wait until returning a failure
    *
    * @return WebElement  the first WebElement using the given method, or null (if the timeout is reached)
    */
  public static WebElement waitForElementPresent(WebDriver driver, final By by, int timeOutInSeconds) {
    WebElement element;
    try{
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
     
      WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
      element = wait.until(ExpectedConditions.presenceOfElementLocated(by));
     
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return element; //return the element
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
 

  /**
    * Wait for the List<WebElement> to be present in the DOM, regardless of being displayed or not.
    * Returns all elements within the current page DOM.
    *
    * @param WebDriver  The driver object to be used
    * @param By  selector to find the element
    * @param int  The time in seconds to wait until returning a failure
    *
    * @return List<WebElement> all elements within the current page DOM, or null (if the timeout is reached)
    */
  public static List<WebElement> waitForListElementsPresent(WebDriver driver, final By by, int timeOutInSeconds) {
    List<WebElement> elements;
    try
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
       
      WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
      wait.until((new ExpectedCondition<Boolean>() {
              @Override
              public Boolean apply(WebDriver driverObject) {
                  return areElementsPresent(driverObject, by);
              }
          }));
     
      elements = driver.findElements(by);
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return elements; //return the element 
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
    * Wait for an element to appear on the refreshed web-page.
    * And returns the first WebElement using the given method.
    *
    * This method is to deal with dynamic pages.
    *
    * Some sites I (Mark) have tested have required a page refresh to add additional elements to the DOM. 
    * Generally you (Chon) wouldn't need to do this in a typical AJAX scenario.
    *
    * @param WebDriver  The driver object to use to perform this element search
    * @param locator  selector to find the element
    * @param int  The time in seconds to wait until returning a failure
    *
    * @return WebElement  the first WebElement using the given method, or null(if the timeout is reached)
    *
    * @author Mark Collin
    */
   public static WebElement waitForElementRefresh(WebDriver driver, final By by,
                                 int timeOutInSeconds) {
    WebElement element;
    try
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
            new WebDriverWait(driver, timeOutInSeconds) {
            }.until(new ExpectedCondition<Boolean>() {

                @Override
                public Boolean apply(WebDriver driverObject) {
                    driverObject.navigate().refresh(); //refresh the page ****************
                    return isElementPresentAndDisplay(driverObject, by);
                }
            });
        element = driver.findElement(by);
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return element; //return the element
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
   }
  
  /**
    * Wait for the Text to be present in the given element, regardless of being displayed or not.
    *
    * @param WebDriver  The driver object to be used to wait and find the element
    * @param locator  selector of the given element, which should contain the text
    * @param String  The text we are looking
    * @param int  The time in seconds to wait until returning a failure
    *
    * @return boolean
    */
  public static boolean waitForTextPresent(WebDriver driver, final By by, final String text, int timeOutInSeconds) {
    boolean isPresent = false;
    try
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
          new WebDriverWait(driver, timeOutInSeconds) {
          }.until(new ExpectedCondition<Boolean>() {
 
              @Override
              public Boolean apply(WebDriver driverObject) {
                return isTextPresent(driverObject, by, text); //is the Text in the DOM
              }
          });
          isPresent = isTextPresent(driver, by, text);
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return isPresent;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }
 



  /**
   * Waits for the Condition of JavaScript. 
   *
   *
   * @param WebDriver    The driver object to be used to wait and find the element
   * @param String  The javaScript condition we are waiting. e.g. "return (xmlhttp.readyState >= 2 && xmlhttp.status == 200)"
   * @param int  The time in seconds to wait until returning a failure
   *
   * @return boolean true or false(condition fail, or if the timeout is reached)
   **/
  public static boolean waitForJavaScriptCondition(WebDriver driver, final String javaScript,
                               int timeOutInSeconds) {
    boolean jscondition = false;
    try
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
          new WebDriverWait(driver, timeOutInSeconds) {
          }.until(new ExpectedCondition<Boolean>() {
 
              @Override
              public Boolean apply(WebDriver driverObject) {
                return (Boolean) ((JavascriptExecutor) driverObject).executeScript(javaScript);
              }
          });
          jscondition =  (Boolean) ((JavascriptExecutor) driver).executeScript(javaScript);
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return jscondition;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }

 
  /** Waits for the completion of Ajax jQuery processing by checking "return jQuery.active == 0" condition. 
   *
   * @param WebDriver - The driver object to be used to wait and find the element
   * @param int - The time in seconds to wait until returning a failure
   *
   * @return boolean true or false(condition fail, or if the timeout is reached)
   * */
  public static boolean waitForJQueryProcessing(WebDriver driver, int timeOutInSeconds){
    boolean jQcondition = false;
    try
      driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
          new WebDriverWait(driver, timeOutInSeconds) {
          }.until(new ExpectedCondition<Boolean>() {
 
              @Override
              public Boolean apply(WebDriver driverObject) {
                return (Boolean) ((JavascriptExecutor) driverObject).executeScript("return jQuery.active == 0");
              }
          });
          jQcondition = (Boolean) ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0");
      driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
      return jQcondition;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return jQcondition;
    }
 

  /**
   * Coming to implicit wait, If you have set it once then you would have to explicitly set it to zero to nullify it -
   */
  public static void nullifyImplicitWait(WebDriver driver) {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
  }
 

  /**
   * Set driver implicitlyWait() time.
   */
  public static void setImplicitWait(WebDriver driver, int waitTime_InSeconds) {
    driver.manage().timeouts().implicitlyWait(waitTime_InSeconds, TimeUnit.SECONDS)
  }
 
  /**
   * Reset ImplicitWait. 
   * To reset ImplicitWait time you would have to explicitly
   * set it to zero to nullify it before setting it with a new time value.
   */
  public static void resetImplicitWait(WebDriver driver) {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
    driver.manage().timeouts().implicitlyWait(DEFAULT_WAIT_4_PAGE, TimeUnit.SECONDS); //reset implicitlyWait
  }
 

  /**
   * Reset ImplicitWait. 
   * @param int - a new wait time in seconds
   */
  public static void resetImplicitWait(WebDriver driver, int newWaittime_InSeconds) {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS); //nullify implicitlyWait()
    driver.manage().timeouts().implicitlyWait(newWaittime_InSeconds, TimeUnit.SECONDS); //reset implicitlyWait
  }
       

     /**
     * Checks if the text is present in the element.
       *
     * @param driver - The driver object to use to perform this element search
     * @param by - selector to find the element that should contain text
     * @param text - The Text element you are looking for
     * @return true or false
     */
  private static boolean isTextPresent(WebDriver driver, By by, String text)
  {
    try {
        return driver.findElement(by).getText().contains(text);
    } catch (NullPointerException e) {
        return false;
    }
  }
   

  /**
   * Checks if the elment is in the DOM, regardless of being displayed or not.
   *
   * @param driver - The driver object to use to perform this element search
   * @param by - selector to find the element
   * @return boolean
   */
  private static boolean isElementPresent(WebDriver driver, By by) {
    try {
      driver.findElement(by);//if it does not find the element throw NoSuchElementException, which calls "catch(Exception)" and returns false;
      return true;
    } catch (NoSuchElementException e) {
      return false;
    }
  }
 

  /**
   * Checks if the List<WebElement> are in the DOM, regardless of being displayed or not.
   *
   * @param driver - The driver object to use to perform this element search
   * @param by - selector to find the element
   * @return boolean
   */
  private static boolean areElementsPresent(WebDriver driver, By by) {
    try {
      driver.findElements(by);
      return true;
    } catch (NoSuchElementException e) {
      return false;
    }
  }

  /**
   * Checks if the elment is in the DOM and displayed.
   *
   * @param driver - The driver object to use to perform this element search
   * @param by - selector to find the element
   * @return boolean
   */
  private static boolean isElementPresentAndDisplay(WebDriver driver, By by) {
    try {     
      return driver.findElement(by).isDisplayed();
    } catch (NoSuchElementException e) {
      return false;
    }
  }
 

 
}
/*
* References:
* 1. Mark Collin's post on: https://groups.google.com/forum/?fromgroups#!topic/webdriver/V9KqskkHmIs%5B1-25%5D
*     Mark's code inspires me to write this class. Thank you! Mark.
* 2. Andre, and Tarun Kumar's post on: https://groups.google.com/forum/?fromgroups=#!topic/selenium-users/6VO_7IXylgY 
* 3. Explicit and Implicit Waits: http://seleniumhq.org/docs/04_webdriver_advanced.html
*
* Note:
* 1. Instead of creating new WebDriverWait() instance every time in each methods,
*    I tried to reuse a single WebDriverWait() instance, but I found and tested
*    that creating 100 WebDriverWait() instances takes less than one millisecond.
*    So, it seems not necessary. 
*/ 
TOP

Related Classes of wtbox.util.WaitTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.