如何在Selenium中读取Web浏览器控制台?

3
我可以帮你翻译这段内容。它涉及到IT技术相关的话题。
我在使用Selenium 2.46.0版本。为了调试不同的问题(例如客户端问题),我想获取所有的网络浏览器控制台内容(错误、警告...)。
我尝试使用:
LogEntries logs1 = DefaultDriver.getWebDriver().manage().logs().get("client");

但是得到了空的日志条目...

顺便说一下,我定义了这些功能:

capabilities = DesiredCapabilities.firefox();
LoggingPreferences logs = new LoggingPreferences();
logs.enable( LogType.CLIENT, Level.ALL );
capabilities.setCapability( CapabilityType.LOGGING_PREFS, logs );
webDriver = new FirefoxDriver( capabilities );

我尝试了“driver”和“browser”这两种日志类型,但是没有得到Web控制台的内容。
你有什么想法吗?
以下链接中的解决方案都没有起作用... 使用Selenium捕获浏览器日志

可能是使用Selenium捕获浏览器日志的重复问题。 - undefined
@Eugene,该链接中描述的解决方案没有起作用。 - undefined
你需要使用.get(LogType.BROWSER),而不是.get("client")。你代码中的能力部分没问题。 - undefined
3个回答

1

我在使用C#的selenium时遇到了相同的问题,我想展示我的解决方法,适用于所有浏览器(在C#中)

首先,我将网站生成的所有日志重定向到一个数组中存储所有日志。 同时,我将onerror函数重定向以收集所有JavaScript错误。

    private void BindConsole(IWebDriver webDriver)
  {
     var script = "if (console.everything === undefined) {
        console.everything = [];
        console.defaultLog = console.log.bind(console);
        console.log = function(){
           const args = Array.prototype.slice.call(arguments).join('_');
           console.everything.push({ 'Type':'Log', 'Datetime':Date().toLocaleString(), 'Value':args});
           console.defaultLog.apply(console, arguments);
        }
        console.defaultError = console.error.bind(console);
        console.error = function(){
           const args = Array.prototype.slice.call(arguments).join('_');
           console.everything.push({ 'Type':'Error', 'Datetime':Date().toLocaleString(), 'Value':args});
           console.defaultError.apply(console, arguments);
        }
        console.defaultWarn = console.warn.bind(console);
        console.warn = function(){
           const args = Array.prototype.slice.call(arguments).join('_');
           console.everything.push({ 'Type':'Warn', 'Datetime':Date().toLocaleString(), 'Value':args});
           console.defaultWarn.apply(console, arguments);
        }
        console.defaultDebug = console.debug.bind(console);
        console.debug = function(){
           const args = Array.prototype.slice.call(arguments).join('_');
           console.everything.push({ 'Type':'Debug', 'Datetime':Date().toLocaleString(), 'Value':args});
           console.defaultDebug.apply(console, arguments);
        }
        window.onerror = function(message, url, linenumber) {
           console.error('JavaScript error: ' + message + ' on line ' +
           linenumber + ' for ' + url);
           }
        }";

     ((IJavaScriptExecutor)webDriver).ExecuteScript(script);
  }

注意:在进行测试之前,您需要运行此函数,因为日志不会被捕获,并且每次刷新或更改页面时重新运行它(在刷新/更改所有日志时都将丢失,因此请提前保存)。
然后,我有一个对象,与我的函数中的日志签名匹配。
 public class LogEntry
   {
      public LogType Type { get; set; }
      public string Datetime { get; set; }
      public string Value { get; set; }
   }

 public enum LogType
   {
      Error,
      Warn,
      Log,
      Debug
   }

然后我运行以下函数:

 /// <summary>
  /// Check whether new blogs are in browser console and captures them if any. 
  /// </summary>
  /// <returns>Logs from browser console</returns>
  public IEnumerable<LogEntry> GetAllConsoleLogs()
  {
     SystemTools.Delay();

     var jsScript = "return console.everything";
     var list = ((IJavaScriptExecutor)_driver.Driver).ExecuteScript(jsScript) as IReadOnlyCollection<object>;
     if (list!=null && list.Count > 0) {
        var token = JArray.FromObject(list);
        ClearConsole();
        return token.ToObject<IEnumerable<LogEntry>>();
     } else {
        return null;
     }
  }
  

  /// <summary>
  /// Delete all previous entrys form browser console, so only new ones will be captured
  /// </summary>
  private void ClearConsole()
  {
     var jsScript = "console.everything =[];";
     ((IJavaScriptExecutor)_driver.Driver).ExecuteScript(jsScript);
  }

这个函数接受一个包含日志的数组(Json格式),并利用.NET Json库将其转换为C#对象。

每次获取日志时,我清除对象,因为我只想检查新的日志。如果这种行为不适合您,可以删除调用此函数并保留所有测试的日志。


0

你可以尝试这个:

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

def get_logs2(driver):
# enable browser logging
    #d = DesiredCapabilities.CHROME
    #d['goog:loggingPrefs'] = { 'browser':'ALL' }
    #driver = webdriver.Chrome(desired_capabilities=d)

    # load the desired webpage
    #driver.get('http://34.90.50.21/')
    #driver.get(driver.current_url)
    a = driver.get_log('browser')

    # print messages
    for entry in driver.get_log('browser'):
        print(entry)
    print("finished")
    return a

或者查看这个:使用Robot Framework/selenium在Robot Framework中获取背景调用


0

我不确定这个方法是否有效。 但你可以尝试以下类似的方式在控制台中打开:

Actions builder = new Actions(pbDriver); builder.keyDown(Keys.CONTROL).sendKeys(Keys.F12).keyUp(Keys.CONTROL).perform();

然后使用Selenium与控制台进行交互。

或者,

你可以尝试一个不太优雅的解决方案,通过从用户数据目录中'手动'获取日志:

  1. 将用户数据目录设置为固定位置:

    options = new ChromeOptions(); capabilities = DesiredCapabilities.chrome(); options.addArguments("user-data-dir=/your_path/"); capabilities.setCapability(ChromeOptions.CAPABILITY, options);

  2. 从上述输入路径中的chrome_debug.log文件中获取文本

编辑:

我实际上尝试了问题中提到的方法,并且对我有效。我使用的浏览器是Chrome。正如Siking所指出的,我使用了.enable(LogType.BROWSER)来获取日志。 以下代码会打印出整个运行期间捕获到的所有日志。

LogEntries logEntries = pbDriver.manage().logs().get("browser"); for (LogEntry entry : logEntries) { System.out.println(entry.getMessage());

而且我刚学到,由于开发者工具不是 DOM 模型的一部分,无法使用 Selenium 进行交互。可以使用 Sikuli 来完成这项工作。


你可以使用Selenium与控制台进行交互。你能展示一个工作的例子吗? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接