So I'm making some automated testing for some web apis. I'm trying to see if I can use System.Windows.Forms.WebBrowser class to navigate to a page, enter some text, and press a button, all from the console. I decided to use wikipedia for my test, because entering text into the search bar and hitting search is pretty much the same thing I'm trying to do.
I used code from this question to start off.
The problem I'm having is that I can't quite seem to chain the two actions together, 1) navigate to wikipedia, 2) Enter text into the search box and hit go. It navigates to wikipedia alright. I was told to try using state machines, but I don't quite know how that's supposed to look. As it is, when it comes back to the runBrowser method for the second time, the line br.Document.GetElementByID("searchInput") throws an InvalidCastException. So I have not the foggiest what's going on there. I assume something to do with creating a new thread while the old one is running, but when I kill the old one, it also seems to kill the WebBrowser and throws an error saying "Disconnected Context"
Here's my code:
static WebBrowser br = new WebBrowser();
static void runBrowserThread()
{
var th = new Thread(() =>
{
br.DocumentCompleted += browser_DocumentCompleted;
if (state == 0)
{
br.Navigate(new Uri("http://en.wikipedia.org/wiki/Main_Page"));
state++;
}
else if (state == 1)
{
if (br.Document.GetElementById("searchInput") != null)
{
HtmlElement search = br.Document.GetElementById("searchInput");
search.SetAttribute("value", searchterm);
foreach (HtmlElement ele in search.Parent.Children)
{
if (ele.TagName.ToLower() == "input" && ele.Name.ToLower() == "go")
{
ele.InvokeMember("click");
break;
}
}
}
else
Console.WriteLine("Meep");
state++;
}
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
static void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// var br = sender as WebBrowser;
if (br.Url == e.Url)
{
Console.WriteLine("Natigated to {0}", e.Url);
}
HtmlElement search = br.Document.GetElementById("searchInput");
Console.WriteLine(search.InnerHtml);
Console.ReadLine();
// Application.ExitThread(); // Stops the thread
runBrowserThread();
return;
}
Any idea on how to arrange this code to make the threading stuff play nice would be really appreciated.