By imbaiye


2017-12-18 03:34:41 8 Comments

For some unknown reasons ,my browser open test pages of my remote server very slowly. So I am thinking if I can reconnect to the browser after quitting the script but don't execute webdriver.quit() this will leave the browser opened. It is probably kind of HOOK or webdriver handle. I have looked up the selenium API doc but didn't find any function. I'm using Chrome 62,x64,windows 7,selenium 3.8.0. I'll be very appreciated whether the question can be solved or not.

3 comments

@Todor Minakov 2018-08-24 11:12:08

Yes, that's actually quite easy to do.

A selenium <-> webdriver session is represented by a connection url and session_id, you just reconnect to an existing one.

Disclaimer - the approach is using selenium internal properties ("private", in a way), which may change in new releases; you'd better not use it for production code; it's better not to be used against remote SE (yours hub, or provider like BrowserStack/Sauce Labs), because of a caveat/resource drainage explained at the end.

When a webdriver instance is initiated, you need to get the before-mentioned properties; sample:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.google.com/')

# now Google is opened, the browser is fully functional; print the two properties
# command_executor._url (it's "private", not for a direct usage), and session_id

print(f'driver.command_executor._url: {driver.command_executor._url}')
print(f'driver.session_id: {driver.session_id}')

With those two properties now known, another instance can connect; the "trick" is to initiate a Remote driver, and provide the _url above - thus it will connect to that running selenium process:

driver2 = webdriver.Remote(command_executor=the_known_url)  
# when the started selenium is a local one, the url is in the form 'http://127.0.0.1:62526'

When that is ran, you'll see a new browser window being opened.
That's because upon initiating the driver, the selenium library automatically starts a new session for it - and now you have 1 webdriver process with 2 sessions (browsers instances).

If you navigate to an url, you'll see it is executed on that new browser instance, not the one that's left from the previous start - which is not the desired behavior.
At this point, two things need to be done - a) close the current SE session ("the new one"), and b) switch this instance to the previous session:

if driver2.session_id != the_known_session_id:   # this is pretty much guaranteed to be the case
    driver2.close()   # this closes the session's window - it is currently the only one, thus the session itself will be auto-killed, yet:
    driver2.quit()    # for remote connections (like ours), this deletes the session, but does not stop the SE server

# take the session that's already running
driver2.session_id = the_known_session_id

# do something with the now hijacked session:
driver.get('https://www.bing.com/')

And, that is it - you're now connected to the previous/already existing session, with all its properties (cookies, LocalStorage, etc).

By the way, you do not have to provide desired_capabilities when initiating the new remote driver - those are stored and inherited from the existing session you took over.


Caveat - having a SE process running can lead to some resource drainage in the system.

Whenever one is started and then not closed - like in the first piece of the code - it will stay there until you manually kill it. By this I mean - in Windows for example - you'll see a "chromedriver.exe" process, that you have to terminate manually once you are done with it. It cannot be closed by a driver that has connected to it as to a remote selenium process.
The reason - whenever you initiate a local browser instance, and then call its quit() method, it has 2 parts in it - the first one is to delete the session from the Selenium instance (what's done in the second code piece up there), and the other is to stop the local service (the chrome/geckodriver) - which generally works ok.

The thing is, for Remote sessions the second piece is missing - your local machine cannot control a remote process, that's the work of that remote's hub. So that 2nd part is literally a pass python statement - a no-op.

If you start too many selenium services on a remote hub, and don't have a control over it - that'll lead to resource drainage from that server. Cloud providers like BrowserStack take measures against this - they are closing services with no activity for the last 60s, etc, yet - this is something you don't want to do.

And as for local SE services - just don't forget to occasionally clean up the OS from orphaned selenium drivers you forgot about :)

@DebanjanB 2017-12-18 06:00:01

No, you can't reconnect to the previous Web Browser session after quiting the script. Even if you are able to extract the Session ID, Cookies and other session attributes from the previous Browsing Session still you won't be able to pass those attributes as a HOOK to the WebDriver.

A cleaner way would be to call webdriver.quit() and then span a new Browsing Session.

History :

Previously there had been some discussions and attempts to reconnect WebDriver to an existing running browsing session. You can find the discussions in these QA :

@imbaiye 2017-12-18 06:18:46

You totally understand and solved my confusion. I'll do cleanup . Thank you very much.

@Eugene S 2017-12-18 04:56:59

Without getting into why do you think that leaving an open browser windows will solve the problem of being slow, you don't really need a handle to do that. Just keep running the tests without closing the session or, in other words, without calling driver.quit() as you have mentioned yourself. The question here though framework that comes with its own runner? Like Cucumber?

In any case, you must have some "setup" and "cleanup" code. So what you need to do is to ensure during the "cleanup" phase that the browser is back to its initial state. That means:

  • Blank page is displayed
  • Cookies are erased for the session

@Eugene S 2017-12-18 05:37:41

So in such case, the setup code will open the browser and navigate to this page for you, then you run all your tests and the cleanup part will close the window and the browser. This does not look like a good practice as you are adding possible issues from not having a clean session each time but can work as a workaround. Also not sure how the page will behave if you clear the cookies after teach test.

@imbaiye 2017-12-18 05:39:08

The function <code>webdriver.Chrome.get(url)</code> will wait until the page loads completely.This will take a lot of time to load the remote page. So I want to open and load the page once. I think the webdriver is still running background after I quit my script . So I want to find the handle for the webdriver and reconnect to the webdriver to reuse the opened page

@Eugene S 2017-12-18 05:41:09

You edited your comment after I posted a reply but have a look at it see if this helps.

@imbaiye 2017-12-18 05:48:35

I'm sorry about that .Stackoverflow sets a 5 mintues edit time.And almost every time I make it time out.

@imbaiye 2017-12-18 05:49:35

My poor English.It is my bad.

@Eugene S 2017-12-18 05:51:43

Is what I said helpful?

@imbaiye 2017-12-18 06:12:48

yeah , I know what I am thinking is wrong and the cleanup should be done everytime .Thank you very much.

Related Questions

Sponsored Content

3 Answered Questions

42 Answered Questions

[SOLVED] How to take screenshot with Selenium WebDriver

13 Answered Questions

11 Answered Questions

43 Answered Questions

[SOLVED] How can I represent an 'Enum' in Python?

1 Answered Questions

2 Answered Questions

1 Answered Questions

[SOLVED] Selenium Webdriver Error - SessionNotCreatedError

1 Answered Questions

Sponsored Content