Saturday, December 21, 2013

Finding web elements by executing JQuery script

WebDriver provides findElement(By by) to find elements by selectors such as Xpath, CSS, name, id, class name etc. Similar way, we can use JQuery expression to select elements and traverse through the DOM tree. 
Here is a simple way to findout, 
For an input element with class 'spbtn' of a parent element with id 'myDiv', we can use the below code to find the web element:
String jQuerySelector = "'#myDiv input.spbtn'";
WebElement webElement = (WebElement) ((JavascriptExecutor) getDriver()).executeScript("return $(" + jQuerySelector+ ").get(0);");
In the other way, we can use the following code which uses a proper wait with optimized way to find out the element. The method throws NoSuchElementException exception if there is no element with this JQuery selector.
/**
 * Finds an element by executing the given jQuery statement
 * jQueryScript
 * 
 * @param jQueryScript
 *            a JQuery Script
 * @return WebElement that is described by that jQuery statement
 *         jQueryScript, if not found, returns null.
 */
public WebElement findElementByJQuery(final String jQueryScript) {
 WebElement element = null;

 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
   .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
   .pollingEvery(50, TimeUnit.MILLISECONDS)
   .ignoring(NoSuchElementException.class);
 try {
  element = wait.until(new Function<WebDriver, WebElement>() {
   @Override
   public WebElement apply(WebDriver d) {
    String script = "return " + jQueryScript + ".get(0);";
    JavascriptExecutor jse = (JavascriptExecutor) d;
    WebElement webElement = (WebElement) jse
      .executeScript(script);
    return webElement;
   }
  });
 } catch (Exception e) {
  log.error("Failed to find the element by executing JQuery script '"
    + jQueryScript + "'." + e);
 }
 return element;
}
Usage of the above method:
For an element with JQuery selector '#myDiv input.spbtn'
String aJQueryString = "jQuery(\"div.sorted\")";//To get the element
String aJQueryString = "jQuery(\"div.sorted\").parent()";//To get parent of the element
String aJQueryString = "jQuery(\"div.sorted\").mouseover()";//To mouseover on the element

WebElement element = findElementByJQuery(aJQueryString);
Similar way you can use other JQuery functions to work with web elements.

To find all elements with the given JQuery selector. This is similar to findElements(By by) of WebDriver.
/**
 * Find all the elements by executing the given jQuery statement
 * jQueryScript
 * 
 * @param jQueryScript
 *            a JQuery Script 
 * @return WebElement that is described by that jQuery statement
 *         jQueryScript, if not found, returns null.
 */
public List<WebElement> findElementsByJQuery(final String jQueryScript) {
 List<WebElement> elements = null;

 Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
   .withTimeout(timeoutSeconds, TimeUnit.SECONDS)
   .pollingEvery(50, TimeUnit.MILLISECONDS)
   .ignoring(NoSuchElementException.class);
 try {
  elements = wait.until(new Function<WebDriver, List<WebElement>>() {
   @Override
   public List<WebElement> apply(WebDriver d) {
    List<WebElement> webElements = new ArrayList<WebElement>();
    for (int i = 0;; i++) {
     String script = "return " + jQueryScript + ".get(" + i
       + ");";
     JavascriptExecutor jse = (JavascriptExecutor) d;
     WebElement webElement = (WebElement) jse
       .executeScript(script);
     if (webElement != null) {
      webElements.add(webElement);
     } else {
      break;
     }
    }
    return webElements;
   }
  });
 } catch (Exception e) {
  log.error("Failed to find the elements by executing JQuery script '"
    + jQueryScript + "'." + e);
 }
 return elements;
}

3 comments:

  1. Does it support xpath as well ? I mean can we use xpath as well ?

    ReplyDelete
    Replies
    1. This needs a JQuery string input only. CSS works very well as JQuery recognizes it. XPath won't work.
      But you can find CSS for almost every XPath, so try to use CSS in this case. If you need any help on finding let me know.

      Delete
  2. Thanks Aswini Kumar, Bookmarked and shared with my colleagues

    ReplyDelete