My favorites | Sign in
Logo
                
Search
for
Updated Oct 28, 2009 by matt.senter
Labels: Phase-Design, Phase-Support
TelluriumjQuerySelector  
Tellurium jQuery Selector Guide.

Introduction

Starting with version 0.6.0, Tellurium will support a jQuery selector to address the problem of poor performance of xpath in Internet Explorer. Auto-generating jQuery instead of xpath has the following advantages:

  1. Faster performance in IE
  2. We are able to use the power of jQuery to call methods on jQuery collections to retrieve bulk data
  3. We will eventually be able to convert selenium browser-bot to use jQuery

Performance Comparison

To test the performance of our jQuery Selector, we create a Benchmark project at

http://aost.googlecode.com/svn/branches/test-benchmark

We use the following three different locators in the project

  1. XPath using Ajaxslt library
  2. XPath using Javascript library
  3. jQuery Selector

The tests are created from Tellurium Issues page and include three sets

  1. A series of test flow including issue search and issue data access
  2. Similar to the first one but without group locating in UI modules
  3. Access data from the issue table (limit the size to 20 rows and 10 columns)

We run the benchmark in Firefox 3 and IE 7 ten times and calculate the average times. To reduce the effects from network latency and page loading, we do not count the time for methods such as opening page and waitForPageLoad. The test results are listed in the following table,

Locator Browser TestFlow NoGroup Bulk Data
Ajaxslt XPath FF 3 64.78 58.95 165.93
Ajaxslt XPath IE 7 138.23 133.13 475.82
Javascript XPath FF 3 62.39 59.82 164.23
Javascript XPath IE 7 132.89 131.20 470.57
jQuery Selector FF 3 61.75 59.60 0.159
jQuery Selector IE 7 78.60 72.97 0.239

where the time unit is second.

The following chart shows the results for Firefox 3,

and chart for IE 7 is as follows,

Although, the results only show the performance for our Benchmark, we can still observe that:

  1. jQuery selector is as fast as Ajaxslt XPath and Javascript XPath in Firefox 3.
  2. jQuery selector is much faster in IE 7 than the two XPath libraries
  3. jQuery selector uses only one method call to get back data for all table cells and thus it is the fastest one for bulk data access.

Brief Overview of how to Use the jQuery Selector

Tellurium automatically builds runtime xpath or jQuery selector based on a flag exploreJQuerySelector in DslContext, which is false by default. To use jQuery selector, you should call

useJQuerySelector()

and use

disableJQuerySelector()

to go back to XPath as shown in the following diagram.

Some of the jQuery functions are provided by the custom selenium server, which is created by our Tellurium Engine project. Be aware that jQuery selector only works for composite locator, i.e., clocator. If you have base locator, which is xpath, then the jQuery selector will not work for you.

How Does the jQuery Selector Work ?

The basic idea is to customize Selenium Core to load the jQuery library at startup time. You can add jquery.js in to the TestRunner.html and RemoteRunner.html. Another way is dump all jquery.js into user-extensions.js. Since our Engine prototype customizes Selenium core anyway, we used the former method.

After that, we register a custom locate strategy "jquery", using the following Selenium API call:

addLocationStrategy ( strategyName,functionDefinition )
This defines a new function for Selenium to locate elements on the page. For example,

if you define the strategy "foo", and someone runs click("foo=blah"), we'll run your function, passing you the string "blah", and click on the element that your function returns, or throw an "Element not found" error if your function returns null. Selenium passed three arguments to the location strategy function:

The function must return null if the element can't be found.

Arguments:

Accordingly, we define the custom locate strategy as follows,

addLocationStrategy("jquery", '''
  var found = $(inDocument).find(locator);
  if(found.length == 1 ){
    return found[0];
  }else if(found.length > 1){
    return found.get();
  }else{
    return null;
  }
''')

The code is pretty straightforward. When we find one element, return its DOM reference (Note: Selenium does not accept returning an array with only one element) and if we find multiple elements, we use jQuery get() method to return an array of DOM references. Otherwise, return null.

The actual code is a bit more complicated because we need to consider our custom attribute locator. We use the same format of attribute locator as the XPath one, i.e.,

locator@attribute

Apart from that, we need to create a set of custom Selenium methods and add the appropriate Selenium RC Java methods. For example, we created the following Selenium method

Selenium.prototype.getAllText = function(locator){
  var $e = $(this.browserbot.findElement(locator));
  var out = [];
  $e.each(function(){
     out.push($(this).text());
  });

  return JSON.stringify(out);
};

Then, created the corresponding Java method by extending Selenium

class CustomSelenium extends DefaultSelenium {

  def String getAllText(String locator){
     String[] arr = [locator];
     String st = commandProcessor.doCommand("getAllText", arr);
     return st;
  }
}

New Features Provided by jQuery Selector

The most important feature is that Tellurium automatically generates the runtime jQuery selector based on your UI module definition, more specifically, the composite locator clocator. Tellurium also supports group locating for jQuery Selector by using jQuery :has() pseudo class and multiple selectors. For example, the following UI module

ui.Container(uid: "Google", clocator: [tag: "table"], group: "true") {
   InputBox(uid: "Input", clocator: [tag: "input", title: "Google Search", name: "q"])
   SubmitButton(uid: "Search", clocator: [tag: "input", type: "submit", value: "Google Search", name: "btnG"])
   SubmitButton(uid: "ImFeelingLucky", clocator: [tag: "input", type: "submit", value: "I'm Feeling Lucky", name: "btnI"])
}

could produce the jQuery selector with group locating as follows,

jquery=table:has(input[title=Google Search][name=q], input[type=submit][value=Google Search][name=btnG], input[type=submit][value$=m Feeling Lucky][name=btnI]) input[title=Google Search][name=q]

jQuery Selector provides the following additional Selenium methods, which are utilized in DslContext to form a set of new DSL methods:

  1. String getAllText(String locator): Get all text from the set of elements corresponding to the jQuery Selector.
  2. String getCSS(String locator, String cssName): Get the CSS properties for the set of elements corresponding to the jQuery Selector.
  3. Number getJQuerySelectorCount(String locator): Get the number of elements matching the corresponding jQuery Selector
  4. boolean isDisabled(String locator): Test if an element is disabled.

jQuery supports the following attribute selectors

Tellurium supports all the attribute selectors, that is to say, it looks at the prefix of the value and converts them to the appropriate attribute selectors if the values include either '!', '^', '$', or '*'. Be aware Tellurium partial matching symbol "%%" is depreciated. Please use the new symbols. The are something you should be aware of for jQuery Selector:

New DslContext Methods

Tellurium provides a set of locator agnostic methods, i.e., the method will automatically decide to use XPath or jQuery dependent on the exploreJQuerySelector flag, which can be turn on and off by the following two methods:

public void useJQuerySelector()

public void disableJQuerySelector()

In the meanwhile, Tellurium also provides the corresponding XPath specific and jQuery selector specific methods for your convenience. However, we recommend you to use the locator agnostic methods until you have a good reason not to.

The new methods are listed here:

Get the Generated locator from the UI module

Locator agnostic:

JQuery selector specific:

XPath specific:

Get the Number of Elements matching the Locator

Locator agnostic:

JQuery selector specific:

XPath specific:

Table methods

Locator agnostic:

JQuery selector specific:

XPath specific:

Check if an Element is Disabled

Locator agnostic:

JQuery selector specific:

XPath specific:

Get the Attribute

Locator agnostic:

Check the CSS Class

Locator agnostic

Get CSS Properties

JQuery selector specific:

  • String getCSS(String uid, String cssName)

Get All Data from a Table

JQuery selector specific:

  • String getAllTableCellText(String uid)
  • String getAllTableCellTextForTbody(String uid, int index)

Get List Size

Locator agnostic:

JQuery selector specific:

XPath specific:

jQuery Selector Cache Option

Tellurium offers jQuery selector cache option to further improve the test speed. You can find more details in The Cache Mechanism of jQuery Selector.

How to Obtain the jQuery Selector Support

Tellurium Engine project starts to build a custom selenium-server.jar, you can download it from Tellurium project subversion trunk/core/lib or from Tellurium user group. But the best way is to use Maven.

The two Tellurium archetypes are updated to support jQuery selector. You can use them to create a Tellurium test project. For JUnit project, use the following Maven command

mvn archetype:create -DgroupId=Your_Group_ID -DartifactId=Your_Artifact_ID \
-DarchetypeArtifactId=tellurium-junit-archetype -DarchetypeGroupId=tellurium \
-DarchetypeVersion=1.0-SNAPSHOT -DarchetypeRepository=http://maven.kungfuters.org/content/repositories/snapshots 

Then go to the project and run the test

mvn test

For TestNG project, you should use the tellurium-testng-archetype

mvn archetype:create -DgroupId=Your_Group_ID -DartifactId=Your_Artifact_ID \
-DarchetypeArtifactId=tellurium-testng-archetype -DarchetypeGroupId=tellurium \
-DarchetypeVersion=1.0-SNAPSHOT -DarchetypeRepository=http://maven.kungfuters.org/content/repositories/snapshots

If you want to manually add Maven dependencies, use this sample POM as a reference.

Reference Materials


Sign in to add a comment
Hosted by Google Code