Writing WatiN Tests
The most important thing to understand about WatiN tests is that the moment you put in Ajax, you are inheritedly testing multi threaded code. This means that you are going to be aware about concurrency issues.
Here are a few recommendations:
- Only open IE once per test fixture - this has a significant overhead, so we want to reduce it as much as possible.
- Make sure that in the setup you go back to the page and refresh. This is important to handle browser cache issues.
- Build a set of expectations to handle waiting, it will make your life much easier.
Here is an example of a test:
[Setup]
public void Setup()
{
Open("policies/newPolicy.aspx");
ie.Refresh();//avoid cached data, and start from clean slate
}
[Test]
public void CanAddNewNote()
{
ie.Button(PartialId("AddNewNote")).Click();
ie.SelectList(PartialId("Customers")).Option("Rhino").Select();//cascading drop down
WaitUntilEnabled("Policies");//wait for child drop down to become enabled
ie.SelectList(PartialId("Policies")).Option("Home").Select();
ie.TextField(PartialId("NoteText")).TypeText("Should we do that?");
ie.Button(PartialId("SaveNote")).Click();// ajax call.
WaitUntilHidden("NewNoteDiv");//finished updating the page
AssertTextPresent("Should we do that?");
}
PartialId() will look for a control that ends with the text that you gave it, this is done to handle ASP.Net control name mangling.
Comments
Thanks, examples and advice like are this are really time-savers.
Came across this, and it looked to be a life-saver. Unfortunately, some of the code (PartialId, WaitUntilEnabled) don't seem to be from WatiN. Am I missing someting? If these are methods that you wrote, would you mind sharing? I, for one, would find it very beneficial. Thanks
Partial Id is just a regex:
public Id PartialId(string partialElementId)
{
return new Id(new Regex(".*"+partialElementId+"$");
}
This is from memory, so it may be a bit off, but:
public void WaitUntilEnabled(string partialElementId)
{
SimpleTimer timer = new SimpleTimer(IE.Settings.WaitUnitCompleteTimeout);
do
{
if( ie.Element(PartialId(partialElementId)).GetAttributeValue("disabled") != "true")
return;
Thread.Sleep(200);
}
while(!timer.Elapsed);
throew TimeoutException("Waited too long for "+partialElementId+" to become enabled");
}
David, Ayende,
Just to inform you, the next release of WatiN will include:
Element.WaitUntil(Attribute)
Element.WaitUntil(atributename, value)
Example:
ie.Element(PartialId(partialElementId)).WaitUntil("disabled", "false")
or
ie.Element(PartialId(partialElementId)).WaitUntil(new Attribute("disabled", "false"));
BTW another way of writing:
ie.Element(PartialId(partialElementId)).GetAttributeValue("disabled") != "true"
would be using multiple attribute support:
ie.Element(PartialId(partialElementId) && Find.ByCustum("disabled", "false")).Exists.
You can also check SWExplorerAutomation (SWEA) from http://webiussoft.com. SWEA was specially designed to automate complex DHTML/AJAX applications.
... but is it free?
Comment preview