21

I am attempting to open a new tab OR a new window in a browser using selenium for python. It is of little importance if a new tab or new window is opened, it is only important that a second instance of the browser is opened.

I have tried several different methods already and none have succeeded.

  1. Switching to a window that does not exist with hopes that it would then open a new window upon failure to locate said window:

    driver.switch_to_window(None)

  2. Iterating through open windows (although there is currently only one)

    for handle in driver.window_handles:
        driver.switch_to_window(handle)
    
  3. Attempting to simulate a keyboard key press

    from selenium.webdriver.common.keys import Keys
    driver.send_keys(Keys.CONTROL + 'T')
    

The problem with this one in particular was that it does not seem possible to send keys directly to the browser, only to a specific element like this:

driver.find_element_by_id('elementID').send_keys(Keys.CONTROL + 'T')

However, when a command such as this is sent to an element, it appears to do absolutely nothing. I attempted to locate the topmost HTML element on the page and send the keys to that, but was again met with failure:

driver.find_element_by_id('wrapper').send_keys(Keys.CONTROL + 'T')

Another version of this I found online, and was not able to verify its validity or lack thereof because I'm not sure what class/module which needs importing

act = ActionChains(driver)
act.key_down(browserKeys.CONTROL)
act.click("").perform()
act.key_up(browserKeys.CONTROL)

Something very similar with different syntax (I'm not sure if one or both of these is correct syntax)

actions.key_down(Keys.CONTROL)
element.send_keys('t')
actions.key_up(Keys.CONTROL)
Zach Olivare
  • 3,805
  • 3
  • 32
  • 45
  • That only for wor head browsers, Firefox, Chrome, etc. In example PhantomJS has no key bindings and you need to call `execute_script()` with the proper javascript code. Case you need to pass items/cookies, just create a target=_blank link then click it before. – m3nda Apr 25 '17 at 00:12
  • Almost duplicate of [Open web in new tab Selenium + Python - Stack Overflow](https://stackoverflow.com/questions/28431765/open-web-in-new-tab-selenium-python) -- except that it opens in a new tab; however, most of the time tab/window is handled the same by selenium – user202729 Aug 18 '21 at 03:27

6 Answers6

28

How about you do something like this

driver = webdriver.Firefox() #First FF window
second_driver = webdriver.Firefox() #The new window you wanted to open

Depending on which window you want to interact with, you send commands accordingly

print driver.title #to interact with the first driver
print second_driver.title #to interact with the second driver

For all down voters:


The OP asked for "it is only important that a second instance of the browser is opened.". This answer does not encompass ALL possible requirements of each and everyone's use cases. The other answers below may suit your particular need.

Amey
  • 8,470
  • 9
  • 44
  • 63
  • 1
    Perfect! So simple yet it achieved exactly what I desired, thank you. However, is there a way to generalize that command so that the it would work regardless of the browser being used? Perhaps a way to derive the browser being used in the first driver to open the second? – Zach Olivare Jun 26 '13 at 20:51
  • @"Perhaps a way to derive the browser being used in the first driver to open the second?" -- I am not sure what value will this add. Even if it does. I am sorry I do not know how to do it. Anyways, if you found this answer helpful, you could mark this as the answer, this is how - http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235 – Amey Jun 26 '13 at 20:55
  • 10
    This actually opens a second instance of Firefox. The distinction between "new window in the existing browser" versus "entirely new browser application" may be important for some test cases. – ManicDee Dec 09 '13 at 05:35
  • It may use lots of memory when you opens numbers of instances of browsers. Each instance will take more than 100 MB. I recommend not to do that way. – fx-kirin Feb 27 '15 at 13:13
  • 2
    What if you need to open a new window while sharing the session and whatnot? This answer works if you really just need 2 windows and don't care at all about how the user would actually interact with the browser. Down-voting because, "How to open a new window __on a browser__ using Selenium WebDriver for python?" suggests that they want a new window from an existing browser or driver. That is what I was looking for in google, and your answer does not do this at all. Maybe you should include the other methods for doing this as well? – RattleyCooper Jul 21 '16 at 14:42
18

You can use execute_script to open new window.

driver = webdriver.Firefox()
driver.get("https://linkedin.com")
# open new tab
driver.execute_script("window.open('https://twitter.com')")
print driver.current_window_handle

# Switch to new window
driver.switch_to.window(driver.window_handles[-1])
print " Twitter window should go to facebook "
print "New window ", driver.title
driver.get("http://facebook.com")
print "New window ", driver.title

# Switch to old window
driver.switch_to.window(driver.window_handles[0])
print " Linkedin should go to gmail "
print "Old window ", driver.title
driver.get("http://gmail.com")
print "Old window ", driver.title

# Again new window
driver.switch_to.window(driver.window_handles[1])
print " Facebook window should go to Google "
print "New window ", driver.title
driver.get("http://google.com")
print "New window ", driver.title
supputuri
  • 13,644
  • 2
  • 21
  • 39
Dhiraj
  • 481
  • 6
  • 13
  • 4
    There's no mention in there to the Jquery loading, and you're assuming it's loaded by the previous url loaded with PhantomJS. Also, the javascript code is the same, so just `driver.execute_script("window.open('https://twitter.com')")` will work. – m3nda Apr 25 '17 at 00:15
  • Note: this might open in new tab or new window, depends on Firefox setting. Refer to [my answer](https://stackoverflow.com/a/68826888/5267751) for more details. – user202729 Aug 18 '21 at 05:13
9

I recommend to use CTRL + N command on Firefox to reduce less memory usage than to create new browser instances.

import selenium.webdriver as webdriver
from selenium.webdriver.common.keys import Keys

browser = webdriver.Firefox()
body = browser.find_element_by_tag_name('body')
body.send_keys(Keys.CONTROL + 'n')

The way to switch and control windows has already been mentioned by Dhiraj.

Community
  • 1
  • 1
fx-kirin
  • 1,906
  • 1
  • 20
  • 33
1
driver = webdriver.Chrome()
driver.execute_script("window.open('');")
driver.get('first url')

driver.switch_to.window(driver.window_handles[1])
driver.get('second url')
Vinay
  • 29
  • 2
0

In JavaScript, there's no distinction between window and tab.

driver.window_handles consider both the same.

However, if it's necessary to open a new window, there are a few methods: (see [3] for the required imports)

  1. Emulate ctrl+N. Doesn't work in new versions. See this comment.

    (
            ActionChains(driver)
            .key_down(Keys.CONTROL)
            .send_keys('n')
            .key_up(Keys.CONTROL)
            .perform()
            )
    

    or

    body = driver.find_element_by_tag_name('body')
    body.send_keys(Keys.CONTROL + 'n')
    
  2. Hold shift, and click at a link on the page -- only works if there's any link on the page.

    (
            ActionChains(driver)
            .key_down(Keys.SHIFT)
            .click(driver.find_element_by_tag_name("a"))
            .key_up(Keys.SHIFT)
            .perform()
            )
    

    If there isn't any, it's possible to create one... (modifies the current page!)

    driver.execute_script('''{
        let element=document.createElement("a");
        element.href="about:home";
        element.id="abc"
        element.text="1";
        document.body.appendChild(element);
        element.scrollIntoView();
        }''')
    
    (
            ActionChains(driver)
            .key_down(Keys.SHIFT)
            .click(driver.find_element_by_id("abc"))
            .key_up(Keys.SHIFT)
            .perform()
            )
    

    ... or navigate to a page with one. (if you do this at the start of the session, or open a new tab to do this and close it later, it isn't a problem)

    driver.get("data:text/html,<a href=about:blank>1</a>")
    (
            ActionChains(driver)
            .key_down(Keys.SHIFT)
            .click(driver.find_element_by_tag_name("a"))
            .key_up(Keys.SHIFT)
            .perform()
            )
    

    Looks like a hack.

  3. (for Firefox) Turn off the "Open links in tabs instead of new windows" option, then execute window.open().

    From Settings to open browser links in new tab, and external links in new window | Firefox Support Forum | Mozilla Support and Browser.link.open_newwindow - MozillaZine Knowledge Base:

    browser.link.open_newwindow - for links in Firefox tabs

    3 = divert new window to a new tab (default)
    2 = allow link to open a new window
    1 = force new window into same tab

    This option should be set to 2. [2]

    Note that, according to https://github.com/SeleniumHQ/selenium/issues/2106#issuecomment-320238039-permalink it's not possible to set the option with FirefoxProfile [1].

    options=webdriver.FirefoxOptions()
    options.set_preference("browser.link.open_newwindow", 2)
    driver=Firefox(firefox_options=options)
    
    driver.execute_script("window.open()")
    
  4. For Selenium 4.0.0 (pre-release. At the moment you can install it with for example pip install selenium==4.0.0b4) it's possible to do:

    driver.execute(
        selenium.webdriver.remote.command.Command.NEW_WINDOW,
        {"type": "window"}
    )
    

    Technique taken from this answer.


[1]: In the current version, for some reason, this works and set browser.link.open_newwindow to 2

fp = webdriver.FirefoxProfile()
fp.set_preference("browser.link.open_newwindow", 3)
fp.default_preferences["browser.link.open_newwindow"]=3
fp.DEFAULT_PREFERENCES["browser.link.open_newwindow"]=3
driver=Firefox(firefox_profile=fp)

while this keeps the option value at 3

driver=Firefox()

[2]: If the value is set to 3, window.open() will open in a new tab instead of a new window.

[3]: All required imports:

from selenium import webdriver
from selenium.webdriver import Firefox, FirefoxProfile
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

[4]: this answer only covers how to open a new window. For switching to that new window and back, use WebDriverWait and driver.switch_to.window(driver.window_handles[i]). Refer to https://stackoverflow.com/a/51893230/5267751 for more details.

user202729
  • 3,358
  • 3
  • 25
  • 36
  • As far as I remember this solution does work and is correct for me (except the first solution where it's noted that it doesn't work in new versions). Maybe someone can explain what is wrong? – user202729 Aug 09 '22 at 00:32
0
driver.switch_to.new_window()

will open a new window.

Then you can search the web

driver.get("https://google.com")
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223