This post could have been “Reliable Selenium locators” since this is always a point of interrest, but the topic is covered regularly and a google search will get you a good result easily. However some specific cases are not that widely discussed, as I discovered in my latest assignment.

The assignment is pretty straightforward, the system under test is migrating to a new front-end and the company grabs this opportunity to introduce an automated test strategy. I’m hired to do the actual set up of the automation framework. The new front-end is ExtJs based and for me it’s the first time automating an ExtJs application with Selenium.

After some research and getting to know the application I discovered that ExtJs re-generates unique id’s for all elements, so a simple WebDriverBy(id) will not suffice. Looking at the structure xpath’s will result in long, cluttered and leaning towards brittle. So I started some google adventures and what I found was not promising.

The top three results (skipping Sencha results) are motivators to not use Selenium as the automation tool for ExtJs applications, which is not going to fly with me since I believe in Selenium for browser applications.

I went to the root of the “problem” and ended up in the docs of ExtJs and found a little gem in there “Ext.ComponentQuery“. It is the internal component locator for ExtJs, it’s capable of finding components on the page and retrieving information, like the current id. Selenium is capable of running javascript, so I did a 1+1=2 and settled for the following locator strategy:

// Note, not production code, but shows the main idea.

// Initialize a new object of type Button
// Give it the unique ExtJs locator 
// Can be anything from name, value, structure
$myButton = new Button("nextItemButton");

// Use click function of Button
$myButton->click();

class Button {
  // Will hold the changable id to use by Selenium
  protected $seleniumLocator;

  public function __construct($extJsLocator)
  {
    $this->seleniumLocator = getLocator($extJsLocator);
  }

  // Execute the ComponentQuery to get the current id
  private function getLocator($loc)
  {
    return $driver->executeScript(
    "return Ext.ComponentQuery.query('button[$loc]')"
    );
  }

  // Use the current id as selector in Selenium
  public function click()
  {
      $driver->findElement(WebDriverBy::id($this->seleniumLocator))->click();
  }
}

Are you starting out with test automation and thinking about Selenium? Or are you already automating tests with Selenium and feel bogged down by your programming language of choice? You’re not alone.

In my line of work I find myself answering the following questions quite frequently:

What programming language is best for Selenium automation?

I don’t know Java, can I still use Selenium WebDriver?

The answers might not be as clear as some might think. Sure the WebDriver bindings originate from Java, so this might sound like the first choice. But what if you don’t like working with Java or your work environment doesn’t play nice with Java.
The bindings are ported to quite a few programming languages and widely used, so you might think the answer to “what is the best?” is as simple as “Use whatever language you like best” (of the ported languages). But is this really true?

For me it was a no brainer to pick Java when I started out. I had some experience with Java and the information on Java-Selenium WebDriver is widely available.

Over the course of a couple test automation jobs I shifted away from the seemingly obvious answers and started thinking a bit further. The first incentive to reassess my answers came when I was forced to use a Python implementation of Selenium. I was not fluent in Python and I had a hard time enjoying my day to day work. I like finding “enemies” on my automation adventures, but not at the level I can’t start a fair battle. I felt bogged down by Python, it’s not for me.

Another insight came when I was using PHP (facebook php-webdriver) for an implementation. The client wanted to use Page Objects, which is fine, but I was used to Page Objects in Java. In Java you also get to use the Page Factory support package which makes using the Page Objects a fluent experience. In PHP Page Objects can be used, but the Page Factory is not available. There is an old implementation available, but I didn’t feel like maintaining a fork of this repository for this assignment. I’m not saying the PHP bindings are a bad port, but a port at best. There are no guarantees.

So what are my answers?

It depends. You need to take into account all variables which are involved and assign a relative value to each:

– What language is used to create the application under test?
– How proficient are you in the available languages?
– Do you wish to learn a new language?
– What are the time frames for the assignment?
– Are you working alone? Who will be working with your automation set up?
– Might you need a package which is not readily available?

This list is not complete for all assignments, but it should give an idea of what to think about.

Ever had your test break because of “StaleElementReferenceException”? There can be a couple of reasons this happens:

  1. The element has been deleted entirely. (For example after a page refresh)
  2. The element is no longer attached to the DOM. (For example with tabbed ui’s, certain tabs are not displayed until needed)
  3. The element changes type, but keeps the same locator semantics. (For example on focus a textfield gets set as password field by Javascript)

All good and fun, but breaking tests for whatever reason need to be avoided. By using the code snippet below in your element locating method you can gracefully handle “StaleElementReferenceException”. The logic for how you want to handle the exception should be placed in the catch.

public boolean isStale(WebElement element) 
{
    try {
        element.isEnabled();
        return false;
    } catch (StaleElementReferenceException sere) {
        return true;
    }
}