Sunday, April 08, 2007

Q: How do you make Watin catch a JavaScript confirmation dialog?

A: Use the JavaScript setTimeOut() function

[Parent Advisory: This is GEEK!]

I like Watin for automated unit testing... a lot in many ways. I wish that the documentation was better. More examples would be nice. So here is my modest attempt to contribute to making the world a better place for those of us who have seen the light and understand that Test Driven Development is really the way to go.

Recently I had a problem getting Watin to click JavasScript Confirmation dialog boxes.

Here is what I learned.

Watin testing works in machine time not human time.

Thus, page interaction instructions fire in under a millisecond.

This is OK for web page interactions such as hyperlink and button clicks. But, for Alert and Confirmation dialogs, which live outside of the page, catching a button and firing a click is a problem.

The Confirmation or Alert display takes place too fast for Watin to pick up.

I get "confirmation catching" to happen by putting in a 1 millisecond time delay in the JavaScript in HiThere.htm. This 1 millisecond delay is unnoticeable to human beings but of significance for testing computers.

So here is the HiThere.htm page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Confirmation Thrower</title>
</head>

<script type="text/javascript">

function doWrite()
{
var isGood=confirm('Do you to do this??');
elm = document.getElementById('WriteHere');
if (isGood == true)
{
elm.value = 'I am good';
}
else
{
elm.value = 'I am bad';
}
}


function getConfirmValue()
{
setTimeout('doWrite()', 1);
}

</script>

<body>
<form id="form1">
<a id="YouOK" href="javascript:getConfirmValue()">OK?</a>
<input id="WriteHere" value="" />
</form>
</body>
</html>


Here is the Watin test:

[Test]
public void SimpleConfirmCatchTest()
{
IE ie = new IE();
ie.DialogWatcher.Add(new LogonDialogHandler(WATIN_USER, WATIN_PWD));
ie.GoTo(GetHiTherePage());
ie.ShowWindow(NativeMethods.WindowShowStyle.Maximize);
Link link = ie.Link("YouOK");

link.Click();

ConfirmDialogHandler confirm = new ConfirmDialogHandler();
using (new UseDialogOnce(ie.DialogWatcher, confirm))
{
confirm.WaitUntilExists();
confirm.OKButton.Click();
ie.WaitForComplete();
}
ie.Close();
}

Go here to get the code for UseDialogOnce. (Thanks Trev!)

2 Comments:

Anonymous Anonymous said...

Hi,

Was surfing the web and found your blog. WatiN's documentation is indeed lacking a bit. I would advice everybody to look into the unit tests as an alternative.

Changing the test code (starting from the line that sets the link field) to this would solve the problem you have and avoids having to change your html page to make it testable.The trick is in using ClickNoWait instead of the Click.


ConfirmDialogHandler confirm = new ConfirmDialogHandler();
using (new UseDialogOnce(ie.DialogWatcher, confirm))
{
ie.Link("YouOK").ClickNoWait();

confirm.WaitUntilExists();
confirm.OKButton.Click();
ie.WaitForComplete();
}
ie.Close();
}

Hope this info helps,

2:46 PM  
Anonymous Anonymous said...

How do make watin process a alert or confirm box from javascript if the popup happens on a text change and NOT a button click

Thanks
Mark Crosbie
www.quiznetonline.com

3:08 PM  

Post a Comment

<< Home