Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium WebDriver jQuery

I'm very new to Selenium WebDriver and I'm learning how to use jQuery selectors to work with elements instead of using XPath expressions, IDs, etc...

Could you please help me by providing a link where I can find some basic information on how to use jQuery in Selenium WebDriver?

like image 444
Venkatesh Lakshmanan Avatar asked Jul 09 '13 18:07

Venkatesh Lakshmanan


People also ask

Can we use jQuery in selenium?

Selenium WebDriver can be enhanced by jQuery selectors using the jQuery API. However, we need to make sure that the page has jQuery API loaded before using these selectors. The jQuery API provides the find() function through which we can search for elements.

Can I use JavaScript with selenium WebDriver?

Selenium WebDriver with JavaScript is a favorable combination to perform automated UI testing of applications. JavaScript offers efficiency with its well-built and structured patterns and functions, making the script more compact. It offers security and is well supported by a large community of developers.

What is jQuery best for?

The purpose of jQuery is to make it much easier to use JavaScript on your website. jQuery takes a lot of common tasks that require many lines of JavaScript code to accomplish, and wraps them into methods that you can call with a single line of code.


2 Answers

You shoudn't. JQuery selectors offer most of what CSS 2 and CSS 3 selectors do, plus something more, but you can probably live without it. If you know JQuery selectors, you already know CSS selectors.

Use CSS selectors where you can and use XPath expressions where it's not enough (they're stronger). I doubt you'll find many real usages where these two aren't enough (and then, the usual approach is to get what you can and iterate over the collection, filtering the results manually).


That said, you could possibly force WebDriver to accept JQuery selectors, too:

If you only want to support one or two browsers, the easiest way might be to write a simple addon to that browser which would inject JQuery to every page if it's not already present. You'd then force this addon to be used by the browser you're using.

If you want to support all of the browsers, that solution quickly becomes a burden and the best you could do is to write a decorator for WebDriver that would try to inject JQuery into the page before any findElements() and/or executeScript() call, if it's not already present.

See this question to get an idea about injecting JQuery.

After you've injected it, you can use it, again, only via JavaScript:

// earlier
if (driver instanceof JavascriptExecutor) {
    js = (JavascriptExecutor)driver;
} else {
    throw new IllegalStateException("This driver cannot run JavaScript.");
}

WebElement element = (WebElement)js.executeScript("$('div.account').get(0)");
// or
List<WebElement> elements = (List<WebElement>)js.executeScript("$('div.account').get()");

You can easily wrap those lines into a new By object, or a new findElement(String jQuerySelector) method for your decorated WebDriver, if you want, but that's up to your convenience and laziness, we got it working...


The best approach, I think, would be to create a new By implementation called ByJQuery. See this answer on how to make a ByJavaScript - it's a small step from there to reuse it, inject JQuery into the page and run the actual query.

class ByJQuery extends By implements Serializable {
    private final String query;

    public ByJQuery(String query) {
        checkNotNull(query, "Cannot find elements with a null JQuery expression.");
        this.query = query;
    }

    @Override
    public List<WebElement> findElements(SearchContext context) {
        WebDriver driver = getWebDriverFromSearchContext(context);

        if (!isJQueryInThisPage(driver)) {
            injectJQuery(driver);
        }

        return new ByJavaScript("return $(" + query + ")").findElements(context);
    }

    private static WebDriver getWebDriverFromSearchContext(SearchContext context) {
        if (context instanceof WebDriver) {
            return (WebDriver)context;
        }
        if (context instanceof WrapsDriver) {
            return ((WrapsDriver)context).getWrappedDriver();
        }
        throw new IllegalStateException("Can't access a WebDriver instance from the current search context.");
    }

    private static boolean isJQueryInThisPage(WebDriver driver) {
        // TODO Some JavaScript test for a JQuery object.
    }

    private static void injectJQuery(WebDriver driver) {
        // TODO Load JQuery from a file, inject it into the page via JS.
    }

    @Override
    public String toString() {
        return "By.jQuery: \"$(" + query + ")\"";
    }
}
like image 181
Petr Janeček Avatar answered Sep 28 '22 06:09

Petr Janeček


iWebdriver jQuery Extension, This will work across all browsers. Copy and paste to your webdriver extension.

  public static IWebElement FindByTextJQuery(this IWebDriver driver, string Tagname, string Text)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        bool flag = (bool)js.ExecuteScript("return typeof jQuery == 'undefined'");
        if (flag)
        {
            js.ExecuteScript("var jq = document.createElement('script');jq.src = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';document.getElementsByTagName('head')[0].appendChild(jq);");
        }
        driver.WaitForAjax();
        js.ExecuteScript("$('" + Tagname + ":contains(" + Text + ")').css('background-color', '')");
        IWebElement elements = (IWebElement)js.ExecuteScript(@"return $('"+Tagname+":contains("+Text+")')[0]");
        return elements;
    }

 public static string getTextByJquery(this IWebDriver driver, string jquery)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        string elementsText = (string)js.ExecuteScript("return $('" + jquery +    "').text()");
        return elementsText;
    }

 public static int returnIndexByJquery(this IWebDriver driver, string jQuery)
    {

        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        bool flag = (bool)js.ExecuteScript("return typeof jQuery == 'undefined'");
        if (flag)
        {
            js.ExecuteScript("var jq = document.createElement('script');jq.src = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';document.getElementsByTagName('head')[0].appendChild(jq);");
        }
        driver.WaitForAjax();
      //  js.ExecuteScript(@"return $('" + Tagname + ":contains(" + Text + ")').css('background-color', 'blue')");
        Int64 elementIndex = (Int64)js.ExecuteScript(@"return $('"+jQuery+"').index()[0]");
        return Convert.ToInt32(elementIndex);                     
    }

   public static int returnCountByJquery(this IWebDriver driver, string jQuery)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        bool flag = (bool)js.ExecuteScript("return typeof jQuery == 'undefined'");
        if (flag)
        {
            js.ExecuteScript("var jq = document.createElement('script');jq.src = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';document.getElementsByTagName('head')[0].appendChild(jq);");
        }
        driver.WaitForAjax();
        //  js.ExecuteScript(@"return $('" + Tagname + ":contains(" + Text + ")').css('background-color', 'blue')");
        Int64 elementCount = (Int64)js.ExecuteScript(@"return $('" + jQuery + "').size()");
        return Convert.ToInt32(elementCount);
    }
like image 26
user3644719 Avatar answered Sep 28 '22 07:09

user3644719