【问题标题】:Properly Attach to existing chrome driver with C# Selenium Webdriver使用 C# Selenium Webdriver 正确附加到现有的 chrome 驱动程序
【发布时间】:2021-09-11 16:53:30
【问题描述】:

我使用了这个由 Tarun Lalwani 设计的method,通过在 C# 中重用 url 和 sessionID 来附加 Selenium Chrome 驱动程序。此附加部分有效,但某些驱动程序方法(例如 FindElement(By.ID) 显示错误 "invalid argument: invalid locator (Session info: chrome=91.0.4472.114)" 在此行:

    var respBase = base.Execute(driverCommandToExecute, parameters);

我的猜测是,当附加驱动程序时,选项或所需功能为空。但我还没有找到在 ReuseRemoteWebDriver 上正确设置它的方法。 含有附属的司机的样子的图片 here。 我该如何解决这个问题,以便我可以附加以前的 chrome 驱动程序并保留所有预期的 selenium 功能?

 static void Main(string[] args)
        {

            InputSimulator teclado = new InputSimulator();
            ChromeOptions options = new ChromeOptions();
            options.UseSpecCompliantProtocol = true;
            ChromeDriverService service = ChromeDriverService.CreateDefaultService(@"Thepathofchromedriver");
            IWebDriver driver;
            DesiredCapabilities capabilities = new DesiredCapabilities();

            Uri myUri = new Uri("http://127.0.0.1:65431", UriKind.Absolute);
            service.Port = 65431;
            string ID = "1f42d5f0ad105910e8d2fc7be23480a9";
            if (ID != "")
            {
                
                IWebDriver drivertest1 = new ChromeDriver(service, options);
                
                IWebDriver drivertest = new ReuseRemoteWebDriver(myUri, ID,capabilities,options);
                driver = drivertest;
            }
            else
            {
                IWebDriver drivertest = new ChromeDriver(service,options);
                
                driver = drivertest;


            }

        IWebElement inputUser = driver.FindElement(By.Id("ID"));}


public class ReuseRemoteWebDriver : OpenQA.Selenium.Remote.RemoteWebDriver
    {
        private String _sessionId;
        
        public ReuseRemoteWebDriver(Uri remoteAddress, String sessionId, OpenQA.Selenium.Remote.DesiredCapabilities capability, ChromeOptions options)
            : base(remoteAddress,options)

        {
            this._sessionId = sessionId;
            var sessionIdBase = this.GetType()
                .BaseType
                .GetField("sessionId",
                          System.Reflection.BindingFlags.Instance |
                          System.Reflection.BindingFlags.NonPublic);
            sessionIdBase.SetValue(this, new OpenQA.Selenium.Remote.SessionId(sessionId));

            
        }

        protected override OpenQA.Selenium.Remote.Response
            Execute(string driverCommandToExecute, System.Collections.Generic.Dictionary<string, object> parameters)
        {
            if (driverCommandToExecute == OpenQA.Selenium.Remote.DriverCommand.NewSession)
            {
                var resp = new OpenQA.Selenium.Remote.Response();
                resp.Status = OpenQA.Selenium.WebDriverResult.Success;
                resp.SessionId = this._sessionId;
                resp.Value = new System.Collections.Generic.Dictionary<String, Object>();
                return resp;
            }
            var respBase = base.Execute(driverCommandToExecute, parameters);
            return respBase;
        }
    }

更新:正如我在回复中指出的那样,我可以解决大多数问题。 我无法恢复的最重要的功能是注入 js 脚本

    IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    var script = "your script";
    js.ExecuteScript(script);

任何关于如何恢复注入脚本功能的想法将不胜感激。

【问题讨论】:

    标签: c# selenium google-chrome selenium-webdriver selenium-chromedriver


    【解决方案1】:

    如果有人感兴趣,我将之前的类修改如下,所以我可以使用 sendKeysToElement

        public class ReuseRemoteWebDriver : OpenQA.Selenium.Remote.RemoteWebDriver
        {
            private String _sessionId;
    
            public ReuseRemoteWebDriver(Uri remoteAddress, String sessionId, ChromeOptions options, ChromeDriverService service)
                : base(remoteAddress, options)
    
            {
                //object x = driver;
                this._sessionId = sessionId;
    
                var sessionIdBase = this.GetType()
                    .BaseType
                    .GetField("sessionId",
                              System.Reflection.BindingFlags.Instance |
                              System.Reflection.BindingFlags.NonPublic);
    
    
                //System.Collections.Generic.Dictionary<string, object> x = this.GetCapabilitiesDictionary(capability);
    
    
                sessionIdBase.SetValue(this, new OpenQA.Selenium.Remote.SessionId(sessionId));
    
    
            }
    
            protected override OpenQA.Selenium.Remote.Response
                Execute(string driverCommandToExecute, System.Collections.Generic.Dictionary<string, object> parameters)
            {
                if (driverCommandToExecute == OpenQA.Selenium.Remote.DriverCommand.NewSession)
                {
                    var resp = new OpenQA.Selenium.Remote.Response();
                    resp.Status = OpenQA.Selenium.WebDriverResult.Success;
                    resp.SessionId = this._sessionId;
                    resp.Value = new System.Collections.Generic.Dictionary<String, Object>();
                    return resp;
                }
                if (driverCommandToExecute == "sendKeysToElement")
                {
                    object[] array = (object[])parameters["value"];
    
                    string stringfinal = (string)array[0].ToString();
    
    
                    parameters.Add("text", stringfinal);
    
                }
                if (driverCommandToExecute == "executeScript")
                {
                    Console.WriteLine("");
                }
                var respBase = base.Execute(driverCommandToExecute, parameters);
                return respBase;
            }
        }
    }
    
    

    在其他类中,我使用以下方法正确使用了 Selenium 等待。

       public Boolean WaitInteligente(WebDriverWait wait, string condition, By selector = null, 
                IWebElement optionalWebElement = null,string optionalstring = null,
                bool optionalbool = false,bool devolverexcepcion=true )
            {
                TimeSpan Tiempo = wait.Timeout;
                var globalclock = Stopwatch.StartNew();
                Boolean stop = false;
                double segundos = globalclock.Elapsed.TotalSeconds;
                Exception exception = null;
                //globalclock.Stop();
                while (segundos <= Tiempo.TotalSeconds)
                {
                    Thread.Sleep(500);
                    try
                    {
                        segundos = globalclock.Elapsed.TotalSeconds;
                        if (condition == "ElementExists")
                            wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementExists(selector));
                        if (condition == "ElementIsVisible")
                            wait.Until(ExpectedConditions.ElementIsVisible(selector));
                        if (condition == "ElementToBeClickable")
                            wait.Until(ExpectedConditions.ElementToBeClickable(selector));
                        if (condition == "ElementToBeSelected")
                            wait.Until(ExpectedConditions.ElementToBeSelected(selector));
                        if (condition == "FrameToBeAvailableAndSwitchToIt")
                            wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(selector));
                        if (condition == "InvisibilityOfElementLocated")
                            wait.Until(ExpectedConditions.InvisibilityOfElementLocated(selector));
                        if (condition == "PresenceOfAllElementsLocatedBy")
                            wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(selector));
                        if (condition == "VisibilityOfAllElementsLocatedBy")
                            wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(selector));
                        if (condition == "AlertIsPresent")
                            wait.Until(ExpectedConditions.AlertIsPresent());
                        if (condition == "ElementToBeSelected")
                            wait.Until(ExpectedConditions.ElementToBeSelected(optionalWebElement));
                        if (condition == "InvisibilityOfElementWithText")
                            wait.Until(ExpectedConditions.InvisibilityOfElementWithText(selector,optionalstring));
                        if (condition == "StalenessOf")
                            wait.Until(ExpectedConditions.StalenessOf(optionalWebElement));
                        if (condition == "TextToBePresentInElement")
                            wait.Until(ExpectedConditions.TextToBePresentInElement(optionalWebElement,optionalstring));
                        if (condition == "TextToBePresentInElementLocated")
                            wait.Until(ExpectedConditions.TextToBePresentInElementLocated(selector, optionalstring));
                        if (condition == "TextToBePresentInElementValue")
                            wait.Until(ExpectedConditions.TextToBePresentInElementValue(selector, optionalstring));
                        if (condition == "TitleContains")
                            wait.Until(ExpectedConditions.TitleContains(optionalstring));
                        if (condition == "TitleIs")
                            wait.Until(ExpectedConditions.TitleIs(optionalstring));
                        if (condition == "UrlContains")
                            wait.Until(ExpectedConditions.UrlContains(optionalstring));
                        if (condition == "UrlMatches")
                            wait.Until(ExpectedConditions.UrlMatches(optionalstring));
                        if (condition == "UrlToBe")
                            wait.Until(ExpectedConditions.UrlToBe(optionalstring));
                        if (condition == "FrameToBeAvailableAndSwitchToIt")
                            wait.Until(ExpectedConditions.FrameToBeAvailableAndSwitchToIt(optionalstring));
                        if (condition == "AlertState")
                            wait.Until(ExpectedConditions.AlertState(optionalbool));
                        if (condition == "ElementSelectionStateToBe")
                            wait.Until(ExpectedConditions.ElementSelectionStateToBe(selector,optionalbool));
                        if (condition == "ElementSelectionStateToBe")
                            wait.Until(ExpectedConditions.ElementSelectionStateToBe(selector, optionalbool));
    
    
                        stop = true;
                        break;
                    }
                    catch (Exception e)
                    {
                         e = new Exception(selector.ToString() + condition + e.Message);
                        exception = e;
                    }
                }
    
                if (!stop && devolverexcepcion)
                    throw exception;
    
                return stop;
            }
    

    附加时不能正常工作的方法是 driver.FindElement(By.Id) 和 driver.FindElement(By.ClassName) 可以通过分别使用 By.CssSelector 调用 ID 或 Classname 轻松绕过。

    我无法恢复的最重要的功能是注入 js 脚本

      IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    var script = "your script";
    js.ExecuteScript(script);
    

    任何关于如何恢复注入脚本功能的想法将不胜感激。

    【讨论】:

      猜你喜欢
      • 2016-06-21
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 2013-10-16
      • 2014-11-16
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      相关资源
      最近更新 更多