获取已打开的Chrome浏览器的WebDriver

问题描述 投票:0回答:1

我希望有一个像Chrome这样已经打开的浏览器的IWebDriver。因为那时我需要自动化表单身份验证和/或基本身份验证。

我以为这个

IWebDriver driver = new RemoteWebDriver(new System.Uri("http://localhost:4445/wd/hub"), new ChromeOptions());

会做的伎俩,但它只打开另一个镀铬窗口。相反,我想“阅读”已经打开的那个。

硒有可能吗?我应该使用另一个图书馆吗?

c# selenium selenium-chromedriver
1个回答
2
投票

根据Selenium Issues页面:https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/18

该问题已关闭并标记为不可行连接到现有浏览器的过程将基于每个浏览器。在IE中执行此操作可能很容易,但在Chrome或Firefox中执行此操作会有问题。

例如:Chrome实际上通过network / tcp json请求从Selenium接收命令到特定端口。当Selenium驱动程序停止运行时 - 它会丢失Chrome调试端口的端口号。端口可能仍然是打开的,但它可以是10000到30000之间的任何东西等

即使你为Chrome解决它,它也需要另一个定制的Firefox解决方案。

除非您的身份验证有“Captcha”或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被删除和替换 - 它会更好地工作。

© www.soinside.com 2019 - 2024. All rights reserved.