pythonseleniumselenium-webdriverwindow-handlesexpected-condition

How to switch tabs using the expected conditions new_window_is_opened and verify the page title using Selenium and Python


I'm writing a test which goes through multiple pages and then verifies the title is being displayed. Currently my test is at the point where i can click a button and it opens a report. The problem is the report opens up in a new tab so i need my test to move tabs and verify the title in the new tab.

The title that needs to be verified is 'valuation'. I've done an assert to confirm the title is the same as i expect

I've written the code below in python. Its currently failing at wait on the 2nd line

current = self.driver.current_window_handle
wait(self.driver, 10).until(EC.new_window_is_opened(self.driver.window_handles))
self.driver.switch_to.window([w for w in self.driver.window_handles if w != current][0])
title = self.driver.title
self.assertTrue("Valuation" == self.driver.title)

I'm opening a new tab with the following lines of code:

element = driver.find_element_by_xpath("//input[@id='save' and @name='save'][@value='View Report']") 
driver.execute_script("arguments[0].click();", element)

Solution

  • new_window_is_opened(current_handles)

    new_window_is_opened(current_handles) is the expectation that a new window will be opened and have the number of windows handles increase.


    Demonstration

    The following example opens the url http://www.google.co.in first and then opens the url https://www.yahoo.com in the adjacent tab:

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    options = webdriver.ChromeOptions() 
    options.add_argument("start-maximized")
    driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get("http://www.google.co.in")
    windows_before  = driver.window_handles
    driver.execute_script("window.open('https://www.yahoo.com')")
    WebDriverWait(driver, 20).until(EC.new_window_is_opened(windows_before))
    driver.switch_to.window([x for x in driver.window_handles if x not in windows_before][0])
    

    Note: The argument passed to new_window_is_opened(current_handles) is a list. In order to create a list we need to use windows_before = driver.window_handles


    This usecase

    In your code block, it is expected that when you:

    current = self.driver.current_window_handle
    

    There exists only one window handle. So moving forward, the line of code:

    wait(self.driver, 10).until(EC.new_window_is_opened(self.driver.window_handles))
    

    would wait for a new window to be opened and have the number of windows handles increases and that would happen only after an action is performed which opens a new window, which seems to be missing from your code block.


    Solution

    Insert the line of code which initiates opening of a new :

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    windows_before  = driver.window_handles
    element = driver.find_element_by_xpath("//input[@id='save' and @name='save'][@value='View Report']")
    driver.execute_script("arguments[0].click();", element)
    WebDriverWait(self.driver, 10).until(EC.new_window_is_opened(windows_before))
    driver.switch_to.window([x for x in driver.window_handles if x not in windows_before][0])
    assertTrue("Valuation" == driver.title)
    

    Note: As per the lines of code you have updated within your comments you are not using Python class, so you shouldn't use the keyword self.