.net 是否可以将Selenium与包含WebBrowser对象的C#windows窗体一起使用?
我想知道是否可以将Selenium与C#Windows窗体一起使用 包含WebBrowser对象的 我在用硒 我能够用Selenium脚本记录创建测试用例;我是 只是想确定我是否可以导出C代码和 让它在C#环境中运行。我很感激你的任何想法或建议 解释 更新 我要让Selenium打开包含WebBrowser组件的WinForm。然而,从那里我的测试将不会执行。看起来它不理解selenium命令。但是我没有看到任何错误消息被抛出。嗯 问题是用webbrowser打开winForm的.net 是否可以将Selenium与包含WebBrowser对象的C#windows窗体一起使用?,.net,winforms,selenium,webbrowser-control,.net,Winforms,Selenium,Webbrowser Control,我想知道是否可以将Selenium与C#Windows窗体一起使用 包含WebBrowser对象的 我在用硒 我能够用Selenium脚本记录创建测试用例;我是 只是想确定我是否可以导出C代码和 让它在C#环境中运行。我很感激你的任何想法或建议 解释 更新 我要让Selenium打开包含WebBrowser组件的WinForm。然而,从那里我的测试将不会执行。看起来它不理解selenium命令。但是我没有看到任何错误消息被抛出。嗯 问题是用webbrowser打开winForm的winformW
winformWithWebBrowserTest
.exe被打开。
但什么也没发生。下面的代码是启动.exe的代码
测试代码(Selenium命令)
.exe
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//this gets executed always......
HtmlElement head = webBrowser1.Document.GetElementsByTagName("body")[0];
HtmlElement scriptOne = webBrowser1.Document.CreateElement("script");
IHTMLScriptElement element = (IHTMLScriptElement)scriptOne.DomElement;
element.text = "function sayHello() { " +
"alert('hello');" +
" }" ;
head.AppendChild(scriptOne);
webBrowser1.Document.InvokeScript("sayHello");
}
//getter setter.....
public WebBrowser getWebBrowser()
{
return this.webBrowser1;
}
public void setWebBrowser(WebBrowser wb)
{
this.webBrowser1 = wb;
}
//just address bar
private void button1_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(textBox1.Text))
{
webBrowser1.Navigate(textBox1.Text);
}
}
//just address bar
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if (textBox1.Text != e.Url.ToString())
{
textBox1.Text = e.Url.ToString();
}
}
}
}
更新
我简化了我的测试,所以现在我不用NUnit了。我创建了C#控制台应用程序,只是为了运行C#.exe文件。但在我的控制台中,它只会输出“--1--”和“--2--”
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Selenium;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("-- 1---");
ISelenium selenium;
selenium = new DefaultSelenium
("localhost", 4444, "*custom C:\\Users\\m-takayashiki\\Documents\\Visual Studio 2010\\Projects\\winformWithWebBrowserTest\\winformWithWebBrowserTest\\bin\\Release\\winformWithWebBrowserTest.exe", "http://www.livemocha.com");
Console.WriteLine("-- 2---");
selenium.Start();
Console.WriteLine("-- 3---");
selenium.Open("/");
selenium.WaitForPageToLoad("30000");
selenium.Open("/users/logout");
selenium.Open("/users/login");
Console.WriteLine("test test test");
//tear down
selenium.Stop();
}
}
}
更新
我查看了RC日志:
15:40:35.379 DEBUG [13] org.openqa.jetty.http.HttpContext - Handler org.openqa.selenium.server.SeleniumDriverResourceHandler in HttpContext[/selenium-server,/selenium-server]
15:40:35.380 DEBUG [13] org.openqa.selenium.server.SeleniumDriverResourceHandler - req: POST /selenium-server/driver/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: localhost:4444
Content-Length: 247
Expect: 100-continue
Connection: keep-alive
15:40:45.408 DEBUG [13] org.openqa.selenium.server.FrameGroupCommandQueueSet - waiting for window 'null' local frame 'null' for 1790 more secs
15:40:45.408 DEBUG [13] org.openqa.selenium.server.FrameGroupCommandQueueSet - waiting for condition for 1000 more ms
15:40:45.945 DEBUG [12] org.openqa.selenium.server.FrameGroupCommandQueueSet - got condition? : false
理论上,只要Selenium能够将JS注入浏览器组件,它就可以工作。您需要使用*custom命令并传入希望Selenium启动的可执行文件,然后它将尝试执行您想要的操作。我认为您可以,但您可能必须使用。它有一个.Net版本的Selenium API。我还没有用Selenium实现这一点,但当我想自动化InfoPath时,我用WatiN也做了同样的事情。我采取的方法如下:
杀死所有具有该名称的进程(在我的例子中是“infopath”)
启动测试应用程序调用Process.getProcessByName以获取所有进程id,然后获取第一个进程的窗口句柄,因为应该只有一个进程在运行
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;
既然我有了窗口句柄,我就可以使用WatiN自动处理IHTMLDocument2
InternalHTMLDOMDocument = IEDom.IEDOMFromhWnd(this.hWnd);
在IEDom类中,真正的橡胶击中道路。。。代码如下
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");
}
}
}
很抱歉,这不是硒的问题,但这是我为WatiN解决问题的方法,所以我希望它能有所帮助。代码在这里,我还认为这也被添加到了WatiN中。我们对selenium webdriver代码进行了轻微的黑客攻击,以附加到windows应用程序中的嵌入式IE实例 关于硒的阅读非常有趣。看来只有selenium2可以处理.NET实现。我是.NET维护者,所以只展示代码的大小写。它有.NET、Java、Ruby和Pythonaldo。如果我的理解正确的话,看起来有人以前做过这件事。等待project white不使用硒。。winformProject White的just自动化框架构建在WPF附带的Microoft UI自动化堆栈之上。是的,我知道selenium测试可以使用C#编写,但我不确定selenium是否能够以某种方式与winForm对话,winForm是否能够理解自动执行某些操作的命令,如button click etcAll,您需要做的就是调用C#代码中所需的任何内容。如果您想使用winform按钮,那么只需使用buttonname.PerformClick()。如果您想运行某个特定的函数,那么调用该函数应该很简单。您的意思是,selenium只用于执行,而C#代码的其余部分是。。。只是c代码???我的意思是不要像“selenium.open(“/somepath”)”那样使用seleniese,因为seleniese似乎不适合我。你应该可以很好地使用seleniese。你是如何进行测试的?努尼特?主要功能?我正在运行NUnit,这有区别吗???但问题是,比如说,客户端创建了clientCSharp.exe,而我用cs编写的测试代码必须识别clientCSharp.exe中的webbrowser控件才能实现自动化。感谢您提供的示例代码,我将尝试用Selenium应用此方法。@masato san 2015年的问候语。你有没有做到这一点?
InternalHTMLDOMDocument = IEDom.IEDOMFromhWnd(this.hWnd);
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");
}
}
}