TwinTechs

Dream, Create, Deliver…

Adding XPATH support for SafariWatir

April 28th, 2009 · 1 Comment · Mobile Devices, RIA, iPhone/iPod Touch

Recently, I was tasked with writing automated functional tests for a web app we were developing. We first had to decide what platform/browser we wanted to test. The target platform for the app was actually an iPhone. As we knew of no tools to run automated functional tests on an iPhone, we decided the best approach would be to run our tests on Safari on  Mac. The tool we picked to develop the tests was SafariWatir, a port of the Watir tool to OS X on Mac driving Safari.

Everything seemed well until I realized that SafariWatir does not support retrieving elements from the browser document via XPATH. This was a significant minus. Not having XPATH support means test writers have to look up the document element they need by id, element text, or some other less flexible method. Furthermore, one cannot rely on elements always having ids or unique names defined.

Fortunately, we have XPATH to solve this problem. Safari has native JavaScript support for resolving XPATH to select document elements, so it was relatively easy to patch SafariWatir to allow us to fetch elements via XPATH:

# Add xpath support.  Example:
#
# @browser.text_field(:xpath, "/html/body/div[2]")
module Watir
  module Container
    class HtmlElement

      OPERATIONS = {
        :id => "by_id",
        :index => "by_index",

        :class => "by_class",
        :name => "by_name",
        :text => { "Link" => "on_link",
          "Label" => "by_text" },

        :url => "on_link",
        :value => "by_input_value",
        :caption => "by_input_value",

        :src => "by_src",
         :x path => "by_xpath"  # add xpath here

      }
    end
  end
  class AppleScripter
    # add method to allow us to fetch elements via XPATH
    def operate_by_xpath(element)

      js.operate(%|
var result = document.evaluate('#{element.what}',
                    document.documentElement,
                    null,
                    XPathResult.FIRST_ORDERED_NODE_TYPE,
                    null);
var element = result ? result.singleNodeValue : null;|,
      yield)
    end
  end
end

Now we can easily fetch almost any element in the DOM using XPATH expressions. For example, there were multiple forms on my page, all with a classification of “select-form”, and I had to find the one with an input named “userId”. This was simple using XPATH:

@browser.form( :x path,
  '//form[@class="select-form"]/input[@name="userId"]/..')

Imagine trying to accomplish the same thing without XPATH.

Tags:

1 response so far ↓

You must log in to post a comment.