6

I have webpage which open new browser window on click. I am able to get 2 handles however driver.close() always closes the first/main window.

from selenium import webdriver
import time
driver = webdriver.Chrome() 
driver.get("file:///D:/blackhole/print.html")
han = driver.window_handles
print("handles:", han) # gets 1 handle
time.sleep(2)
click_btn = driver.find_element_by_link_text('Print')
click_btn.click()
han = driver.window_handles
print("handles:", han) # gets 2 handles
driver.switch_to_window = han[1] # first element is always first window handle
driver.close() # main window close

Below webpage code which invokes new window

<a href="print.html"  
onclick="window.open('popprint.html', 
                    'newwindow', 
                    'width=300,height=250'); 
        return false;"
>Print</a>

Same behaviour for Firefox as well. Python 3.6.7

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Nutan
  • 63
  • 1
  • 1
  • 4
  • I just tried running one of the tests (`testShouldThrowNoSuchWindowExceptionOnAnyElementOperationIfAWindowIsClosed` in python bindings of Selenium. The test is passing. Please have a look at https://github.com/SeleniumHQ/selenium/blob/aed1c2ad01048753f55317685d28ab69e99e8bd5/py/test/selenium/webdriver/common/window_switching_tests.py#L116 Therefore, I feel that `driver.close()` is working fine. – Jitendra Dec 18 '18 at 10:57
  • I tested with Python 3.7.0 on Windows too. The above stated test works fine. – Jitendra Dec 18 '18 at 11:19
  • Yes it does. Main difference I have found it `switch_to_window` versus `switch_to.window()` . – Nutan Dec 18 '18 at 18:30

2 Answers2

4

Selenium is unable to close the active window i.e the newly opened window because practically you havn't switched to the newly opened window in a clean way.

Solution

A few words about Tab/Window switching/handling:

  • switch_to_window(window_name) is deprecated for quite some time now and you need to use driver.switch_to.window
  • Always keep track of the Parent Window handle so you can traverse back later if required as per your usecase.
  • Always use WebDriverWait with expected_conditions as number_of_windows_to_be(num_windows) before switching between Tabs/Windows.
  • Always keep track of the Child Window handles so you can traverse whenever required.
  • Always use WebDriverWait with expected_conditions as title_contains("partial_page_title") before extracting the Page Title.
  • Here is your own code with some minor tweaks mentioned above:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    driver = webdriver.Firefox(executable_path=r'C:\WebDrivers\geckodriver.exe')
    driver.get("file:///D:/blackhole/print.html")
    parent_han  = driver.window_handles
    driver.find_element_by_link_text('Print').click()
    WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
    all_han = driver.window_handles
    new_han = [x for x in all_han if x != parent_han][0]
    driver.switch_to.window(new_han)
    driver.close()
    
  • You can find a detailed discussion in Selenium Switch Tabs

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • +1 Thanks Deb for detailed answer and suggestions. Somehow switch_to_window did not show deprecated warning in my code. – Nutan Dec 17 '18 at 10:49
  • @Nutan Phasing out the deprecated methods and implementing newly developed methods is a part of _best practice_ every developer should follow. However, unless _removed_ deprecated methods should continue to work as expected. – undetected Selenium Dec 17 '18 at 11:06
2

driver.close() only closes the current window. To close all Windows and quit the webdriver, call driver.quit() instead.

Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143