Google Analytics

Search

To search for specific articles you can use advanced Google features. Go to www.google.com and enter "site:darrellgrainger.blogspot.com" before your search terms, e.g.

site:darrellgrainger.blogspot.com CSS selectors

will search for "CSS selectors" but only on my site.


Wednesday, January 27, 2010

xpath

I have been doing a lot of web testing. The general idea behind all UI test automation tools is to locate an element on a page then do something with it, set it, clear it, read it, etc.

For the web automation tools you can use:

(a) the position on the screen (x,y coordinations)
(b) the position in the DOM (e.g. /html/body/table/tbody/tr[2]/td[4]
(c) a unique attribute

The position on the screen never works. Different browsers, fonts, screen resized, etc. will change the layout and ultimately, change the screen position of elements. I wouldn't use this. Working with development to provide alternative means will be less work than maintaining automation with x,y coordinates.

The position within the DOM is a little brittle. When a browser is patched or a new browser needs to be supported it is not uncommon for the developers to throw in some span or div elements to help with layout. So the element /html/body/table might change to /html/body/div/span/table. The more precise the positioning information the more brittle it will be.

A unique attribute would be something like the id of a tag. For example:
Darrell
I can find this via the class or id attribute, or both. This is where xpath comes in handy. The automation tools I have been using (Watij, Selenium) can use xpath to locate an element. For my td element I can use:
//TD[@class='username-cell']
or
//TD[@id='username']
or
//TD[@class='username-cell' and @id='username']
The id attribute is required to be unique. So if the element has an id, that is the attribute to use. If you start an xpath with // it tells the tool to start searching anywhere in the DOM. Starting with a single / will start at the root. For a web page that will always be /html.

Xpath can be quite powerful in identifying elements. You have a few 'tricks' you want to use. First is that id=' foo' is not the same as id='foo '. The whitespace makes a difference. To get around this I would use:
//TD[contains(@id,'foo')]
Now the whitespace does not matter. you have to be careful with this however. If there are two matches, it depends on the automation tool as to what will happen. If I have:

darrellDarrell
then:
//TD[contains(@id,'user')]
will have unpredictable results. Not something you want in test automation. So how to get around this?
//TD[contains(@id,'user') and not(contains(@id,'username'))]
Any attribute inside the tag can be used via the @ symbol. You can do things like look at the style attribute using @style. Because the order of the things in style does not matter to the browser, the contains() function helps a lot.

Finally, the text between the open and close tag can be found using the text() function. So if I had:
I can find it using:
//A[contains(text(),'Google')]
What about the difference between Google and google? For matching either you can use:
//A[contains(lower-case(text()),'google')]
This will take the text in the anchor (e.g. Google) and changing it to lower case (e.g. google) then comparing that resulting string to 'google'.

In addition to and there is an or keyword as well but I usually find it better to narrow things down (and will filter out) rather than build up the matches (or will combine).

There is a lot more to know about xpath. If you are curious, ask.

Additionally, I find a developer will put an id on something because he uses it from javascript to find it and all the elements underneath it. So if there is:

  • Darrell


  • Jerome


  • Mark

  • I would tend to use:
    //DIV[contains(@id,'users')]/UL/LI[contains(text(),'Darrell')]
    to find the element which contains 'Darrell'. The developer will tend to not want to change the structure under the id'd tag because it will cause them a lot of maintenance as well.

    3 comments:

    yesimbrandon said...

    I have been using selenium IDE for about two months now. I have run into some problems and have not really began automating my tests for our projects yet. I hope you continue to post in this blog I find it to be very useful because I am new to testing. Is there a list of keywords that can be used in xpaths? I've seen sites that talk about syntax but I've never really found a great list. I didn't even know I could do contains(@id, 'foo') nor did I know I could use lower-case in the locator.

    Darrell said...

    Hello Brandon,

    I like to use w3schools.com for a list of xpath functions. Most the stuff I learned about xpath however has come from trial and error.

    Raveendra BV said...

    Fantastic article Darrell. Helped me to understand lot many things. Too good..