Evaluating Javascript in WatiN

September 5th, 2007

The WatiN framework is quite cool, but it lacks two important things.
First one is searching by CSS selectors, or, at least, classes.
Find.ByCustom(“className”, “X”) is way too ugly. Or am I missing something?

The second (more important) one is a weak access to Javascript.
First thing I wanted to do with WatiN was to change something and then check some script state.
And getting some values from script was not obvious.

I didn’t want to use Ayende’s evil hack (no harm intentended, it gets the work done) — putting javascript state into DOM is not pretty and too string oriented.
I thought that browser COM interfaces should definitely have a way to get Javascript objects outside, that is just the way MS/COM people think.
Thanks to Jeff Brown’s comment for explaining last obstacles.

So here goes the code.
It is quite basic, but it allows you to get value of any Javascript evaluation.
As you can see, I hadn’t included any error handling, I had no time to look into it.

    public static class JS {
        public static object Eval(Document document, string code) {
            IExpando window = JS.GetWindow(document);
            PropertyInfo property = JS.GetOrCreateProperty(window, "__lastEvalResult");

            document.RunScript("window.__lastEvalResult = " + code + ";");

            return property.GetValue(window, null);
        }

        private static PropertyInfo GetOrCreateProperty(IExpando expando, string name) {
            PropertyInfo property = expando.GetProperty(name, BindingFlags.Instance);
            if (property == null)
                property = expando.AddProperty(name);

            return property;
        }

        private static IExpando GetWindow(Document document) {
            return document.HtmlDocument.parentWindow as IExpando;
        }
    }

Nitpicking:
By the way, Ayende, getting permalinks to comments in your blog is not obvious (I used View Source).