6

After upgrading to geckodriver I'm unable to reuse my Selenium's sessions. Here's my setup:

I have a start_browser.py script, which launches a Firefox instance and prints a port to connect to, like:

firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
browser = webdriver.Firefox(capabilities=firefox_capabilities)
print browser.service.port
wait_forever()

... and another script, which tries to connect to the existing instance via Remote driver:

caps = DesiredCapabilities.FIREFOX
caps['marionette'] = True
driver = webdriver.Remote(
        command_executor='http://localhost:{port}'.format(port=port),
        desired_capabilities=caps)

But it seems to be trying to launch a new session, and failing with a message:

selenium.common.exceptions.WebDriverException: Message: Session is already started

Is there an ability to just attach to the existing session, like in previous versions of Selenium? Or is this an intended behaviour of geckodriver (hope not)?

Alex Morozov
  • 5,823
  • 24
  • 28

2 Answers2

4

Alright, so unless anyone comes up with more elegant solution, here's a quick dirty hack:

class SessionRemote(webdriver.Remote):
    def start_session(self, desired_capabilities, browser_profile=None):
        # Skip the NEW_SESSION command issued by the original driver
        # and set only some required attributes
        self.w3c = True

driver = SessionRemote(command_executor=url, desired_capabilities=caps)
driver.session_id = session_id

The bad thing is that it still doesn't work, complaining that it doesn't know the moveto command, but at least it connects to a launched browser.

Update: Well, geckodriver seems to lack some functionality at the moment, so if you guys are going to keep using Firefox, just downgrade it to a version which supports old webdriver (45 plays fine), and keep an eye on tickets like https://github.com/SeleniumHQ/selenium/issues/2285 .

Alex Morozov
  • 5,823
  • 24
  • 28
0

You can reconnect to a session by using the session id.

firefox_capabilities = DesiredCapabilities.FIREFOX
firefox_capabilities['marionette'] = True
browser = webdriver.Firefox(capabilities=firefox_capabilities)
print browser.service.port
wait_forever()

# get the ID and URL from the browser
url = browser.command_executor._url
session_id = browser.session_id

# Connect to the existing instance
driver = webdriver.Remote(command_executor=url,desired_capabilities={})
driver.session_id = session_id
RemcoW
  • 4,196
  • 1
  • 22
  • 37
  • Still no luck. It crashes before I even can assign the session, in the `webdriver.Remote()` constructor. Current implementation seems to have new session creation hardcoded: https://github.com/SeleniumHQ/selenium/blob/master/py/selenium/webdriver/remote/webdriver.py#L177 . Any thoughts? – Alex Morozov Jun 22 '16 at 10:22
  • @AlexMorozov That shouldn't be the problem as it works for me. The only difference is that I'm not using `marionette`. Did you try it with the `capabilities` for the `webdriver.Remote` call as `{}` or did you add new `capabilities`? – RemcoW Jun 22 '16 at 10:28
  • Tried both `capabilities` options. Actually it have been working for me too until a recent version of Firefox deprecated the old driver and made a `marionette` the only way of interacting with the browser. So the question is how to reattach to a session considering new conditions. – Alex Morozov Jun 22 '16 at 12:20
  • How do you get the session id for a browser you launched manually? – Cerin Jun 17 '20 at 02:31
  • This doesn't actually works due to the inability to set the session_id, because you don't get webdriver instance, so nothing can be patched. @Cerin the session ID is not on the browser, it's on the geckodriver. I think you're looking for the gekocdriver --connec-existing parameter. It does suffer the very same problema about session ID already started. The way is to patch the start command like selected answer does. – m3nda Feb 20 '22 at 09:59