我想要一个已经打开过的浏览器的IWebDriver,比如Chrome。因为那时我需要自动化表单身份验证和/或基本身份验证。
我以为这个
IWebDriver driver = new RemoteWebDriver(new System.Uri("http://localhost:4445/wd/hub"), new ChromeOptions());
可以做到这一点,但它只打开另一个镀铬窗口。相反,我想"阅读"一个已经开放的。
硒有可能吗?我应该使用另一个图书馆吗?
答案 0 :(得分:2)
根据Selenium Issues页面: https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/18
该问题已结束并标记为不可行 连接到现有浏览器的过程将基于每个浏览器。 在IE中进行操作可能很简单,但在Chrome或Firefox中进行操作会有问题。
例如: Chrome实际上通过网络/ tcp json请求从Selenium接收命令到特定端口。 当Selenium驱动程序停止运行时 - 它会丢失Chrome调试端口的端口号。 端口可能仍然是打开的,但它可以是10000到30000之间的任何东西
即使您为Chrome解决了这个问题,也需要另外一个针对Firefox的定制解决方案。
除非您的身份验证包含“验证码”。或bot检查到位,我建议只是自动化身份验证阶段。 一般来说 - 自动化测试是独立的,不依赖于外部干扰或外部测试,这是一种很好的做法。
浏览器应该在测试开始时开始,并在测试结束时终止。
假设您使用Selenium进行测试而非恶意目的。
Selenium在这个阶段对你没有帮助。
但是,如果您的答案/解决方案可以在Chrome上使用,而不是其他浏览器。
public static Chrome StartChromeDriver(int port)
{
try
{
string Path = Registry.Installation.GetChromeExecutable();
Process p = new Process();
ProcessStartInfo psi = new ProcessStartInfo(Path);
string args = "--remote-debugging-port="+ port.ToString()+" --user-data-dir=remote-profile";
psi.Arguments = args;
psi.Verb = "runas";
p.StartInfo = psi;
p.Start();
return new Chrome("http://localhost:" + port.ToString());
}
catch (Exception ee)
{
Console.WriteLine(ee.ToString());
return null;
}
}
这将启动一个chrome进程,调试端口打开到您提供的数字。 (您可以跟踪此情况,并重新连接并向正在运行的chrome实例重新发出命令)
public dynamic EnablePage()
{
json = @"{""id"":12345,""method"":""Page.enable""}";
Thread.Sleep(1000);
return this.SendCommand(json);
}
public dynamic EnableRuntime()
{
json = @"{""id"":12345,""method"":""Runtime.enable""}";
Thread.Sleep(1000);
return this.SendCommand(json);
}
public dynamic EnableNetwork()
{
json = @"{""id"":12345,""method"":""Network.enable""}";
Thread.Sleep(1000);
return this.SendCommand(json);
}
这是我躺在的一些代码。 有一天我很无聊,决定用Chrome自动化重新发明轮子。基本上 - 这段代码就是如何在不使用Selenium的情况下自动化Chrome。 它确实依赖于WebSockets4Net 但话虽如此 - 可能会重构使用TcpClient。 发给Chrome的所有命令都以json请求的形式完成。
例如:以下json命令会告诉chrome执行以下javascript - 基本上导航到提供的URL。
{
"method": "Runtime.evaluate",
"params": {
"expression": "document.location='urlhere'",
"objectGroup": "console",
"includeCommandLineAPI": true,
"doNotPauseOnExceptions": false,
"returnByValue": false
},
"id": 1
}
public dynamic SendCommand(string cmd)
{
if (EventHandler == null)
{
EventHandler = new Events();
EventHandler.OnNavigateStart += new Events.OnPageNavigateStart(EventHandler_OnNavigateStart);
EventHandler.OnNavigateEnd += new Events.OnPageNavigateEnded(EventHandler_OnNavigateEnd);
}
WebSocket4Net.WebSocket j = new WebSocket4Net.WebSocket(this.sessionWSEndpoint);
ManualResetEvent waitEvent = new ManualResetEvent(false);
ManualResetEvent closedEvent = new ManualResetEvent(false);
dynamic message = null;
byte[] data;
Exception exc = null;
j.Opened += delegate(System.Object o, EventArgs e)
{
j.Send(cmd);
};
j.MessageReceived += delegate(System.Object o, WebSocket4Net.MessageReceivedEventArgs e)
{
message = e.Message;
EventHandler.ParseEvents(e);
waitEvent.Set();
};
j.Error += delegate(System.Object o, SuperSocket.ClientEngine.ErrorEventArgs e)
{
exc = e.Exception;
waitEvent.Set();
};
j.Closed += delegate(System.Object o, EventArgs e)
{
closedEvent.Set();
};
j.DataReceived += delegate(object sender, WebSocket4Net.DataReceivedEventArgs e)
{
data = e.Data;
waitEvent.Set();
};
j.Open();
waitEvent.WaitOne();
if (j.State == WebSocket4Net.WebSocketState.Open)
{
j.Close();
closedEvent.WaitOne();
j = null;
}
if (exc != null)
throw exc;
serializer = null;
serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { converter });
dynamic obj = serializer.Deserialize(message, typeof(object));
message = null;
data = null;
return obj;
}
为了演示如何实际使用它 - 您可以实现页面对象并创建'类型'将对象封装在屏幕上。
例如:
public class Link : Base.Element
{
public Link(string XPath)
{
this.XPath = String.Copy(XPath);
}
/// <summary>
/// Overriding it - just in case we need to handle clicks differently
/// </summary>
/// <returns></returns>
public virtual bool Click()
{
Sync();
Console.WriteLine(Chrome.Driver.Eval("document.evaluate('" + XPath.Replace("'", "\\\\'") + "', document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ).snapshotItem(0).click();"));
return true;
}
public virtual bool WaitForExistance(int iTimeout)
{
return base.WaitForExistance(iTimeout);
}
public virtual bool Exists()
{
return base.Exists();
}
public virtual string GetText()
{
Sync();
dynamic dval = Chrome.Driver.Eval("document.evaluate('" + XPath.Replace("'", "\\\\'") + "', document.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null ).snapshotItem(0).innerText");
return dval.result.result.value;
}
}
警告 - 当我使用此代码时,WebSockets4Net中存在内存泄漏 - 因此最终必须重新启动应用程序。 也许如果WebSockets4Net被删除和替换 - 它会更好。