Capturing browser logs with Selenium WebDriver using Java
Asked Answered
F

10

80

Is there a way to capture browser logs while running automated test cases with Selenium? I found an article on how to capture JavaScript errors in Selenium. But that is just for Firefox and only for errors. I would like to get all the console logs.

Friend answered 21/8, 2014 at 16:30 Comment(0)
F
73

I assume it is something in the lines of:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class ChromeConsoleLogging {
    private WebDriver driver;


    @BeforeMethod
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "c:\\path\\to\\chromedriver.exe");        
        DesiredCapabilities caps = DesiredCapabilities.chrome();
        LoggingPreferences logPrefs = new LoggingPreferences();
        logPrefs.enable(LogType.BROWSER, Level.ALL);
        caps.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
        driver = new ChromeDriver(caps);
    }

    @AfterMethod
    public void tearDown() {
        driver.quit();
    }

    public void analyzeLog() {
        LogEntries logEntries = driver.manage().logs().get(LogType.BROWSER);
        for (LogEntry entry : logEntries) {
            System.out.println(new Date(entry.getTimestamp()) + " " + entry.getLevel() + " " + entry.getMessage());
            //do something useful with the data
        }
    }

    @Test
    public void testMethod() {
        driver.get("http://mypage.com");
        //do something on page
        analyzeLog();
    }
}

Source : Get chrome's console log

Franco answered 21/8, 2014 at 16:33 Comment(5)
Not sure what browser support you need, but by changing import org.openqa.selenium.chrome.ChromeDriver; and DesiredCapabilities caps = DesiredCapabilities.chrome(); you should be able to select it.Franco
I would be requiring for all the browsers ...thanks for this . It is definitely something which i can work with @FrancoFriend
nice solution for chrome but have you a solution for IE11?Riposte
@Franco If i call driver.manage().logs().get("browser"); multiple times with in the same driver instance, it fails to capture entries (tried refreshing driver, navigating to another url). Any thoughts or workarounds?Cutlip
@Friend Last time I checked it wasn't supported for IE see github.com/SeleniumHQ/selenium/issues/4802Endogenous
P
64

In a more concise way, you can do:

LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

For me it worked wonderfully for catching JS errors in console. Then you can add some verification for its size. For example, if it is > 0, add some error output.

Padraig answered 21/10, 2014 at 14:3 Comment(5)
awesome, did not have to set desired capabilities and worked like charm.Winger
nice solution for chrome but have you a solution for IE11?Riposte
IE11 WebDriver should have the same API and act similarly.Padraig
@Stas If i call driver.manage().logs().get("browser"); multiple times with in the same driver instance, it fails to capture entries (tried refreshing driver, navigating to another url). Any thoughts or workarounds?Cutlip
@ManPy what WebDriver implementation (==browser), driver version & language are you using?Padraig
B
25

As a non-java selenium user, here is the python equivalent to Margus's answer:

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

class ChromeConsoleLogging(object):

    def __init__(self, ):
        self.driver = None

    def setUp(self, ):
        desired = DesiredCapabilities.CHROME
        desired ['loggingPrefs'] = { 'browser':'ALL' }
        self.driver = webdriver.Chrome(desired_capabilities=desired)

    def analyzeLog(self, ):
        data = self.driver.get_log('browser')
        print(data)

    def testMethod(self, ):
        self.setUp()
        self.driver.get("http://mypage.com")
        self.analyzeLog()

Reference

Edit: Keeping Python answer in this thread because it is very similar to the Java answer and this post is returned on a Google search for the similar Python question

Barrick answered 2/12, 2016 at 20:14 Comment(2)
forgot semi colon on analyzeLog functionPrepossession
Starting from chromedriver, 75.0.3770.8, you have to use goog:loggingPrefs instead of loggingPrefs.Stylo
C
6

Adding LoggingPreferences to "goog:loggingPrefs" properties with the Chrome Driver options can help to fetch the Browser console logs for all Log levels.

ChromeOptions options = new ChromeOptions();    
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
options.setCapability("goog:loggingPrefs", logPrefs);
WebDriver driver = new ChromeDriver(options);
Concettaconcettina answered 11/6, 2020 at 16:9 Comment(0)
T
5

A less elegant solution is taking the log 'manually' from the user data dir:

  1. Set the user data dir to a fixed place:

    options = new ChromeOptions();
    capabilities = DesiredCapabilities.chrome();
    options.addArguments("user-data-dir=/your_path/");
    capabilities.setCapability(ChromeOptions.CAPABILITY, options);
    
  2. Get the text from the log file chrome_debug.log located in the path you've entered above.

I use this method since RemoteWebDriver had problems getting the console logs remotely. If you run your test locally that can be easy to retrieve.

Telepathist answered 20/6, 2016 at 14:58 Comment(0)
M
3

Starting with Firefox 65 an about:config flag exists now so console API calls like console.log() land in the output stream and thus the log file (see (https://github.com/mozilla/geckodriver/issues/284#issuecomment-458305621).

profile = new FirefoxProfile();
profile.setPreference("devtools.console.stdout.content", true);
Modestine answered 29/1, 2019 at 7:43 Comment(0)
S
1

Driver manager logs can be used to get console logs from browser and it will help to identify errors appears in console.

   import org.openqa.selenium.logging.LogEntries;
   import org.openqa.selenium.logging.LogEntry;

    public List<LogEntry> getBrowserConsoleLogs()
    {
    LogEntries log= driver.manage().logs().get("browser")
    List<LogEntry> logs=log.getAll();
    return logs;
    }
Sorcery answered 8/3, 2020 at 17:4 Comment(0)
R
0

Before launching webdriver, we just set this environment variable to let chrome generate it:

export CHROME_LOG_FILE=$(pwd)/tests/e2e2/logs/client.log
Rooftree answered 21/4, 2020 at 16:52 Comment(0)
A
0

Add cast RemoteWebDriver to driver initialize and you will have the .setLogLevel method:

import java.util.logging.Level;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;

public class PrintLogTest {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "/Users/.../chromedriver");
        WebDriver driver = new ChromeDriver();

        //here
        ((RemoteWebDriver) driver).setLogLevel(Level.INFO);

        driver.get("https://google.com/");
        driver.findElement(By.name("q")).sendKeys("automation test");
        driver.quit();
    }
}

Example output:

Jun 15, 2020 4:27:04 PM org.openqa.selenium.remote.RemoteWebDriver log
INFO: Executing: get [430aec21a9beb6340a4185c4ea6a693d, get {url=https://google.com/}]
Jun 15, 2020 4:27:06 PM org.openqa.selenium.remote.RemoteWebDriver log
INFO: Executed: [430aec21a9beb6340a4185c4ea6a693d, get {url=https://google.com/}]
Jun 15, 2020 4:27:06 PM org.openqa.selenium.remote.RemoteWebDriver log
INFO: Executing: findElement [430aec21a9beb6340a4185c4ea6a693d, findElement {using=name, value=q}]
Jun 15, 2020 4:27:06 PM org.openqa.selenium.remote.RemoteWebDriver log
INFO: Executed: [430aec21a9beb6340a4185c4ea6a693d, findElement {using=name, value=q}]
...
...

At least I've tried it on ChromeDriver() and FirefoxDriver() and it working fine.

Allstar answered 15/6, 2020 at 9:51 Comment(1)
But isn't this just logging what the driver is doing and not what is in the browser console?Reputation
Q
0

Browser and performance logging only captures whatever is logged to the console and connection metadata in Chrome (at least, at the time of this writing). To actually get the contents of a fetch request I found some JS (source) to intercept all fetch requests and log the contents to the console which I could then access in browser logs. Total overkill, but hey it works.

const { fetch: originalFetch } = window;
window.fetch = async (...args) => {
  let [resource, config] = args;

  let response = await originalFetch(resource, config);

  response
    .clone()
    .json()
    .then((data) => console.log("fetch response:" + JSON.stringify(data)));

  return response;
};

Minified

const{fetch:originalFetch}=window;window.fetch=async(...n)=>{let[t,e]=n,o=await originalFetch(t,e);return o.clone().json().then((n=>console.log("fetch :"+JSON.stringify(n)))),o};

Usage snippet (Scala)

driver.executeScript("""const{fetch:originalFetch}=window;window.fetch=async(...n)=>{let[e,o]=n,t=await originalFetch(e,o);return t.clone().json().then((n=>console.log("fetch response:"+JSON.stringify(n)))),t};""")

// action that triggers the fetch

val logEntry = driver.manage().logs().get("browser").iterator().asScala.filter(_.getMessage.contains("fetch response:")).toList
Quiroz answered 23/4, 2023 at 23:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.