Total Pageviews

Monday, January 2, 2012

How to use JQuery instead of Xpath in Selenium.


To identify objects, generally we use Xpath, CSS and DOM. If we are going with FF, we will use Xpath. It will works tremendously slowly in IE 6 and IE 7.
To solve the speed in IE, we can use css or JQuery also.

see the below mentioned code:
<table class="style">
    <tr class="somestyle">
        <td>SomeName1</td>
        <td>
            <input type="submit" value="Edit" class="btn" />
        </td>
    </tr>
    <tr class="gvAlternatingRowH35">
        <td>SomeName2</td>
        <td>
            <input type="submit" value="Edit" class="btn" />
        </td>
    </tr>
</table>

Here all the buttons are having the same name,  If you want to click the “Edit” button next to SomeName2, you can easily complete this task in selenium by using XPath and its parent feature:

selenium.click("//td[text()='SomeName2']/../td/input[@value='Edit']")

As we mentioned above, this won’t be that easy to do with CSS because it doesn’t have the appropriate feature. So, we used the JQuery parent() function to have the ability to select the parent of the current node. It works really fast in all browsers, since JQuery uses CSS.

by adding the query's library to the selenium server and execute JQuery script directly from selenium and find the objects easily. To execute JQuery script, you can use selenium.getEval(someJS) if you need the return value, or selenium.runScript(someJS) if you don’t.


1. Add Jquery’s library to Selenium server.

Add JQuery’s library (‘jquery.min.js’) to your selenium-server.jar (‘selenium-server.jar\core\scripts\’ folder). To do that, open ‘selenium-server.jar’ by using one of the archives — for example, 7-Zip — and drag-and-drop ‘jquery.min.js’ in the mentioned folder.


2. Add script reference to JQuery library.

Add script reference to ‘jquery.min.js’ to the ‘<head>’ section of the RemoteRunner.html (‘selenium-server.jar\core\’).

<head>
...
<script language="JavaScript" type="text/javascript" src="scripts/jquery.min.js" />
...
<\head>

3. Add new JQuery locator to Selenium core.

You can add a new JQuery locator to the Selenium core in the runSeleniumTest() function of the selenium-remoterunner.js file. All you need to do is to add a call of selenium.doAddLocationStrategy() method before Selenium property initialization of the window object. See the sample below for more details.

function runSeleniumTest() {
    ...
    selenium.doAddLocationStrategy("jquery", "
var loc = locator;
var attr = null;
var isattr = false;
var inx = locator.lastIndexOf('@');

if (inx != -1) {
    loc = locator.substring(0, inx);
    attr = locator.substring(inx + 1);
    isattr = true
}

var selectors = loc.split('<');
var found = $(inDocument);

for (var i = 0; i < selectors.length; i++) {
    if (i > 0) {found = $(found.parents()[0]);
}

if (jQuery.trim(selectors[i]) != '')
    found = found.find(selectors[i]);
}

if (found.length > 0) {
    if (isattr) {
        return found[0].getAttributeNode(attr);
    }
    else {
        return found[0];
    }
}
else {
    return null;
}
    ");
    ...
}

The first parameter of the selenium.doAddLocationStrategy method (“JQuery”) is the new Selenium locator’s name. The second one (“var loc = locator…”) is the new custom Selenium locator. If you want to, you can write your own implementation for the locator. To call the JQuery parent() function, we used the '<' custom symbol .

Finally, let’s take a look at how you can use the new JQuery locators, instead of the XPath ones.

XPath locators:
•    xpath=//a[contains(@href,'#id1')]
•    xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td
•    xpath=//input[@name='name2' and @value='yes']

JQuery locators:
•    jquery= a[href*='#id1']
•    jquery= table[class='stylee'] th:contains('theHeaderText')<td
•    jquery= input[name='name2'][value='yes']