Firebug and XPath: two new ingredients to the mix.
Hello everyone!
In our previous post, we learned the basics to record a Selenium script using IDE and run it with JUnit.
Today we are going to learn how to use Firebug and basic XPath to locate elements on your test page.
Things you will need for this lesson:
- Firefox
- The Firebug extension
- The FireXPath extension for Firebug or XPather
If you read the code generated by Selenium IDE, you might have noticed the following cryptic line:
selenium.click(“//div[@id=’wpbody-content’]/div[2]/h2/a”);
What is that? What does it mean?
To understand it better, I would like to introduce you to your new friend, the XPath expression!
XPath expressions are used when you want to navigate a XML structure using its elements and their attributes. Since the HTML DOM (Document Object Model) is technically a XML file as well, we can parse it with XPath.
When an HTML element is not easily identified or when you need to identify an element based on the relative position of another element, you can use XPath to locate it. Selenium IDE does not generate user friendly expressions and there is a high chance it won’t work across different browsers, so let’s use that line to learn a few things.
Let’s see that line again:
selenium.click(“//div[@id=’wpbody-content’]/div[2]/h2/a”);
If you know some basic HTML, you will see that it has something to do with HTML tags. Start reading from right to left. Can you identify any familiar tags?
We have three tags in that expression:
- a – link
- h2 – heading 2
- div – div
So, Selenium will click on a link contained in a heading text, which is contained in the second div inside the div which ID is “wpbody-content”.
Phew! That’s quite a long example. How about a visual approach?
Open Firebug and click on the XPath tab, let’s find alternatives to that expression.
Start with something easy, type “//a” – you should see around 90 results. It doesn’t look so unique, does it? It is important to use unique expressions to identify the elements you want to interact with, unless you want to iterate over them, but that’s something for another post :)
Now that you have all the links filtered, type “//a[@href=’post-new.php’]” – you should get only three results by now:
Still not unique enough. If you observe the 3 results, you will notice that they are in different containers: the first is in a “div”, the second in a “li” and the third in a “h2” tag. Now, you can reduce the original expression down to “//TAG/a[@href=’post-new.php’]”. Try it!
Instead of using the HREF property, we could have searched for links containing the “Add New” text, using “//a[contains(text(), ‘Add New’)]”, but if you try to parse that expression, you will see that FireXPath returns about 8 results. How do we select the right link? A good option would be:
//a[contains(text(),’Posts’)]/following::a[contains(text(),’Add New’)][1]
Notice that we are using two new things here, a XPath Axis (“following”) and an index [1]. Axes are used to work with node sets relative to the current node, in this case, the “Posts” link. Since the “following” axis returns a set of nodes, we are only interested in the first, thus the need for the [1] index.
In the last post, our script only was able to fill only the “Title” field, not the actual post text. As an exercise, you can change the script write a complete post, with tags, categories and text.
Additional resources:
Recent Comments