I’m just getting started with WatiN and attempting to test a large number of pages with authentication. I’ve taken the approach of only creating a new instance of IE each time new login details are required. Once authenticated, the framework needs to navigate to 2 pages on the site and click a link on each to download a file (repeated multiple times within one authenticated session for different clients).
Navigating to the pages is fine and the download is working with IE9 using a combination of WatiN and SendKeys(). However, when it navigates to the second page and attempts to find the Link object by Text (which has the same text as on the previous page) it returns the download URL from the first page. This means that essentially whatever page I direct WatiN to, it still seems to be persisting the Link object from the first page.
The first method creates my browser object and returns it to the parent class:
public IE CreateBrowser(string email, string password, string loginUrl)
{
Settings.MakeNewIe8InstanceNoMerge = true;
Settings.AutoCloseDialogs = true;
IE ie = new IE(loginUrl);
ie.TextField(Find.ById("Email")).TypeText(email);
ie.TextField(Find.ById("Password")).TypeText(password);
ie.Button(Find.ById("btnLogin")).Click();
Thread.Sleep(1500);
return ie;
}
I then iterate through logins, passing the URL for each required page to the following:
public void DownloadFile(IE ie, string url)
{
//ie.NativeBrowser.NavigateTo(new Uri(url));
ie.GoTo(url);
Thread.Sleep(1000);
//TODO: Why is link holding on to old object?
Link lnk = null;
lnk = ie.Link(Find.ByText("Download file"));
lnk.WaitUntilExists();
lnk.Focus();
lnk.Click();
//Pause to allow IE file dialog box to show
Thread.Sleep(2000);
//Alt + S to save
SendKeys.SendWait("%(S)");
}
The calling method ties it all together like so (I’ve obfuscated some of the details):
for (int i = 0; i < loginCount; i++)
{
using (IE ie = HelperClass.CreateBrowser(lLogins[i].Email, lLogins[i].Password, ConfigurationManager.AppSettings["loginUrl"]))
{
...Gets list of clients we're wanting to check
for (int j = 0; j < clientCount; j++)
{
string url = "";
switch ()
{
case "Page1":
string startDate = "20110831";
string endDate = "20110901";
url = String.Format(page1BaseUrl, HttpUtility.UrlEncode(lClients[j].Name), startDate, endDate);
break;
case "Page2":
url = String.Format(page2BaseUrl, HttpUtility.UrlEncode(lClients[j].Name));
break;
}
HelperClass.DownloadFile(ie, url);
}
}
}
Does anyone have any idea what could be causing this or how to get around it? Do I need to create a new IE object for each request?
Okay, so I’ve managed to find out what was causing my Link object (and the parent Page object) to persist across multiple URLs.
It seems that because I’m clicking the Link which forces the “Save As” box in IE9, this keeps the Page object current, even as the browser runs through all the other URLs in the background. This seems to update the HTML rendered in the window but not release the existing Page object (or possibly creates additional Page objects in memory).
Because I’m using SendKeys() to hit the “Save” button, rather than a handled dialog in WatiN, the dialog stays open and persists the Page object.
From the looks of things, I need to find a different, handled way of performing my file downloads/saving.