Skip to content

[py] Remove logging API for non-Chromium browsers #15641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 19, 2025

Conversation

cgoldberg
Copy link
Contributor

@cgoldberg cgoldberg commented Apr 18, 2025

User description

🔗 Related Issues

Fixes #15588
Fixes #15589
Fixes #15587
Fixes #15586

💥 What does this PR do?

This PR changes the logging API in the Python bindings so it only works on Chromium based browsers (Chrome/Edge), as discussed in: #15588

It removes the related methods from the selenium.webdriver.remote.webdriver.WebDriver class and adds them to selenium.webdriver.chromium/webdriver.WebDriver.

Relevant tests have been updated so the are expected failures on all non-Chromium browsers.

This will bring the Python bindings in line with other language bindings where this has already been removed from most browsers.

🔄 Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)

PR Type

Bug fix, Enhancement

@selenium-ci selenium-ci added the C-py Python Bindings label Apr 18, 2025
Copy link
Contributor

qodo-merge-pro bot commented Apr 18, 2025

PR Code Suggestions ✨

No code suggestions found for the PR.

@titusfortner
Copy link
Member

titusfortner commented Apr 18, 2025

So I looked deeper at Ruby Selenium code, and we have a MixIn that allows users to call this method from Chromium. So maybe we just want to move this to Chromium driver class and not delete it entirely (sorry for my earlier mixup).

@cgoldberg
Copy link
Contributor Author

OK, I'll update this PR in a little while (and also fix the linting error)

@cgoldberg cgoldberg force-pushed the py-remove-logging-api branch from 09b8e12 to ef248a5 Compare April 18, 2025 21:06
@SeleniumHQ SeleniumHQ deleted a comment from qodo-merge-pro bot Apr 18, 2025
@cgoldberg
Copy link
Contributor Author

It should be all set now... I updated the PR description also.

I moved the logging methods to the Chromium WebDriver class, so it works in Chrome/Edge. I also adjusted the tests to be expected failures on all browsers except Chrome/Edge.

... just waiting for CI to run.

@cgoldberg cgoldberg changed the title [py] Remove logging API [py] Remove logging API for non-Chromium browsers Apr 19, 2025
@cgoldberg cgoldberg merged commit 3e26d11 into SeleniumHQ:trunk Apr 19, 2025
17 checks passed
@cgoldberg cgoldberg deleted the py-remove-logging-api branch April 19, 2025 02:10
BeryJu added a commit to goauthentik/authentik that referenced this pull request May 5, 2025
GraemeWatt added a commit to HEPData/hepdata that referenced this pull request May 6, 2025
BeryJu added a commit to goauthentik/authentik that referenced this pull request May 6, 2025
* core: bump selenium from 4.31.0 to v4.32.0

* deal with selenium breaking stuff on minor versions

SeleniumHQ/selenium#15641
Signed-off-by: Jens Langhammer <[email protected]>

* format

Signed-off-by: Jens Langhammer <[email protected]>

---------

Signed-off-by: Jens Langhammer <[email protected]>
Co-authored-by: Jens Langhammer <[email protected]>
@cia2154
Copy link

cia2154 commented May 10, 2025

Am I correct in understanding that this PR broke programs that call get_log from webdriver.Remote?
As GraemeWatt mentions, is the only solution to just call driver.execute(Command.GET_LOG, {"type": ""})["value"]?

The following code works fine in 4.31.0, but doesn't work in 4.32.0.

from selenium import webdriver
from selenium.webdriver.remote.command import Command

options = webdriver.ChromeOptions()
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})

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

try:
    driver.get('http://example.com/')
    # AttributeError: 'WebDriver' object has no attribute 'get_log' in 4.32.0
    print(driver.get_log('performance'))

    # This code works with both versions
    #print(driver.execute(Command.GET_LOG, {"type": "performance"})["value"])

except Exception as e:
    raise e
finally:
    driver.quit()

@cgoldberg
Copy link
Contributor Author

@cia2154 yes, that is correct. I will look into restoring it for remote chromedriver/edgedriver.

@titusfortner
Copy link
Member

@cgoldberg add those methods to here:

def _remote_commands(self, vendor_prefix):

@cgoldberg
Copy link
Contributor Author

@titusfortner I tried to implement this, but I can't find a good way to add get_log and get_log_types methods to the base WebDriver class (for remote) so only Chrome/Edge browsers can access them.

I don't see how adding those methods to _remote_commands helps with that.

I think we would need a pretty big restructuring of the class hierarchy to allow Chromium specific methods on a webdriver.Remote instance.

Maybe I'm missing something?

@cgoldberg
Copy link
Contributor Author

Thinking about this some more... The only solution I can think of is to move the get_log and get_log_types methods back to the parent WebDriver class, and also add them to subclasses for non-Chromium browsers... and when they are called from a subclass, just raise NotImplementedError.

The methods on the base WebDriver class would need to check which browser it's using when those methods are called and raise NotImplementedError if the driver isn't Chrome or Edge.

It's kind of ugly, but this would allow the logging API to be used for Chrome, Edge, and Remote drivers, and give a reasonable error when called from a local or remote driver that is not Chrome or Edge.

@titusfortner
Copy link
Member

You don't need to throw a not implemented error. There are a bunch of chromium specific features like casting that work with Remote driver.

This isn't a great way to do it to reference subclasses this way, but it avoids mixins which Python people don't like:
https://github.com/SeleniumHQ/selenium/blob/trunk/py/selenium/webdriver/remote/webdriver.py#L122

Literally just add those methods to the list above, and webdriver will add the commands to remote sessions that have that browser name

@cgoldberg
Copy link
Contributor Author

There are a bunch of chromium specific features like casting that work with Remote driver.

None of the casting methods (like get_sink, start_tab_mirroring, stop_casting) work on Remote webdrivers (because of the same issue I am running into).

Literally just add those methods to the list above, and webdriver will add the commands to remote sessions that have that browser name

It doesn't. _remote_commands is just a mapping of command names to endpoints. For eaxmple, it contains this:

"launchApp": ("POST", "/session/$sessionId/chromium/launch_app")

There is a method on chromium.WebDriver called launch_app that references this command. However, you can't call launch_app on a Remote instance... it doesn't exist.

So to use any of the commands listed in _remote_commands, you have to implement a method that calls the command. Where do I add that method? Do you have an example of a method you can call on a Remote instance that only works for Chromium browsers? I can't find any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
4 participants