Complicated Xpaths for automated testing
Yesterday at work I was trying to click on a specific button with selenium ,webdriver and python.
I was trying to delete a course coupon from my Schoox academy and needed to click the little Delete button shown in the image below.Â
The thing though was, that this delete button was not the only one on the page. Just imagine 10 different course coupons(or images like the one above) but with the same Preview/Accept/Delete buttons. How am I going to specify that I want to press the Delete of a very specific course?? And on top of that (to make things interesting!) I wanted to check that this coupon was expired (the ribbon on the left).
Essentially I was trying to ... press (with webdriver) the delete button of a course coupon with a specific title and simultaneously make sure that this coupon has the expired ribbon on it.Â
Dont worry ... it is indeed possible.
The tools necessary (for me at least) are Firebug and SeBuilder firefox addons.
Firebug is used to work with the html structure and build the actual Xpath and SeBuilder to verify along the way that what I am making actually works in real time.
I give the actual html of the div used to construct the Xpath and the xpath that was finally used .
I am starting by defining the div with class 'listCoupons' as a starting point. That is //div[@class='listCoupons'] .
Xpaths always start with // . Attributes begin with @ .
Next, I step two divs inside . This is the  /div/div . In the last div that I have reach, I must specify that it contains the ribbon image that I look for. So, the syntax will be /div[img[@src[contains(.,'ribbon_coupon_expired.png')]]] . That means ...check for the div that has an image whose src attribute contains this text . The dot before the comma means text.
Then the syntax goes... and p[@class='infos']/a[contains(.,'course-coupon-title')]. Â That means , .. " the div that I was talking about, yes the one with the image, MUST have this paragraph too". "That paragraph has the attribute @class='infos' , and after that comes an <a> tag that contains this text(the actual coupon title)" .Â
Then comes the syntax for the actual delete button. That is /p[@class='buttons']/a[@class='delete-coupon'] .
I think the last one is pretty straightforward.Â
Note: Along the way I figured out that if you write a couple of complicated xpaths and get used to its syntax (dots,contains,attributes,translating html structures), it is really easy to just describe what you want it find. Just check with SeBuilder every step to make sure that you construct it right.Â
After making sure with SeBuilder that what I wrote makes actual sense, (the green thingy around the xpath :] ) I copy-pasted it in my code after replacing the actual values with variables to make it flexible.
This is how I finally ended up coding it in my test. I have break it up in 3 lines for readability.
















