Adding Authenticaton to WatiN
Well after a week or so of not touching WatiN, I had another crack at getting authentication to work. In the short term I have abandoned the “technically correct” solution of trying to get impersonation to work, and instead I have ported over the AutoIT code from watir. To do this I created two new classes AutoIT and AutoItLogonParamaters. The main methods in the AutoIT class are:
public void logon(AutoITLogonParameters loginParamaters)
{
autoit.WinWait(loginParamaters.windowTitle, "", _timeout);
autoit.WinActivate(loginParamaters.windowTitle, "");
autoit.Send(loginParamaters.userName, 0);
autoit.Send("{TAB}", 0);
autoit.Send(loginParamaters.password, 0);
autoit.Send("{ENTER}", 0);
}
The logon parameters class just contains properties to get and set three strings so I can pass in one parameter instead of three. The next trick was to work out how to get this code to work on another thread. This required “drilling a hole” through the IE class, passing the login paramaters class into the popupwatcher class and adding the following to the MyEnumThreadWindowsProc method.
private bool MyEnumThreadWindowsProc(IntPtr hwnd, IntPtr lParam)
{
if (IsDialog(hwnd))
{
IntPtr handleToDialogText = NativeMethods.GetDlgItem(hwnd, 0xFFFF);
string alertMessage = GetText(handleToDialogText);
alertQueue.Enqueue(alertMessage);
// get the window title, and check if it matches our login window
if (GetText(hwnd).StartsWith("Connect to"))
{
if (logonParameters != null)
{
// TODO: We should be able to use win32 for all this like
// NativeMethods.SetWindowText(hwnd, "Hello");
WatiN.Core.AutoIT auto = new AutoIT();
auto.logon(logonParameters);
}
else
{
throw new MissingFieldException("A window title is missing.");
}
}
NativeMethods.SendMessage(hwnd, NativeMethods.WM_CLOSE, 0, 0);
}
return true;
}
This works exactly as I expected and the following test passed with no problem.
IE ie = new IE(new AutoITLogonParameters("Connect to localhost", "uid", "pwd"));
ie.GoTo("http://localhost");
Assert.IsTrue(ie.ContainsText("this is a test"), "Text not found");
ie.Close();
The main problem with this approach is that it requires the AutoIT dll to be bundled with the code, and it needs to be registered on the machine before it can be used. My next step is to investigate the Win32 calls similar to what already exists to close the popup windows, removing the need for AutoIT entirely.
February 4th, 2007 at 5:32 am
You can use WebAii here: http://www.artoftest.com, it has a built in UI automater for both mouse and keyboard in addition to all the features that WatiN support. It is not open source but is offered for free. Seems like we are getting more options now for doing such automation. One thing WebAii has that WatiN doesn’t, is the ability to wait for elements on the page. An essential part of any ajax testing.
February 4th, 2007 at 10:13 pm
Ian,
WatiN in the 0.9.5 release does support waiting for elements on a page with the element.exists method, and AJAX support will be increased in the future.
Bruce