A blog on Test Automation, Technical QA, DevOps, Testing Tools & Techniques and more. This is a personal blog. The content and opinions expressed in this blog are solely my own and do not express the views or opinions of my current or past employers.
XPath is a very powerful and widely used mechanism in Selenium for locating elements on a Web Page. XPath is used for locating nodes in an XML document and it can also be used for locating HTML elements in XHTML. Selenium supports XPath along with various other locator strategies. XPath in Selenium extends beyond the simple methods of locating by id or name attributes, and opens up all sorts of new possibilities for locating complex & dynamically rendered elements.
Developers not always follow best practices or testability guidelines while building the applications. XPath comes to your help when you don’t have a suitable id or name attribute for the element you wish to locate. You can use XPath to either locate the element in absolute terms or relative to an element that does have an id or name attribute. XPath locators can also be used to specify elements via attributes other than id and name.
Recently a team approached me for solving a locator problem in Selenium. They were testing an e-commerce web application. They had a difficulty in selecting & adding an item to shopping cart. The table listing the items was rendered dynamically using dynamic ids and complex HTML structure. Following figure shows the structure of page:
The textbox to enter the Quantity and image to add item was buried under layer of div elements inside a td element in a table. The ids for these elements were generated dynamically and it was difficult to add an item dynamically from the test script. Here is html code for Quantity textbox:
As you can see in the above code, we cannot rely on id attribute as it changes every time page is refreshed and secondly name of textbox is not unique.
XPath Axes comes to a great help to resolve this problem and develop a generic location strategy. In simple terms XPath Axes helps to locate elements based on element’s relationship with other elements in a document. For more information, there is a nice tutorial available on W3Schools on XPath & XPath Axes.
Coming back to the problem, first we need to find a unique way to identify a Product in the table. There are two columns which contain unique values namely Product & Article column. However Article column contains primary key from the database so it is highly recommended to use this value as basis to locate the product. We can also use Product column otherwise. Following XPath Query will locate the cell containing the specified Article using XPath functions contains() & text():
Now we need to find the cell which contains the elements. Here we will use following-sibling axis and find the third cell from the current cell. Following query will return the cell containing Quantity & Add to cart image:
Following screen-shot shows the Selenium IDE commands to enter the Quantity and click on the Shopping Cart image:
These actions will be used to add multiple items in various test cases. We need to make these actions more generic and remove the hardcoded Article Id. Following example shows the custom command implemented in Selenium User Extension and Selenium IDE:
However while using XPath we need to consider the fact that these locators are dependent on structure of the page and the layout of the elements. Any changes to the structure or layout will affect the locators and tests will result into failures.
Sometimes XPath queries may not work well or tests run slow in browsers that do not have good support for XPaths. CSS selectors is a good alternative in such situations. CSS selectors are considerably faster than XPath. Selenium supports CSS 1.0, 2.0 & 3.0. Following code sample describes CSS selectors for locating the elements from above example: