-
-
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]: Support custom headers for remote WebDriver connection (python) #10892
Comments
@scook12, 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! |
I think as a workaround you an pass your own RemoteConnection object as a command executor at the moment tho thats a bit heavy handed for the use case maybe, will take a look when i'm home |
Just to clarify, @scook12 are you wanting to set a custom header to allow your test code to access a Selenium Grid on a secured remote server? For instance, WebdriverIO lets me do something like this in my configuration file:
Is something like this what you're looking for, or are you looking to control the headers that the browser sends to the app under test? |
@jamesmortensen yes, I need to control headers sent to the grid! My grid is deployed behind Traefik and using the For more context, the intent was to use subdomains to organize my hubs. We test on web and mobile (via appium) deployed on docker swarm. I wanted To do that, I just need to include the Host header in requests sent via Hopefully that helps clarify! |
UPDATE: Unpublished and renamed to "selenium-proxy" as it's incorrect to say it's a "reverse proxy". Sorry for any inconvenience. @scook12 I have had some success with this Selenium Proxy Server which I just published. I wanted to be able to set the authorization header, but not every test automation library makes that easy to do. With the proxy server, we can modify the headers for any framework we want to use just by pointing the testing library to the proxy server. So what you can do is configure your testing library to go through this proxy, and then configure the proxy to communicate securely to your Selenium grid. The proxy handles rewriting the headers with the token so the testing library doesn't need to. It's written in Node.js, but that shouldn't be a problem since Selenium WebDriver is a standard. If you try it out, let me know if you run into any trouble. |
@symonk we could add an In the meantime the user *could subclass the browser specific subclass, but that is clumsy indeed. |
Actually, I found a quite sneaky way without using a Proxy or Extension:You can change the Headers in # resource: https://stackoverflow.com/questions/66227508/selenium-4-0-0-beta-1-how-add-event-listeners-in-cdp
class cdp_listener:
from typing import Dict
def __init__(self):
self.listeners = {}
async def async_helper(self):
async with driver.bidi_connection() as connection:
session, devtools = connection.session, connection.devtools
for listener in self.listeners.items():
my_listener = await listener[1]["listener"](connection=connection)
async for event in my_listener:
try:
await session.execute(listener[1]["at_event"](event=event, connection=connection))
except Exception as e:
print(e)
def trio_helper(self):
import trio
trio.run(self.async_helper)
def start_threaded(self, listeners: Dict[str,Dict[callable, callable]] = {}):
if listeners:
self.listeners = listeners
import threading
thread = threading.Thread(target=self.trio_helper)
thread.start()
return thread
def add_listeners(self, listeners: Dict[str,Dict[callable, callable]]):
self.listeners = listeners
def remove_listener(self, listener:str):
del self.listeners[listener]
async def all_requests(connection):
session, devtools = connection.session, connection.devtools
pattern = map(devtools.fetch.RequestPattern.from_json,[{"urlPattern":"*"}])
pattern = list(pattern)
await session.execute(devtools.fetch.enable(patterns=pattern))
return session.listen(devtools.fetch.RequestPaused)
def continue_request(event, connection):
print({"type":event.resource_type.to_json(),"frame_id": event.frame_id, "url": event.request.url})
session, devtools = connection.session, connection.devtools
headers = event.request.headers.to_json()
my_headers = {"sec-ch-ua-platform": "Android"}
headers.update(my_headers)
my_headers = []
for item in headers.items():
my_headers.append(devtools.fetch.HeaderEntry.from_json({"name": item[0], "value": item[1]}))
return devtools.fetch.continue_request(request_id=event.request_id, headers=my_headers)
cdp_listener = cdp_listener()
thread = cdp_listener.start_threaded(listeners= {"continue":{"listener":all_requests,"at_event":continue_request}})
driver.get('https://modheader.com/headers?product=ModHeader') |
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. |
pretty sure this would have to be added to the webdriver spec or (if it isn't already) to Webdriver BiDi |
There's 2 pieces.
BiDi/network interception manages the second one. This issue relates to the first one. |
Hmm, this might be a part of this larger issue — #12368 |
I have a similar requirement. I want to use an apigateway to protect the selenium grid via an APIKEY that should be present in http headers. Is this possible in Selenium Java to pass custom http header while using RemoteWebdriver class. I looked at #12368 but could not see a discussion about custom headers. |
I think what is being requested here is resolved by this PR - #14587 Although, it was for Better compatibility with appium python, it introduced a new class variable |
Changes landed with PR #14587 Closing as resolved! |
In part of #13286 - via ClientConfig, the header
See more: https://www.selenium.dev/documentation/webdriver/drivers/http_client/ |
This issue has been automatically locked since there has not been any recent activity since it was closed. Please open a new issue for related bugs. |
Feature and motivation
In
RemoteConnection
, theget_remote_connection_headers
method has a set of logical defaults it builds, but there's no way for a user to make an addition to these headers.Adding a hook or property that the consuming code can set to add to these headers would be a big help.
Usage example
I need to add a host header for requests to be successful to my selenium grid running behind traefik reverse proxy. Without this feature, I can't use selenium python out of the box to create sessions (initializing
WebDriver
throws 404 errors because traefik doesn't know where to route without the host header).Passing a parameter from
WebDriver
toRemoteConnection
ought to do the trick:The text was updated successfully, but these errors were encountered: