Solution to WatiN and XPath support

posted by Bryan on

This is lacking. It's been one of the few disappointments I've had with WatiN. It does not handle XPath support out of the box. I found several other posts out there on the same issue with work arounds but we found a pretty slick solution using JavaScript-XPath.

  1. Inject the JavaScript-XPath library onto the page.
  2. Use the JavaScript-XPath library to locate the element in JavaScript.
  3. Add a uniqueidentifier to the element through JavaScript.
  4. Use WatiN to attach to the element.
  5. Continue with actions as usual.

First, inject the latest library from the website. Main link to site is: http://coderepos.org/share/wiki/JavaScript-XPath.

public static void InjectJavascriptXPath(Browser browser)
        {
            try
            {
                const string injectJavascriptXPath =
                    @"{var b=document.getElementsByTagName('body')[0]; " +
                    @"var script=document.createElement('script'); script.src='http://svn.coderepos.org/share/lang/javascript/javascript-xpath/trunk/release/javascript-xpath-latest-cmp.js';" +
                    @"var head=document.getElementsByTagName('head')[0],done=false;script.onload=script.onreadystatechange=function()" +
                    @"{if(!done&&(!this.readyState||this.readyState=='loaded'||this.readyState=='complete')){done=true;" +
                    @"script.onload=script.onreadystatechange=null;head.removeChild(script);}};head.appendChild(script);}";

                browser.RunScript(injectJavascriptXPath);
            }
            catch (Exception)
            { }
        }

Second, use the library to locate the element. Then, add a unique identifier to the element.

string uniqueId = CreateUniqueId(date);
            
StringBuilder js = new StringBuilder();
js.Append(@"var result = document.evaluate('" + xpath.Replace("'", "\"") + "', document, null, 7, null);");
js.Append(@"var ele = result.snapshotItem(0);");
js.Append(@"ele.setAttribute('id', '" + uniqueId + "');");
            
browser.RunScript(js.ToString());

Lastly, find the Element using WatiN.

Element element = browser.Element(Find.ById(uniqueId));
 element.Click()

Props to Anders for the idea. W00t!

Leave a comment

blog comments powered by Disqus