Eval with WatiN
I just run into a situation where, for the tests, I need to run a script in IE, and get result back for the test. The problem is that IE doesn't expose anything like the eval() command in javascript. It does, however, exposes an execScript() command, but this has no return value. A bit of thinking produced this code:
protected string Eval(string code)
{
string elementId = Guid.NewGuid().ToString();
string create =string.Format(@"
var elem = document.createElement('INPUT');
elem.id = '{0}';
elem.type = 'HIDDEN';
elem.value = {1};
document.body.appendChild(elem);
",elementId, code);
RunScript(create);
string result = ie.TextField(elementId).Value;
string remove = string.Format(@"
var elem = document.getElementById('{0}');
document.body.removeChild(elem);
", elementId);
RunScript(remove);
return result;
}
protected void RunScript(string js)
{
IHTMLWindow2 window = ((HTMLDocument) ie.HtmlDocument).parentWindow;
window.execScript(js, "javascript");
}
The isn't very pretty code, but it works. We create a new hidden input field element, set its value to whatever the code that we were given is doing, getting the value of the field, and then remove it. Simple when I see it now, but it was fairly hard to figure out.
Comments
Another approach might be to insert the following into the DOM:
<SCRIPT> function myeval() { return ... code goes here... } </SCRIPT>Then just execute that function using the document.Script property (defined on IHTMLDocument), which would allow you to capture the return value.
It's a bit of a pain to use though because it only exposes the IDispatch interface so you either have to use reflection to make the appropriate call or use a loosely-typed language (Boo? ;)
@Stan,
Can you give ore details about it?
document.execScript() has no return value.
Ayende,
Here is a quick example:
Assuming you have already inserted the following into the DOM:
<script> function myeval() { return 33 + 44; } </script>The following code:
Type scriptEngType = ie.HtmlDocument.Script.GetType();
int result = (int)scriptEngType.InvokeMember("myeval", BindingFlags.InvokeMethod, null, ie.HtmlDocument.Script, null);
Console.WriteLine("Result: {0}", result);
...will print out: Result: 77
Hope that helps.
@Stan,
VERY cool!
I wasn't aware of this possiblity
@Stan: Neat trick!
This is what I put into our little WebTestFramework here. It's similar to WatiN.
Comment preview