Can Selenium interact with an existing browser session?
Solution 1
This is a pretty old feature request: Allow webdriver to attach to a running browser . So it's officially not supported.
However, there is some working code which claims to support this: https://web.archive.org/web/20171214043703/http://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/.
Solution 2
This is a duplicate answer **Reconnect to a driver in python selenium ** This is applicable on all drivers and for java api.
- open a driver
driver = webdriver.Firefox() #python
- extract to session_id and _url from driver object.
url = driver.command_executor._url #"http://127.0.0.1:60622/hub"
session_id = driver.session_id #'4e167f26-dc1d-4f51-a207-f761eaf73c31'
- Use these two parameter to connect to your driver.
driver = webdriver.Remote(command_executor=url,desired_capabilities={})
driver.close() # this prevents the dummy browser
driver.session_id = session_id
And you are connected to your driver again.
driver.get("http://www.mrsmart.in")
Solution 3
This snippet successfully allows to reuse existing browser instance yet avoiding raising the duplicate browser. Found at Tarun Lalwani's blog.
from selenium import webdriver
from selenium.webdriver.remote.webdriver import WebDriver
# executor_url = driver.command_executor._url
# session_id = driver.session_id
def attach_to_session(executor_url, session_id):
original_execute = WebDriver.execute
def new_command_execute(self, command, params=None):
if command == "newSession":
# Mock the response
return {'success': 0, 'value': None, 'sessionId': session_id}
else:
return original_execute(self, command, params)
# Patch the function before creating the driver object
WebDriver.execute = new_command_execute
driver = webdriver.Remote(command_executor=executor_url, desired_capabilities={})
driver.session_id = session_id
# Replace the patched function with original function
WebDriver.execute = original_execute
return driver
bro = attach_to_session('http://127.0.0.1:64092', '8de24f3bfbec01ba0d82a7946df1d1c3')
bro.get('http://ya.ru/')
Solution 4
It is possible. But you have to hack it a little, there is a code What you have to do is to run stand alone server and "patch" RemoteWebDriver
public class CustomRemoteWebDriver : RemoteWebDriver
{
public static bool newSession;
public static string capPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", "tmp", "sessionCap");
public static string sessiodIdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestFiles", "tmp", "sessionid");
public CustomRemoteWebDriver(Uri remoteAddress)
: base(remoteAddress, new DesiredCapabilities())
{
}
protected override Response Execute(DriverCommand driverCommandToExecute, Dictionary<string, object> parameters)
{
if (driverCommandToExecute == DriverCommand.NewSession)
{
if (!newSession)
{
var capText = File.ReadAllText(capPath);
var sidText = File.ReadAllText(sessiodIdPath);
var cap = JsonConvert.DeserializeObject<Dictionary<string, object>>(capText);
return new Response
{
SessionId = sidText,
Value = cap
};
}
else
{
var response = base.Execute(driverCommandToExecute, parameters);
var dictionary = (Dictionary<string, object>) response.Value;
File.WriteAllText(capPath, JsonConvert.SerializeObject(dictionary));
File.WriteAllText(sessiodIdPath, response.SessionId);
return response;
}
}
else
{
var response = base.Execute(driverCommandToExecute, parameters);
return response;
}
}
}
Solution 5
Inspired by Eric's answer, here is my solution to this problem for selenium 3.7.0. Compared with the solution at http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/, the advantage is that there won't be a blank browser window each time I connect to the existing session.
import warnings
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.remote.errorhandler import ErrorHandler
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.remote.mobile import Mobile
from selenium.webdriver.remote.remote_connection import RemoteConnection
from selenium.webdriver.remote.switch_to import SwitchTo
from selenium.webdriver.remote.webdriver import WebDriver
# This webdriver can directly attach to an existing session.
class AttachableWebDriver(WebDriver):
def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=None, browser_profile=None, proxy=None,
keep_alive=False, file_detector=None, session_id=None):
"""
Create a new driver that will issue commands using the wire protocol.
:Args:
- command_executor - Either a string representing URL of the remote server or a custom
remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.
- desired_capabilities - A dictionary of capabilities to request when
starting the browser session. Required parameter.
- browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object.
Only used if Firefox is requested. Optional.
- proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will
be started with given proxy settings, if possible. Optional.
- keep_alive - Whether to configure remote_connection.RemoteConnection to use
HTTP keep-alive. Defaults to False.
- file_detector - Pass custom file detector object during instantiation. If None,
then default LocalFileDetector() will be used.
"""
if desired_capabilities is None:
raise WebDriverException("Desired Capabilities can't be None")
if not isinstance(desired_capabilities, dict):
raise WebDriverException("Desired Capabilities must be a dictionary")
if proxy is not None:
warnings.warn("Please use FirefoxOptions to set proxy",
DeprecationWarning)
proxy.add_to_capabilities(desired_capabilities)
self.command_executor = command_executor
if type(self.command_executor) is bytes or isinstance(self.command_executor, str):
self.command_executor = RemoteConnection(command_executor, keep_alive=keep_alive)
self.command_executor._commands['GET_SESSION'] = ('GET', '/session/$sessionId') # added
self._is_remote = True
self.session_id = session_id # added
self.capabilities = {}
self.error_handler = ErrorHandler()
self.start_client()
if browser_profile is not None:
warnings.warn("Please use FirefoxOptions to set browser profile",
DeprecationWarning)
if session_id:
self.connect_to_session(desired_capabilities) # added
else:
self.start_session(desired_capabilities, browser_profile)
self._switch_to = SwitchTo(self)
self._mobile = Mobile(self)
self.file_detector = file_detector or LocalFileDetector()
self.w3c = True # added hardcoded
def connect_to_session(self, desired_capabilities):
response = self.execute('GET_SESSION', {
'desiredCapabilities': desired_capabilities,
'sessionId': self.session_id,
})
# self.session_id = response['sessionId']
self.capabilities = response['value']
To use it:
if use_existing_session:
browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip),
desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER),
session_id=session_id)
self.logger.info("Using existing browser with session id {}".format(session_id))
else:
browser = AttachableWebDriver(command_executor=('http://%s:4444/wd/hub' % ip),
desired_capabilities=(DesiredCapabilities.INTERNETEXPLORER))
self.logger.info('New session_id : {}'.format(browser.session_id))
Angel Romero
Passionate Android Engineer and Tech Lead who enjoys creating high-quality Android products. A strong advocate of Software quality and best development practices as the optimal way of delivering a unique experience to the customers, while being efficient and predictable in project management terms.
Updated on December 19, 2021Comments
-
Angel Romero over 2 years
Does anybody know if Selenium (WebDriver preferably) is able to communicate with and act through a browser that is already running before launching a Selenium Client?
I mean if Selenium is able to comunicate with a browser without using the Selenium Server (with could be an Internet Explorer launched manually for example).
-
Angel Romero over 12 yearsThank you very much because in that link I have found a class which allow to do that, but unfortunately I cant use that solution with IE (only with Firefox). I'm going to launch a regular IEDriver and comunicate with it from other proccesses using a middleware. If you have an idea why the class isn't working on IE I would appreciate it. Thank you.
-
joinsaad over 8 yearsBased on this excellent solution, I have written a complete blog post in which I have discussed how to connect to an already opened browser instance of chrome. Full source code is also attached on that blog post. binaryclips.com/2015/08/25/…
-
Dzenly almost 8 yearsIt does not use EXISTING browser session. It creates a new chromedriver session and opens a new browser window. And getAllWindowHandles() will not show your old browser window's handle.
-
jalanb over 7 yearsWhat functionality does this add (that the others are missing)?
-
Yanir over 7 yearsInternally, just the startSession(...) method will initialize the capabilities object. The capabilities object is required for many methods such as takeScreenshot, executeScript and more. But by going through startSession you will have to create a new session creation. This overload skips the creation of a new session but still leads to capabilities object initialization.
-
Dzenly almost 7 yearsUpdate: There is seleniumhq.github.io/selenium/docs/api/javascript/module/… Which allows to connect to existing opened browser window.
-
Pavel Vlasov over 6 yearsIt works for me except a duplicate dummy browser is raising each time.
-
googamanga about 6 yearsThis isn't in the 4.0.0 version!
-
Steve Gon almost 6 yearsI am getting the dummy window also, it's not that big of a deal, but during debugging it is annoying. Any ideas on how to get rid of?
-
MasterJoe almost 6 yearsRobert, its 2018 now. Could you please update your answer ?
-
MasterJoe almost 6 yearsIn case anyone needs it, I have tried and tested some Java code to make selenium use an existing browser session - stackoverflow.com/a/51145789/6648326.
-
slesh over 5 years"I don't know if there is a way to get session info for a session which was not created by selenium." it's actually a problem I have been trying for a couple of days already... no success yet
-
Sam about 5 years+1. Works for my purpose of avoiding 2-factor auth logins however duplicate dummy browsers are present. I can live with that.
-
Norill Tempest almost 5 yearsdude, don't compare strings with ==
-
MasterJoe over 4 years@slesh - I suggest you create a new question for that and maybe offer 100 of your points if it does not get enough attention.
-
Sun Shine over 4 yearsIs there a way to find the existing session id and executor URL through automation? In my case, another application opened a browser session and I want to use that. Can you please recommend, how to find the browser session id of that?
-
S.K. Venkat over 4 yearsProbably you can dump the executor_command url & session id into a file when the script starts and read it from the file when do you want to hook the browser session again.
-
Tayyab Nasir about 4 years@S.K.Venkat how can I get session id of chrome window, I opened it using pywinauto and now want to run selenuim on it, is there a python way to get session id of chrome tab
-
S.K. Venkat about 4 years@TayyabNasir, kindly look out the above answer. The fifth line which was commented out
# session_id = driver.session_id
is the way you can retrieve the session id of a chrome window using python selenium api. I guess that each tab in a chrome session doesn't have unique ID. -
Tayyab Nasir about 4 years@S.K. I want session Id of the chrome window that I opened manually, I didn’t open that window using selenium
-
Amr Awad about 4 yearsIf you need to close the dummy browser window, simply call
driver.close()
before updating the session id. -
lazarea almost 4 yearsI tried this using a Chrome webdriver in Python but I didn't manage to connect and to sign in to Gmail unfortunately.
-
Cerin almost 4 years
selenium.common.exceptions.SessionNotCreatedException: Message: Session is already started
-
Tihamer over 3 yearsThanks for the reference to Tarun Lalwani's work. Between his page and your answer, I was able to figure it out. The imports would have been nice, as well as comments explaining the purpose of some of the statements. But all and all, very helpful.
-
Spencer Connaughton about 3 years
driver.service.service_url
also works for the URL, and doesn't require access to a protected filed. -
Mugen about 3 years@AngelRomero How about choosing a new answer. A lot of functionality has been developed since this question was asked.
-
Vishwanath Heddoori over 2 yearsI tried this solution, but it does not work and I get an error stating selenium.common.exceptions.SessionNotCreatedException: Message: Session is already started.
-
Ashark about 2 yearsUnderrated! Simple and easy solution. I firstly had a problem that selenium opened another browser window. I used a driver manager in place of chrome_driver and I forgot to use the chrome_options second parameter.
-
Frank Buss almost 2 yearsJust in case someone found this article first, it doesn't work. But this worked for me: stackoverflow.com/questions/51214668/…
-
Moran Reznik almost 2 yearsI don't get this answer- if I have multiple chrome browsers opened, how does selenium will know to which one to connect?