Can Selenium interact with an existing browser session?

Does anyone know if Selenium (preferably WebDriver) can interact and act through a browser that is already running before the Selenium Client starts?

I mean, if Selenium can communicate with the browser without using Selenium Server (for example, Internet Explorer starts manually).

+43
selenium selenium-webdriver webdriver communication
source share
11 answers

This is a fairly old request: allow the web driver to connect to a working browser . So officially this is not supported.

However, there is some working code that claims to support this: https://web.archive.org/web/20171214043703/http://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/ .

+20
source share

This is a duplicate of the answer ** Connect to the driver in python selenium ** This applies to all drivers and java api.

  • open driver

    driver = webdriver.Firefox() #python 
  • fetch in session_id and _url from the 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 options to connect to your driver.

     driver = webdriver.Remote(command_executor=url,desired_capabilities={}) driver.session_id = session_id 

    And you are again connected to your driver.

     driver.get("http://www.mrsmart.in") 
+24
source share

It is possible. But you need to hack it a bit, there is a code. What you need to do is launch a 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; } } } 
+9
source share

This snippet successfully allows you to reuse an existing browser instance while avoiding duplication of the browser. Found on Taruna 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/') 
+5
source share

All solutions still do not have a certain functionality. Here is my solution:

 public class AttachedWebDriver extends RemoteWebDriver { public AttachedWebDriver(URL url, String sessionId) { super(); setSessionId(sessionId); setCommandExecutor(new HttpCommandExecutor(url) { @Override public Response execute(Command command) throws IOException { if (command.getName() != "newSession") { return super.execute(command); } return super.execute(new Command(getSessionId(), "getCapabilities")); } }); startSession(new DesiredCapabilities()); } } 
+3
source share

Solution for Javascript:

I successfully connected to an existing browser session using this function

 webdriver.WebDriver.attachToSession(executor, session_id); 

The documentation can be found here .

+3
source share

I have a solution in python, I changed the webdriver class, bassed out on the PersistenBrowser class, which I found.

https://github.com/axelPalmerin/personal/commit/fabddb38a39f378aa113b0cb8d33391d5f91dca5

replace module webdriver / usr / local / lib / python2.7 / dist-packages / selenium / webdriver / remote / webdriver.py

Ej. use:

 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities runDriver = sys.argv[1] sessionId = sys.argv[2] def setBrowser(): if eval(runDriver): webdriver = w.Remote(command_executor='http://localhost:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME, ) else: webdriver = w.Remote(command_executor='http://localhost:4444/wd/hub', desired_capabilities=DesiredCapabilities.CHROME, session_id=sessionId) url = webdriver.command_executor._url session_id = webdriver.session_id print url print session_id return webdriver 
+1
source share

Inspired by Eric's answer, here is my solution to this problem for selenium 3.7.0. Compared to the solution at http://tarunlalwani.com/post/reusing-existing-browser-session-selenium/, the advantage is that every time you connect to an existing session there will be no empty browser window.

 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 this:

 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)) 
+1
source share

I use Rails + Cucumber + Selenium Webdriver + PhantomJS, and I use the monkey version of Selenium Webdriver that opens the PhantomJS browser between test runs. See this blog post: http://blog.sharetribe.com/2014/04/07/faster-cucumber-startup-keep-phantomjs-browser-open-between-tests/

See also my answer to this post: How to execute a command on an already opened browser from a ruby ​​file

0
source share

This is pretty easy using the JavaScript selenium-webdriver client:

First, make sure that you have a WebDriver server running. For example, download ChromeDriver , then run chromedriver --port=9515 .

Secondly, create a driver like this :

 var driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .usingServer('http://localhost:9515') // <- this .build(); 

Here is a complete example:

var webdriver = require ('selenium-webdriver');

 var driver = new webdriver.Builder() .withCapabilities(webdriver.Capabilities.chrome()) .usingServer('http://localhost:9515') .build(); driver.get('http://www.google.com'); driver.findElement(webdriver.By.name('q')).sendKeys('webdriver'); driver.findElement(webdriver.By.name('btnG')).click(); driver.getTitle().then(function(title) { console.log(title); }); driver.quit(); 
0
source share

It seems that this function is not officially supported by selenium. But Tarun Lalwani has created working Java code to provide this function. See http://tarunlalwani.com/post/reusing-existing-browser-session-selenium-java/.

Here is a working code example copied from the link above:

 public static RemoteWebDriver createDriverFromSession(final SessionId sessionId, URL command_executor){ CommandExecutor executor = new HttpCommandExecutor(command_executor) { @Override public Response execute(Command command) throws IOException { Response response = null; if (command.getName() == "newSession") { response = new Response(); response.setSessionId(sessionId.toString()); response.setStatus(0); response.setValue(Collections.<String, String>emptyMap()); try { Field commandCodec = null; commandCodec = this.getClass().getSuperclass().getDeclaredField("commandCodec"); commandCodec.setAccessible(true); commandCodec.set(this, new W3CHttpCommandCodec()); Field responseCodec = null; responseCodec = this.getClass().getSuperclass().getDeclaredField("responseCodec"); responseCodec.setAccessible(true); responseCodec.set(this, new W3CHttpResponseCodec()); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } else { response = super.execute(command); } return response; } }; return new RemoteWebDriver(executor, new DesiredCapabilities()); } public static void main(String [] args) { ChromeDriver driver = new ChromeDriver(); HttpCommandExecutor executor = (HttpCommandExecutor) driver.getCommandExecutor(); URL url = executor.getAddressOfRemoteServer(); SessionId session_id = driver.getSessionId(); RemoteWebDriver driver2 = createDriverFromSession(session_id, url); driver2.get("http://tarunlalwani.com"); } 

For your test, RemoteWebDriver must be created from an existing browser session. To create this driver, you only need to know "session information", that is, the address of the server (local in our case) on which the browser is running, and the browser session ID. To get this information, we can create one browser session with selenium, open the desired page and, finally, run a real test script.

I do not know if there is a way to get information about a session that was not created by selenium.

Here is an example session information:

Remote Server Address: http: // localhost: 24266 . The port number is different for each session. Session ID: 534c7b561aacdd6dc319f60fed27d9d6.

0
source share

All Articles