-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[🚀 Feature]: Expose browser specific functionalities for remote webdrivers in Python #11483
Comments
@j3soon, thank you for creating this issue. We will troubleshoot it as soon as we can. Info for maintainersTriage this issue by using labels.
If information is missing, add a helpful comment and then
If the issue is a question, add the
If the issue is valid but there is no time to troubleshoot it, consider adding the
If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C),
add the applicable
After troubleshooting the issue, please add the Thank you! |
Yes, please open a PR. We really appreciate your help with this! |
This issue is looking for contributors. Please comment below or reach out to us through our IRC/Slack/Matrix channels if you are interested. |
Without thinking too much, I will read the thread fully soon (Thanks for a very in depth post), would doing some sort of adapter/augmentor in python be a better approach for the future? A lot of the above is quite a hack w/r/t how python functions/methods work and the descriptor protocol that underpins them, I'd be a -1 with calling functions on the class and passing a seperate driver instance in to work around it, feels like the API is lackluster and we have some shortcomings we should address with a proper API just thinking of the future/maintenance of doing it like the above, will have a skim over the PR shortly. Thanks! |
@symonk, I agree with you that implementing a unified API ( We can either:
I also dislike using the The main motivation of this issue is due to the lack of documentation on local vs. remote webdrivers on these functionalities, which causes a lot of trouble for remote webdriver users. Fortunately, the documentation will be updated after PR SeleniumHQ/seleniumhq.github.io#1267 is merged. So it's totally fine to close PR #11500 and Meanwhile, if anyone want to use these functionalities on remote webdrivers, they can find this issue from the docs and copy the lengthy workaround for now. |
There's not going to be a unified API, each language has its own ways of dealing with this, and the beta annotation of Java can likely be removed at this point. Python might be better off following Ruby approach of using mixins to add methods to the class based on browser name. I didn't see any tests in the PR to understand what the user API would look like with that code. It's ok to put some of the burden on the user, so long as everything actually works. |
This issue is stale because it has been open 280 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
Because of the (hacky) RemoteConnection code we have that pulls in subclass definitions, we currently can do: driver = webdriver.Remote(command_executor=server, options=options)
with open(addon_path, "rb") as file:
addon = base64.b64encode(file.read()).decode("UTF-8")
payload = {"addon": addon, "temporary": False}
driver.execute("INSTALL_ADDON", payload) So what about creating an @isaulv / @AutomatedTester / @symonk does this sound like a reasonable solution for this issue? e.g.: webdriver.firefox.FirefoxFeatures(driver).install_addon(path_to_addon) |
The other piece is the aforementioned hacky implementation of RemoteConnection that knows about its subclasses. I don't think this should be automatic and that the user should be passing in the subclassed remote connection if they want to get the subclassed features... Maybe that needs to be part of the client config class I'm working on, but I think that's a separate issue. |
This issue is stale because it has been open 280 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
This issue was closed because it has been stalled for 14 days with no activity. |
Feature and motivation
As mentioned in saucelabs/sauce-docs#1621, workarounds are required to use browser specific functionalities in remote webdrivers. The current workaround for Python is much shorter than those in C#, but much longer than using
Augmenter
in Java.I have noticed that the workarounds can be greatly simplified with some minor modifications in the Selenium codebase. Since Python is dynamically typed, implementing this feature in Python is much easier than in Java/C#. If the potential modifications are appropriate, I will open a PR.
The following are workarounds for four browser specific functionalities:
Network Conditions
The entries for network conditions are set during the initialization of
ChromiumRemoteConnection
, which aren't set for remote webdrivers. Therefore, we need to set the three entries manually.set_network_conditions
uses_commands["setNetworkConditions"]
,get_network_conditions
uses_commands["getNetworkConditions"]
, anddelete_network_conditions
uses_commands["deleteNetworkConditions"]
.Potential modifications: If we modify the selenium codebase to set the entries in the beginning of
webdriver.Chrome.*_network_conditions
instead of during the initialization ofChromiumRemoteConnection
, the entries don't need to be set manually.Full-Page Screenshots
The simple workaround works for:
get_full_page_screenshot_as_base64
, since it simply callsself.execute("FULL_PAGE_SCREENSHOT")
.But we cannot call:
get_full_page_screenshot_as_file
,save_full_page_screenshot
, andget_full_page_screenshot_as_png
directly, due to their use of
self.get_full_page_screenshot*
.However, we can simply copy & re-write the functions above by modifying the calls to
self.get_full_page_screenshot*
.Potential modifications: Change all calls to
self.get_full_page_screenshot*(...)
intowebdriver.Firefox.get_full_page_screenshot*(driver, ...)
.Install and Uninstall Add-ons
The simple workaround works since:
install_addon
base64 encodes the zipped add-on and callsself.execute("INSTALL_ADDON", ...)
, whileuninstall_addon
simply callsself.execute("UNINSTALL_ADDON", ...)
.Potential modifications: (No modification required)
Change Preferences During Session
The simple workaround works for:
set_context
since it simply callsself.execute("SET_CONTEXT", ...)
,but requires some copy & re-write for:
context
, due to the use ofself.set_context
.Potential modifications: Change all calls to
self.set_context(...)
intowebdriver.Firefox.set_context(driver, ...)
.Usage example
After the potential modifications are applied, we can easily use all four browser specific functionalities in Python with just a few lines of code:
The text was updated successfully, but these errors were encountered: