In my previous post I mentioned that further investigation was required to refine the script to remove the thread.sleep statements. Well post investigation I can share some insights on exactly what is happening and what changes are required.
In addition to the ReadyState property, Internet Explorer exposes a Busy property as well. When a normal page has completed loading the ReadyState will return READYSTATE_COMPLETE and Busy will return false. Internally WatiN uses this to let the browser to dictate when the test script should continue through the Wie.aitForComplete method. This method internally calls two private methods WaitWhileIEBusy() and WaitWhileIEStateNotComplete(). These methods wait for their corresponding methods to return the expected value, then the script continues.
The challenge comes in when a dialog is displayed. When a modal dialog is displayed, IE set’s ie.busy = true, and returns READYSTATE_COMPLETE. If a test is calling WaitForComplete, then the script will hang forever. WatiN caters for this with the WaitForComplete method on it’s HTMLDialog class, which ignores the busy property. Armed with this information, our script now looks like this.
[TestMethod]
public void AddNewUser()
{
using (IE ie = new IE(baseURL))
{
// Click on the 'Manage customers' button to open the customer
// management screen
ie.MainDocument.Button(Find.ByName(btnManageCustomers)).Click();
// Click on the add customer image button (an INPUT tag with type image)
// We need to use ClickNoWait as the Create customer dialog is a modal dialog
// and the readystate does not return to complete until the dialog is closed.
ie.MainDocument.Input(Find.ById(btnSelectTicketType_id)).ClickNoWait();
// Find the new 'Create new customer' dialog that opens in the collection
// of dialogs and wait a maximum of 2 seconds for the dialog
HtmlDialog dialog = ie.HtmlDialog(Find.ByTitle("Select ticket type"),2);
// Select Melbourne, Qantas and Business class
// We need the dialog.WaitForComplete() as these contols load dynamically based on
// the previous selection and we are in dialog mode
dialog.MainDocument.SelectList(Find.ById(ddlDestination_Id)).Select("Melbourne");
dialog.WaitForComplete();
dialog.MainDocument.SelectList(Find.ById(ddlCustomerAirline_Id)).Select("Qantas") ;
dialog.WaitForComplete();
dialog.MainDocument.SelectList(Find.ById(ddlCustomerClass_Id)).Select("Business");
dialog.WaitForComplete();
dialog.MainDocument.Button(Find.ById(btnOk_Id)).ClickNoWait();
ie.WaitForComplete();
// Test that the text 'Melboune' is in the page
Assert.IsTrue(ie.MainDocument.ContainsText("Melbourne"));
// Test that the text 'Qantas' is in the page
Assert.IsTrue(ie.MainDocument.ContainsText("Qantas"));
// Test that the text 'Business class' is in the page
Assert.IsTrue(ie.MainDocument.ContainsText("Business class"));
}

Thanks for your artical. It’s realy helpful. I am a WatiN beginner.