Mar 31

Highlighting Elements in Selenium WebDriver

I’ve decided to write smaller blog entries for a while as I have such a huge backlog of things I’d like to put on here.

So today I’d like to introduce how to highlight elements in the browser using Selenium WebDriver (Java).

Rather than simply explaining how it’s done and giving some code snippets, I’ve also included the functionality in a small Java project that uses my favourite test runner – JBehave. This way, you can build the project yourself, see a “real-life” example and tinker with it.

I’d like to thank Iain for his blog post on highlighting elements.

Getting Started

First of all – if you are building an automation framework at your organisation – it’s a good idea to route all calls to the WebDriver API through a bespoke common library. I’ve discussed at length why I think this is a good idea but here’s a few more reasons:

  • It helps enforce standards inside your organisation. Flexibility is a good thing but do you really want people using your framework to select elements using findElement.By.partialLinkText rather than an Xpath or CSS Selector? A restrictive approach does not necessarily stifle innovation.
  • It can vastly reduce code.
  • It increases code readability.
  • Particularly difficult things to automate (e.g. hover and click, drag and drop) can be used again and again by different project teams.
  • A solid common library makes tests more stable as it is harder to introduce silly errors into your code.
  • It is much much easier to update common methods with the latest API additions and best practise.

We need two methods to achieve our aim.

First, we need to create a setAttribute() method similar to the WebDriver getAttribute() method. The WebDriver API does not have this built in because it is specifically designed to mimic the user’s interactions with the browser – and the user cannot change attribute values (through “normal” use).

The definition of this method depends on your setup. You need to cast your WebDriver instance to JavaScriptExecutor for it to work.

If you use JBehave like I do then WebDriverPage casts the WebDriver instance to JavaScriptExecutor for you already. Like so:

    public Object executeScript(String s, Object... args) {
        makeNonLazy();
        return ((JavascriptExecutor) webDriver()).executeScript(s, args);
    }

So we can call executeScript() directly in our method without worrying about casting it first.

  /**
   * Set an attribute in the HTML of a page.
   * 
   * @param element
   *          The WebElement to modify
   * @param attributeName
   *          The attribute to modify
   * @param value
   *          The value to set
   */
  private void setAttribute(WebElement element, String attributeName, String value) {
    executeScript("arguments[0].setAttribute(arguments[1], arguments[2])", element, attributeName, value);
  }

If you don’t use JBehave then this should do the trick:

  /**
   * Set an attribute in the HTML of a page.
   * 
   * @param driver 
   *          The WebDriver you are using
   * @param element
   *          The WebElement to modify
   * @param attributeName
   *          The attribute to modify
   * @param value
   *          The value to set
   */
  private void setAttribute(WebDriver driver, WebElement element, String attributeName, String value) {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("arguments[0].setAttribute(arguments[1], arguments[2])", element, attributeName, value);
  }

Now we just need to create a highlight method that uses setAttribute().

  /**
   * Highlight an element in the UI.
   * 
   * @param element
   *          The WebElement to highlight
   */
  private void highlight(WebElement element) {
    final int wait = 75;
    String originalStyle = element.getAttribute("style");
    try {
      setAttribute(element, "style",
          "color: yellow; border: 5px solid yellow; background-color: black;");
      Thread.sleep(wait);
      setAttribute(element, "style",
          "color: black; border: 5px solid black; background-color: yellow;");
      Thread.sleep(wait);
      setAttribute(element, "style",
          "color: yellow; border: 5px solid yellow; background-color: black;");
      Thread.sleep(wait);
      setAttribute(element, "style",
          "color: black; border: 5px solid black; background-color: yellow;");
      Thread.sleep(wait);
      setAttribute(element, "style", originalStyle);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

It’s not the prettiest code but the effect is pretty cool.

You could parametrise the colours if you wanted to. I also feel that the wait time is enough to clearly notice what’s going on without slowing tests down.

Using it in your code.

OK so let’s see the code in action.

As I mentioned earlier, I built a small Java project for this which is available at my public GitHub repository. You just need Maven and Firefox installed.

Simply follow the running instructions to see the highlight method in action while searching for things on Amazon.