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 01/09/2015: 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 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”); };

 

Advertisements

7 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.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

Pete Zybrick

Bell Labs to Big Data

Seek Nuance

Python, technology, Seattle, careers, life, et cetera...

TELLURIUM

New Era of Test Automation

Der Flounder

Seldom updated, occasionally insightful.

The 4T - Trail, Tram, Trolley, Train

Exploring Portland with the 4T

Midnight Musings

Thoughts on making art

Automation Guide

The More You Learn The More You Play...!

The Performance Engineer

Code.Test.Tune.Optimize.

humblesoftwaredev

Thoughts related to software development

Yi Wang's Tech Notes

A blog ported from http://cxwangyi.blogspot.com

Appium Tutorial

Technical…..Practical…..Theoretically Interesting

LinuxMeerkat

I swear! Meerkats can do Linux

PacketsDropped

Requeuing the packets dropped in my memory.

Two cents of software value

Writing. Training. Consulting.

@akumar overflow

wisdom exceeding 140 chars.

%d bloggers like this: