Testing XPath and CSS locators FirePath style across browsers

2 May

FirePath (for Firebug on Firefox) is a nice tool for finding and testing XPath and CSS selector locators. Firebug alone (and similar developer tools/console on other browsers) can only inspect element(s) but can’t give you the XPath/CSS to it nor allow you to directly test a given XPath/CSS locator value to see if it matches/finds any element to see if your locator is correct or not.

Well, I recently came up with a workaround that works across browsers. I’d still use FirePath on Firefox, but go with the workaround for all other browsers (until someone comes up with a FirePath port on those browsers).

Here’s the technique. You simply inject/execute some javascript code in your desired browser’s javascript (or error) console. Once done, you can then query for elements by XPath and CSS. Note that this isn’t a perfect workaround, it may have issues, but in general seems to work.

Here’s the javascript code snippet to run in the browser console:

document.getElementByXPath = function(sValue) { var a = this.evaluate(sValue, this, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); if (a.snapshotLength > 0) { return a.snapshotItem(0); } }; document.getElementsByXPath = function(sValue){ var aResult = new Array();var a = this.evaluate(sValue, this, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);for ( var i = 0 ; i < a.snapshotLength ; i++ ){aResult.push(a.snapshotItem(i));} return aResult;}; document.getElementByCssSelector = document.querySelector; document.getElementsByCssSelector = document.querySelectorAll;

To then query by XPath or CSS, simply do:

document.getElementByXPath("value here");
document.getElementByCssSelector("value here");

for getting multiple locators/elements, use the plural versions getElementsBy…

be sure to escape the double & single quotes as needed

and note that you can directly query by CSS w/o executing the code snippet above. You simply call document.querySelector(“css value here”); and document.querySelectorAll(“multiple element css value here”); the above code snippet simply create an alias to the native methods to keep the naming convention closer to Selenium/WebDriver APIs.

Now the results show as HTML tags in the javscript console and when you hover over the result, it should highlight in the browser. You’d get nothing returned if there was no match (or undefined, null, etc.)

Neat trick don’t you think?

As for find element by ID, name, class, tag, we already have those natively in browser as
document.getElementById(), getElementsByClassName(), getElementsByName(), getElementsByTagName(). Note that only by ID returns a single element, the others here return a multiple but if it only matches 1, you then have a javascript array of 1 returned. You can then access directly like document.getElementsByName(‘uniqueName’)[0].

The code snippets here are derived from Selenium discussion thread: https://groups.google.com/d/topic/selenium-users/PTPWFU2ho8Y/discussion

Update 5/22/2013: Thought I’d mention this as well, forgot to mention it before. For CSS selector inspection & testing, one can also look at SelectorDetector and SelectorGadget. However, having tried them, I found them cumbersome to use. They are useful for finding CSS selectors but for testing (modifications to) them, I’d prefer the approach documented here. There may also be other browser extensions for Chrome/Safari/IE that fulfill what FirePath does for Firefox, but as of this writing I know not of any, if there is such now or in the future, please do enlighten me.

Update 6/28/2013: it looks like the code snippet above doesn’t work well in IE by default (tested with IE9, would also apply to older versions, not sure about IE10). But it works fine for Chrome and Safari (tested on Windows for both). For IE support, you need a few more tricks to do:

  1. IE developer tools doesn’t seem to return DOM elements back for inspection (e.g. run some javascript that returns a DOM element), where you can click the result to see it highlighted in browser, unlike FF, Chrome, and Safari. The workaround is to load Firebug Lite with IE (or equivalent add-on javascript console) to get that missing functionality.
  2. IE doesn’t offer native XPath support, so even with Firebug Lite and executing the code snippet above, it may fail XPath lookup. CSS selectors are OK. For XPath workaround then, you’d have to execute some additional code snippet first before the snippet above, and this prerequisite snippet simply injects the needed javascript library (that offers XPath support) into the page’s DOM/HTML source.

var script = document.createElement("script"); script.src = "URL to javascript XPath library"; script.setAttribute("type","text/javascript"); document.body.appendChild(script);

then wait at least one second, maybe a few seconds just in case before executing the original code snippet at beginning of this post. The wait is needed for DOM on page to update with the injected script.

Now, for the URL to the javascript XPath libary, you can choose what library to use. I don’t know how many there are out there, but I came across two:

The first one I think is what the Selenium project uses to support XPath for IE, but not 100% sure. I did my IE testing using this library.

BONUS TIP 1: you can also use the following trick to “find” XPath value for an element in IE, should work for other browsers too. But to verify/test the XPath, you still have to use the tricks in this blog post, or some alternate tools. http://functionaltestautomation.blogspot.com/2008/12/xpath-in-internet-explorer.html

BONUS TIP 2: if tip 1 for IE you don’t like or not work for you, try the Fire IE Selenium tool that require Microsoft Excel to work: https://code.google.com/p/fire-ie-selenium/

Update 10/30/2017: I was informed about yet another CSS bookmarklet tool, SuperSelector, that is supposedly good. Also, there are now Selenium WebDriver based GUI tools that allow Firebug/FirePath type inspection of elements across browsers. Take a look at Looking Glass,  Selenium Webdriver Elementor Toolkit, and SWD Page Recorder

Update 02/18/2016: I came across info about alternate but similar XPath query in javascript to return the DOM element, with more details about the particular query:

document.getElementByXPath = function(xpathExpression) { return document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue”); };



11 Responses to “Testing XPath and CSS locators FirePath style across browsers”

  1. _ michael June 28, 2013 at 10:43 pm #

    In Webkit/Blink, you can use $x(“your xpath here”) for XPath queries in the console, e.g. $x(“//img”). For CSS selectors, there is $$(“selector here”). Works for Chrome and Safari, and perhaps for Opera, too, now that they have moved to Blink (haven’t tried that, though).

    • autumnator June 28, 2013 at 10:55 pm #

      Thanks for the tip. Does that same technique work for Firefox? Also, is there a way to alias $x() and $$() to document.yourOwnCustomMethodName()?

      • _ michael June 29, 2013 at 2:02 pm #

        Yes, you can do it in Firefox: https://getfirebug.com/wiki/index.php/Command_Line_API

        I don’t know about the aliasing but then again, why don’t you just use jQuery for that? Works everywhere, whereas a detour via the console would result in brittle, browser-dependent code doing the same thing.

      • autumnator June 29, 2013 at 10:34 pm #

        You make a good point. However, in the context of test automation (not web application development), not everyone uses jQuery and those nice abbreviated $x(), $(), $$(), methods. In Selenium WebDriver, to actually use those requires executing javascript. There’s no WebDriver shorthand APIs like that. Rather you have to do driver.find_element_by_type() (Python example), where type is ID, name, XPath, CSS selector, etc.

        In the context of the WebDriver API then, document.getElementByType() aliases are easier to relate back to WebDriver, especially since there are native browser supported getElementById() and getElementsByClassName(), getElementsByTagName() methods. On a side note, I don’t suppose the various non-IE browsers offer shorthand versions of these native methods, and so the shorthand workaround is to use XPath/CSS via $x() and $()/$$() to identify the tag name or class name or ID.

    • autumnator July 25, 2013 at 9:59 pm #

      On a funny related note, we can use shorthand $x() and $$() to test XPath & CSS selectors in browser developer console, so don’t need extra tools/scripts to test, but one might wonder, why are we forced to go with a longer named API with WebDriver as in driver.findElement(By.xpath(‘value’)).click() when it might be nice to have something like driver.x(‘xpathValueHere’) and driver.$(‘cssHere’). No much complaining there…Though I guess yes, one can extend their own By.type() method or simply execute jQuery as javascript to manipulate locator elements, but that’s all extra work, like what I suggest a bit here in this blog post of mine. So why not have it built in like the browser dev tools. An argument against it for Selenium could also mean web developers are too lazy that we offer such shorthand syntax in dev tools/code when QA have to do it the long way…

  2. vijay March 9, 2017 at 12:39 pm #

    Thanks for the tips in using the css selectors as well as xpath in selenium locators. It will helpful for beginners to get learn with clear data.

  3. James Affleck October 20, 2017 at 9:54 pm #

    Here’s a few methods I liked better than the ones listed (these all work in IE11):
    //return first Xpath element
    $x = function(xpathExpression) { return document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; };

    // return number of results returned by xpath argument
    $xCount = function(xpath) { var argx = “count(” + xpath +”)”; return document.evaluate(argx, document, null, XPathResult.NUMBER_TYPE, null); return argx; };

    // works kind of like the Jquery shortcut
    // for the real one, see: https://developer.mozilla.org/en-US/Add-ons/Code_snippets/QuerySelector
    $$ = function(by) { return document.querySelectorAll(by); };

    • James Affleck October 20, 2017 at 10:04 pm #

      Oops. Copy-paste error. Here’s a better version of $xCount

      $xCount = function(xpath) { var argx = “count(” + xpath +”)”; var result = document.evaluate(argx, document, null, XPathResult.NUMBER_TYPE, null); return result.numberValue; };

      • James Affleck October 25, 2017 at 9:26 pm #

        I thought I had this working earlier this week. I’m not sure why these functions aren’t working today. /me scratches head

      • autumnator October 27, 2017 at 3:01 am #

        Well, hope you figure it out or that it works for others. You might want to elaborate how you call those aliased methods. I’m not familiar with jQuery shortcuts.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Tea in Eighteenth-Century Britain

History of Tea Project at Queen Mary University of London

Phimosis - A Simple Cure (That is working for me)

No nonsense, no adverts, no sales pitch, just honest information.

Glass Onion Blog

Cheat sheets, post-its and random notes from the desk of a programmer

Abode QA

A Hub For Testing Minds...

The Test Therapist

Performance & Security Testing Blog


a programmer's hub

Let's Not Crash and Burn

it makes your brain tingle


“Incinerate Ignorance”

Anastasia Writes

politics, engineering, parenting, relevant things over coffee.

One Software Tester

Trying To Make Sense Of The World, One Test At A Time

the morning paper

a random walk through Computer Science research, by Adrian Colyer

RoboSim (Robot Simulator)

Visualize and Simulate the Robotics concepts such as Localization, Path Planning, P.I.D Controller


open notebook

a happy knockout mouse.

my journey into computer science

Perl 6 Advent Calendar

Something cool about Perl 6 every day


Inspire and spread the power of collaboration

Niraj Bhatt - Architect's Blog

Ruminations on .NET, Architecture & Design

Pete Zybrick

Bell Labs to Big Data

%d bloggers like this: