How to open a new window or tab in webdriver (Python)?
Asked Answered
R

4

3

I have tried various commands like

driver.switch_to_window("_blank")

or

driver.switch_to_window(None)

but none of these worked. How is this supposed to be done? Thanks.

Ronda answered 4/2, 2013 at 7:44 Comment(0)
D
1

Look at this question. Seems like the library doesn't support tab management atm.

But the second-highest rated answer does offer a solution. I think you can easily translate it to Python.

Dibbuk answered 4/2, 2013 at 8:33 Comment(2)
What about opening a new window? It seems like you can either do it through Robot or window handle. But I can't find any example or documentation for Python, and the things I tried didn't work.Ronda
I got it to work, based on the answer you referred to, but it's ugly as f**k... The webdriver guys really should fix this. Thanks though. script = "var d=document,a=d.createElement('a');a.id='C4wcELn0XTAp';a.target='_blank';a.href='about:blank';a.innerHTML='.';d.body.appendChild(a);return a"; webdriver.Chrome.execute_script(driver, script) my_el = driver.find_element_by_xpath(".//a[@id='C4wcELn0XTAp']") my_el.click()Ronda
R
10

After tons of googling, I came across what works for me in Firefox and which is so simple (elegant, maybe?) as to be almost laughable. Here it is:

>>> from selenium import webdriver
>>> driver = webdriver.Firefox()
>>> driver.execute_script("window.open('');")  <--- JAVASCRIPT!
Rupp answered 20/5, 2015 at 3:30 Comment(2)
This also works nicely with Splinter's window management API.Lourdeslourie
Awesome, this is the right answer, also works with Chrome driver.Geaghan
D
1

Look at this question. Seems like the library doesn't support tab management atm.

But the second-highest rated answer does offer a solution. I think you can easily translate it to Python.

Dibbuk answered 4/2, 2013 at 8:33 Comment(2)
What about opening a new window? It seems like you can either do it through Robot or window handle. But I can't find any example or documentation for Python, and the things I tried didn't work.Ronda
I got it to work, based on the answer you referred to, but it's ugly as f**k... The webdriver guys really should fix this. Thanks though. script = "var d=document,a=d.createElement('a');a.id='C4wcELn0XTAp';a.target='_blank';a.href='about:blank';a.innerHTML='.';d.body.appendChild(a);return a"; webdriver.Chrome.execute_script(driver, script) my_el = driver.find_element_by_xpath(".//a[@id='C4wcELn0XTAp']") my_el.click()Ronda
H
1

I have solved the problem this way:

a_elem = driver.find_element_by_link_text("Link with _blank")
self.driver.get(a_elem.get_attribute('href'))
Harvell answered 23/1, 2016 at 11:15 Comment(1)
hmm, problem is what if the page doesn't have the link with _blank ?Geaghan
K
0

I ran into the same issue, and I wasn't really satisfied with other solutions I found, so I made a context manager to do the handling. This allows:

with link_in_new_window(driver, link_element):
    driver.foo()  # this is in the new window opened from the link
driver.foo()  # this is back in the original window

..which I find to be very convenient.

from contextlib import contextmanager
from selenium.common import exceptions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

# Fundamentally, this shift-clicks to open a new window, and
# hits ctrl-w to close it when done, using ActionChains.
@contextmanager
def link_in_new_window(driver, element):
    """Open a clickable element in a new window for this context

    This opens a clickable element in a new window, and switches
    `driver` to that window for the duration of the context.  
    The window is closed afterward, and the driver switched back
    to the original window.

    If the 'as' clause is used, the handle of the parent (original)
    window is provided as the value.

    Selenium doesn't provide a useful interface to firefox's tabs
    due to some technical complications, so we use new windows
    instead of new tabs. The memory hit isn't too significant.

    :type driver: selenium.webdriver.Firefox
    :type element: selenium.webdriver.remote.webelement.WebElement
    :returns: Parent's Window Handle
    """

    known_handles = set(driver.window_handles)
    original_handle = driver.current_window_handle
    action = ActionChains(driver)
    # Open link in new window (shift-click element)
    # Sometimes, shift would be ignored. move_to_element helped.
    action.move_to_element(element)
        .key_down(Keys.SHIFT)
        .click(element)
        .key_up(Keys.SHIFT)
        .perform()

    # Find the new window handle.  ..anyone know a better way?
    timeout = time.time() + 10
    new_handles = set(driver.window_handles) - known_handles
    while time.time() < timeout and not new_handles:
        new_handles = set(driver.window_handles) - known_handles
        time.sleep(0.5)
    if not new_handles or len(new_handles) != 1:
        msg = "Expected one handle, found {}"
        raise RuntimeError(msg.format(len(new_handles)), new_handles)
    new_handle = new_handles.pop()
    driver.switch_to.window(new_handle)
    try:
        # User code will be executed here
        yield original_handle
    finally:
        # close window, if it still exists (ctrl-w)
        try:
            driver.switch_to.window(new_handle)
            action = ActionChains(driver)
            action.key_down(Keys.CONTROL).send_keys('w').perform()
        except exceptions.NoSuchWindowException:
            pass
        # in any case, switch back to the original window
        driver.switch_to.window(original_handle)
Kincardine answered 11/3, 2015 at 21:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.