selenium icon indicating copy to clipboard operation
selenium copied to clipboard

[🐛 Bug]: driver.get_log() not avaliable to selenium.webdriver.remote.webdriver

Open lozik4 opened this issue 6 months ago • 2 comments

Description

After Release 4.32.0 get_log() and log_types() moved to webdriver.chromium. But if I use Remote connect I use Remote object and I can't extract logs in this case

Reproducible Code

My function    
def log_console_errors(self) -> None:
        if "chrome" in self.driver.name:
            print_error(str(type(self.driver)))
            z = self.driver.get_log("browser")
If I use local it's work ok
But if I run Remote

driver = webdriver.Remote(command_executor=f"{cfg.HUB[self.hub]}/wd/hub",
                                      client_config=ClientConfig(
                                          remote_server_addr=f"{cfg.HUB[self.hub]}/wd/hub",
                                          username=cfg.HUB_AUTH.split(":")[0],
                                          password=cfg.HUB_AUTH.split(":")[1]),
                                      options=options)

Debugging Logs

ERROR in func: log_console_errors
--------------------------------------------------------------------------------

ERROR string: <class 'selenium.webdriver.remote.webdriver.WebDriver'>

ERROR in func: pytest_runtest_makereport
--------------------------------------------------------------------------------

ERROR string: 'WebDriver' object has no attribute 'get_log'
FAILED test: TestMainBanner.test_main_banner

ℹ️ Last known working version: 4.31.0

lozik4 avatar May 21 '25 14:05 lozik4

@lozik4, thank you for creating this issue. We will troubleshoot it as soon as we can.

Selenium Triage Team: remember to follow the Triage Guide

selenium-ci avatar May 21 '25 14:05 selenium-ci

yes... see the comments here: https://github.com/SeleniumHQ/selenium/pull/15641

I am still trying to find a good solution.

cgoldberg avatar May 21 '25 19:05 cgoldberg

@cgoldberg It is possible to roll back until a good solution is found.

lozik4 avatar Jun 24 '25 09:06 lozik4

Closed with #15641. Thank you @cgoldberg

shbenzer avatar Jun 26 '25 00:06 shbenzer

@shbenzer Problem not solved. Remote driver can not get_log method. Please reopen this issue. This method now works only on Chromium, but when we use Remote run, it doesn't work.

lozik4 avatar Jun 30 '25 11:06 lozik4

@shbenzer @cgoldberg can they use BiDi to get the browser logs?

diemol avatar Jun 30 '25 12:06 diemol

@shbenzer @cgoldberg can they use BiDi to get the browser logs?

the BiDi Script class covers Console and Javascript logs - they should be able to use it (its tests are still passing in CI)

shbenzer avatar Jun 30 '25 15:06 shbenzer

Getting logs with BiDi in python:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait


options = Options()
options.enable_bidi = True

# driver = webdriver.Chrome(options=options)
driver = webdriver.Remote("http://localhost:4444/wd/hub", options=options)

log_entries = []
driver.script.add_console_message_handler(log_entries.append)
driver.script.add_javascript_error_handler(log_entries.append)

driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
# Trigger logs by clicking buttons
driver.find_element(By.ID, "jsException").click()
driver.find_element(By.ID, "consoleLog").click()

# Wait for logs to be collected
WebDriverWait(driver, 5).until(lambda _: len(log_entries) == 2)
for i, log in enumerate(log_entries, 1):
    print(f"{i}. [{log.level}] {log.text} (type: {log.type_})")

driver.quit()

navin772 avatar Jul 04 '25 15:07 navin772

You should be able to get around this with:

from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
ChromeDriver.get_log(driver, "browser")

martin-djukanovic avatar Jul 09 '25 14:07 martin-djukanovic

Was this solved @lozik4 ?

AlimTleuliyev avatar Sep 19 '25 06:09 AlimTleuliyev

Was this solved @lozik4 ?

No

lozik4 avatar Sep 22 '25 13:09 lozik4

@lozik4 @cgoldberg What is the workaround?

AlimTleuliyev avatar Sep 22 '25 17:09 AlimTleuliyev

@AlimTleuliyev see previous comments in this issue

cgoldberg avatar Sep 22 '25 17:09 cgoldberg

Getting logs with BiDi in python:

from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait

options = Options() options.enable_bidi = True

driver = webdriver.Chrome(options=options)

driver = webdriver.Remote("http://localhost:4444/wd/hub", options=options)

log_entries = [] driver.script.add_console_message_handler(log_entries.append) driver.script.add_javascript_error_handler(log_entries.append)

driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")

Trigger logs by clicking buttons

driver.find_element(By.ID, "jsException").click() driver.find_element(By.ID, "consoleLog").click()

Wait for logs to be collected

WebDriverWait(driver, 5).until(lambda : len(log_entries) == 2) for i, log in enumerate(log_entries, 1): print(f"{i}. [{log.level}] {log.text} (type: {log.type})")

driver.quit()

@cgoldberg this method does not give me the logs that I get when doing .get_log("performance")

I rolled back to 4.31.0 and it did not work.

AlimTleuliyev avatar Sep 22 '25 17:09 AlimTleuliyev

@AlimTleuliyev

this method does not give me the logs that I get when doing .get_log("performance")

I wouldn't expect it to.

I rolled back to 4.31.0 and it did not work

What didn't work? I don't even think this BiDi functionality existed in 4.31.

If you want the old way of getting logs, use the workaround in https://github.com/SeleniumHQ/selenium/issues/15772#issuecomment-3052961597

If you want to use BiDi, you should only expect the supported logs (console or javascript) to be captured. If you want to capture network traffic, you need to use the Network class.

cgoldberg avatar Sep 22 '25 18:09 cgoldberg

Here’s the workaround that worked for me

    # overridden ChromeDriver object
    @property
    def log_types(self):
        try:
            # local Chrome
            return super().log_types
        except AttributeError:
            # remote Chrome
            return self.execute(Command.GET_AVAILABLE_LOG_TYPES)['value']

    def get_log(self, log_type):
        try:
            # local Chrome
            log = super().get_log(log_type)
        except AttributeError:
            # remote Chrome
            log = self.execute(Command.GET_LOG, {"type": log_type})['value']

        self.dump_log(deepcopy(log), log_type)
        return log

ornichola avatar Oct 01 '25 19:10 ornichola