There is a lot of XPath hate in the Selenium world. Some of it justifiable, but a lot of it is bandwagon-ism and results in hatred for all things XPath. Here’s the rub though, sometimes you really do need XPath and when you do, its power is pretty impressive. Yes, more powerful than CSS Selectors.

<pre lang="javascript">x ='//td[@class="ql-account-requests-title_author"]/a[contains(translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"), translate("' +  material_row.get("author") + '", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"))]/../../td[@class="ql-account-requests-pickup_location" and contains(text(), "' + branch_row.get("branch") + '")]/..//input[@class="ql-account-select-checkbox"]';

Yes. That is a 408 character XPath. And it is awesome.

Context.

This is from a BrowserMob script for a library site revamp. At the end of the script I needed to find the material I had reserved and cancel that reservation. The list of reservations is a tabular data and so was logically in a table. But the accounts are reused during the run so I needed to find the material by the author and title that was randomly chosen for this run. This meant that I needed to find a cell, go back up and over, find a cell, got back up and over and click a checkbox.

This is not a time machine; its a locator. It can’t go back.[1]

When you need a plain top-to-bottom structural locator then CSS Selectors should be your default approach, but it cannot go back up the DOM. XPath can.

CSS cannot also deal with the inevitable matching problems that come from using real-life data. And unfortunately Firefox’s implementation of XPath does not have the lower-case function so you have to use the nasty looking translate. CSS Selectors do not also have substring matching for of descendent text in the standard. Sizzle solves that, but that is not standard. XPath has contains though.

Circling back to this particular XPath.

  • Does it solve the problem? Yes
  • Is it more inherently brittle than another structural locator? No
  • Does it provide guards around case differences in data? Yes
  • Would it be pretty easy to modify if the way that the identifying bits change? Yes

Awesome.

The point of this little rant is to not be afraid of large XPath when it is the proper locator for the task and reserve your judgemental sneers for those use of bad used XPath poorly.

Oh, and remember, your ‘but it relies on the structure of the HTML’ hatred should really be directed at both XPath and CSS Selectors. They are both structural location schemes and therefore suffer the same problems.

[1] Stolen blatantly from Back To The Future by Pagano