Xpath Tutorial Part 2: A Practical Approach for Selenium Users

Here is the link to Part 1.

Technique #1 (Static Elements)

Scenario: Elements in a form such as a user registration or admission form.

These are elements that have constant properties such as IDs and/or names. These properties don’t change upon page refresh or on different browser sessions. They are usually not auto-generated either.

Selenium has a search by id and/or name therefore, don’t use XPath such as //input[@id=username] or //input[@name=’postalAddress’] for static elements. Searching by ID and name is faster and easier.

To make sure that an element is static you need to refresh the page few times using Ctrl-F5 to make sure the element id or name doesn’t change. If you are landed on the current web page by submitting a form (or using http post) then you need to restart the steps that got you to the page where the target element resides.


Go to mail.yahoo.com and do an inspect element on username field. The id=username now refresh and try again. As you can see the id doesn't change so it could be used to target username field in Selenium.

<input type="text" value="" autocomplete="off" autocorrect="off" placeholder="Yahoo ID" aria-required="true" tabindex="1" maxlength="96" id="username" name="login">

Browse to http://proof.subject-7.com/zul/samplePage.zul. Inspect the box in front of “Lastname” write down the id and do a refresh and look at the id again. As you can see, the id changes each time and hence you know the element is not static.

<input type="text" value="" class="z-textbox" style="width:80%;" id="b3EQe">

Here is the HTML excerpt on page refresh:
<input id="o17Qe" style="width:80%;" class="z-textbox" value="" type="text">

Technique #2 (Menu Links)
Scenario: Menus are common structures in web pages. A menu structure usually looks like this:
Link 1

To get to the menu link remember that you are looking for a "Link". An XPath that targets the actual text on the screen won't really work. Here are some examples:

Sample HTML 1:
<li class="">
<a href="services.html">
<canvas />

Target Element: Capture Services menu on the reference site www.subject-7.com.

Sample XPath: //*[contains(text(),'Services')]/ancestor::a
The expression works like this:

//* Find all elements
[contains(text(),'Services')] Containing the text "Services"
ancestor::a Then find an ancestor that is a link

Note how we start by a broad query and we narrow it down as we go. When you try this with Firepath make sure you get 1 match only. Most times when your XPath query matches more than one element on the page you wind up with weird behavior when running your test.

Sample HTML 2:
<li id="gn-iphone">
<a href="/iphone/" onclick="s_objectID="http://www.apple.com/iphone/_1";return this.s_oc?this.s_oc(e):true">

Target Element: Capture iPhone menu on the reference site www.apple.com
Sample XPath:. //*[contains(text(),'iPhone')]/ancestor::a