【问题标题】:Selenium Webdriver 3.141.0 driver.Manage().Logs.AvailableLogTypes throwing System.NullReference ExceptionSelenium Webdriver 3.141.0 driver.Manage().Logs.AvailableLogTypes 抛出 System.NullReference 异常
【发布时间】:2019-08-16 07:08:01
【问题描述】:

在我最新的 Chrome 更新到 76 版本后,我使用 driver.Manage().Logs.GetLog(LogType.Browser) 获取任何控制台日志的 Selenium 代码 sn-p 抛出错误。注意Logs.AvaialbleLogTypes 正在抛出NullReference exception。我们需要启用任何设置吗?有没有其他方法可以得到控制台错误

我尝试使用LoggingPreferences,但返回无效参数错误并且无法打开 chrome 驱动程序

【问题讨论】:

  • 您使用的是哪个版本的 ChromDriver?如果 Chrome 已更新,您还需要更新 ChromeDriver。
  • 我也有同样的问题。我更新到最新的 chrome 驱动程序,但它没有解决问题。

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


【解决方案1】:

这是我快速而肮脏的解决方案(直到 selenium 4 出来,这个问题得到解决) - 它正在工作,您可以对其进行改进并添加更多检查和验证。

我将它作为扩展方法 GetBrowserLogs 公开

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;

namespace SeleniumConsumer
{
    internal static class Program
    {
        private static void Main()
        {
            // setup options
            var options = new ChromeOptions();
            options.SetLoggingPreference(LogType.Browser, LogLevel.All);

            // do whatever actions
            var driver = new ChromeDriver(options)
            {
                Url = "https://www.yahoo.com/"
            };

            // extract logs
            foreach (var log in driver.GetBrowserLogs())
            {
                Console.WriteLine($"{log["timestamp"]}: {log["message"]}");
            }

            // cleanup
            driver.Dispose();
            Console.WriteLine();
            Console.WriteLine("Press any key to exit...");
            Console.ReadLine();
        }
    }

    public static class WebDriverExtensions
    {
        public static IEnumerable<IDictionary<string, object>> GetBrowserLogs(this IWebDriver driver)
        {
            // setup
            var endpoint = GetEndpoint(driver);
            var session = GetSession(driver);
            var resource = $"{endpoint}session/{session}/se/log";
            const string jsonBody = @"{""type"":""browser""}";

            // execute
            using (var httpClient = new HttpClient())
            {
                var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
                var response = httpClient.PostAsync(resource, content).GetAwaiter().GetResult();
                var responseBody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                return AsLogEntries(responseBody);
            }
        }

        private static string GetEndpoint(IWebDriver driver)
        {
            // setup
            const BindingFlags Flags = BindingFlags.Instance | BindingFlags.NonPublic;

            // get RemoteWebDriver type
            var remoteWebDriver = GetRemoteWebDriver(driver.GetType());

            // get this instance executor > get this instance internalExecutor
            var executor = remoteWebDriver.GetField("executor", Flags).GetValue(driver) as DriverServiceCommandExecutor;
            var internalExecutor = executor.GetType().GetField("internalExecutor", Flags).GetValue(executor) as HttpCommandExecutor;

            // get URL
            var uri = internalExecutor.GetType().GetField("remoteServerUri", Flags).GetValue(internalExecutor) as Uri;

            // result
            return uri.AbsoluteUri;
        }

        private static Type GetRemoteWebDriver(Type type)
        {
            if (!typeof(RemoteWebDriver).IsAssignableFrom(type))
            {
                return type;
            }

            while(type != typeof(RemoteWebDriver))
            {
                type = type.BaseType;
            }

            return type;
        }

        private static SessionId GetSession(IWebDriver driver)
        {
            if (driver is IHasSessionId id)
            {
                return id.SessionId;
            }
            return new SessionId($"gravity-{Guid.NewGuid()}");
        }

        private static IEnumerable<IDictionary<string, object>> AsLogEntries(string responseBody)
        {
            // setup
            var value = $"{JToken.Parse(responseBody)["value"]}";
            return  JsonConvert.DeserializeObject<IEnumerable<Dictionary<string, object>>>(value);
        }
    }
}

【讨论】:

    【解决方案2】:

    此问题目前已损坏,仅在 Selenium 4 alpha 版本中修复:https://github.com/SeleniumHQ/selenium/issues/7342

    从阅读问题看来,对 chromedriver 的更改似乎需要更改 .Net Selenium 实现以纠正问题。

    【讨论】:

      猜你喜欢
      • 2016-09-16
      • 2017-07-23
      • 1970-01-01
      • 2013-02-22
      • 2018-07-14
      • 2017-11-25
      • 2012-02-07
      • 2017-10-16
      相关资源
      最近更新 更多