I\'m wondering if it\'s possible to use Selenium with a C# Windows Form that contains a WebBrowser object.
I\'m using selenium and I\'m able to create test cases
I think you can, but you might have to use Selenium RC. It has a .Net version of the Selenium API.
I haven't done this with selenium, but I did the same thing with WatiN when I wanted to automate InfoPath. The approach that I took was as follows:
Kill off all the processes that have that name in my case it was "infopath"
foreach (Process proc in Process.GetProcessesByName("infopath"))
{
proc.Kill();
}
Launch your test application call Process.GetProcessesByName to get all the process id's then get the window handle of the first as there should only be one process running.
Process[] updatedInfopathProcessList = Process.GetProcessesByName("infopath");
if (updatedInfopathProcessList[0].Id == 0)
{
throw new ApplicationException("No Infopath processes exist");
}
infopathProcessId = updatedInfopathProcessList[0].Id;
infopathHwnd = updatedInfopathProcessList[0].MainWindowHandle;
Now that I had the window handle, I get the IHTMLDocument2 to automate against with WatiN.
InternalHTMLDOMDocument = IEDom.IEDOMFromhWnd(this.hWnd);
The real rubber hits the road in the IEDom class ... code is below ...
namespace ItiN
{
public class IEDom
{
internal static IHTMLDocument2 IEDOMFromhWnd(IntPtr hWnd)
{
Guid IID_IHTMLDocument2 = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");
Int32 lRes = 0;
Int32 lMsg;
Int32 hr;
//if (IsIETridentDlgFrame(hWnd))
//{
if (!IsIEServerWindow(hWnd))
{
// Get 1st child IE server window
hWnd = NativeMethods.GetChildWindowHwnd(hWnd, "Internet Explorer_Server");
}
if (IsIEServerWindow(hWnd))
{
// Register the message
lMsg = NativeMethods.RegisterWindowMessage("WM_HTML_GETOBJECT");
// Get the object
NativeMethods.SendMessageTimeout(hWnd, lMsg, 0, 0, NativeMethods.SMTO_ABORTIFHUNG, 1000, ref lRes);
if (lRes != 0)
{
// Get the object from lRes
IHTMLDocument2 ieDOMFromhWnd = null;
hr = NativeMethods.ObjectFromLresult(lRes, ref IID_IHTMLDocument2, 0, ref ieDOMFromhWnd);
if (hr != 0)
{
throw new COMException("ObjectFromLresult has thrown an exception", hr);
}
return ieDOMFromhWnd;
}
}
// }
return null;
}
internal static bool IsIETridentDlgFrame(IntPtr hWnd)
{
return UtilityClass.CompareClassNames(hWnd, "Internet Explorer_TridentDlgFrame");
}
private static bool IsIEServerWindow(IntPtr hWnd)
{
return UtilityClass.CompareClassNames(hWnd, "Internet Explorer_Server");
}
}
}
Sorry this is not for selenium, but it is how I solved the problem for WatiN so I hope it can help. The code is here http://itin.codeplex.com/, and I also think that this has been added to WatiN as well.
In theory it would work as long Selenium can inject JS into the browser component. You would need to use the *custom command and pass in the executable that you want Selenium to start up and then it will try do what you want.
We hacked the selenium webdriver code slightly to attach to an embedded IE instance inside a windows app. http://bradbax.blogspot.ca/2013/07/driving-embedded-wpf-browser-with.html