Tuesday, April 15, 2014

Xpath Tutorial: A Practical Approach for Selenium Users (Part 2)

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. 

Examples:

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:
<ul>
  <li>
     Link 1
  </li>
</ul>

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">
             <cufon>
                       <canvas />
<cufontext>Services</cufontext>
</cufon>
<em>
       </a>
</li>

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">
<span>iPhone</span>
</a>
</li>

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




Tuesday, April 8, 2014

Xpath Tutorial: A Practical Approach for Selenium Users

Intro

This article is for people who want to use Selenium and need to learn XPath. It is organized in several techniques sections where each has a sample scenario and a sample XPath.
In general, I am not going to get too technical about creating a reference for XPath, instead the main focus will be the outline on how to get the XPath you need for Selenium Test Automation.. You can find a reference at http://www.w3schools.com/XPath/


Getting Ready

You will need Firefox 28.0 with Firebug and FirePath for this tutorial.
Install Firefox 28.0 and launch it. Press Ctrl-Shift-A to bring up the Add-ons Manager. On the left panel click on Extensions and search for Firebug install it and then do the exact same thing to get FirePath.

Firebug & FirePath Quick Guide

Firebug is a tool for developers to inspect HTML elements on a webpage.
Note: Firefox version used here is 28.0 but you can use older versions of Firefox. Just make sure FirePath and Firebug can be used with it and that there are no version issues.
Here is how you would use Firebug and FirePath:

Step 1: Once you installed them bring up a Firefox instances and browse to http://mail.yahoo.com.  Then Right click on first box for username (Yahoo ID)









Step 2: Select “Inspect Element with Firebug:






As you can see the input element with id=username is highlighted in blue. Pay attention to the selected tab in the newly opened window: HTML. There are also other tabs for different operations but for this tutorial you would only need HTML tab and the FirePath tab.

You can have Firebug window embedded or open up as a separate pop-up which ever you prefer.



The left-most button closes Firbug window, the middle button attaches Firebug to the browser window or opens Firebug in a new pop-up window. The right button deactivates Firebug for the current website which we would hardly ever use. 

Step 3: Now tab over to FirePath.






FirePath is a tool that allows us to test our XPath and make sure that we get them right before using it in Selenium. As shown on the image, the XPath has one match and the targeted element is highlighted in the HTML code it’s also marked as dashed-lines in the browser on the right hand side of the image. The “Eval” button on the top right corner of the page is to test your XPath. So place your expression in the XPath box and press Eval, if you get a match you are set, if you don’t you need to revise your XPath expression.  However, if you get more than one match then you have to make your selection stricter or specify which element you specifically want from the list. For example, if //input matches 5 nodes then (//input)[1] will give you the first one and (//input)[2] the second and so forth.


The top left drop down currently selected as “Top Window” indicates where the element is located in terms of frames. In most new web applications the usage of frames and iframes are discouraged but nevertheless there are lots of web applications that uses them.



Quick Review of XPath

In simple words, XPath is an expression used to locate html elements on screen. You can think of it as a query language to target elements on the page. Here are some basic examples:

XPath Expression
Description
//input[@id=’username’]
Returns inputs with id=username
//input[@type=’text’]
Returns all text inputs
//table/tbody/tr[1]
Returns 1st rows of all tables in this page
//div
Returns all the divs in this page
//a[text()=MyText]
Returns a link that has the text matching precisely “MyText”. So <a href=”msn.com”>MyText</a> would be a match but
<a href=”yahoo.com”>MyText   </a> won’t match because of extra spaces at the end. 
//*[contains(text(),’hel’)]
Returns all elements that contain the text ‘hel’. Here are some possible matches:
<div>hello</div>
<tr<td>hel   </td></tr>
<a href=”#”>Shell</a>

Anything that comes immediately after // is an HTML tag or just use * as wildcard.
Every web page is based on HTML code and it is called DOM (Document Object Model). In fact HTML is an XML document that browsers can render into the nice looking web pages. To locate elements (Textbox, Links, Images, etc.) in a XML document we use XPath.

Relative vs. Absolute Expression

 An absolute expression starts from the beginning of the DOM and follows instructions blindly until it reaches the element. A relative XPath is much smarter and it can figure out the target element based on some hints. For example, on our sample page http://proof.subject-7.com/zul/samplePage.zul the box for Last name has the following absolute XPath: /html/body/div/div/div/span/table/tbody/tr[2]/td[2]

It’s basically a turn by turn navigation that goes like: Start from the beginning DOM (This is because there is only one slash at the beginning) where the tag <html> . Then find the element <body> right after that, then a <div>, another <div> and another <div>. This is followed by a <span> then we arrive at a <table> and  <tbody> then tr[2] selected the 2nd row and td[2] the second column. BORING!

The good thing about absolute expressions is that most tools like FirePath or Firebug can produce them for you without breaking a sweat.

However, the smallest change to your webpage, such as adding an element or changing positions will break your XPath.


After working with Xpath for almost 6 years, I still sometimes need examples and reference to write my own expressions. To use XPath with Selenium you need to master a handful of techniques without delving too deep into the subject of XPath. This handful of techniques will cover more than 95% of all the XPath you need for your automation.