Handling multiple browser windows with Ranorex Webtestit


#1

Automating a web application often requires handling multiple browser windows, whether you need to handle advertisement pop-up windows or a scenario where you have to open a new tab, perform some actions on it, and finally, switch back to your parent tab.
This may seem complicated, but using the WebDriver interface methods getWindowHandle() & getWindowHandles() and Ranorex Webtestit, it can be done quite easily.

getWindowHandle()
returns an opaque handle to this window that uniquely identifies it within this driver instance. This can be used to switch to this window later on.

getWindowHandles()
returns a set of window handles that can be used to iterate over all open windows of this WebDriver instance by passing them to switchTo().window() method.

Getting a set of window handles can sometimes be tricky, due to the loading/timing issues that may occur and due to the different behavior of the endpoint (browser) that we use to execute our tests. A recommended way to overcome this is to use the driver.wait.until(ExpectedConditions.numberOfWindowsToBe()); and provide the expected number of windows to be opened, before we collect all the window handles!

In this example, we will use this demo website for handling multiple browser windows.
Under the Switch Window Example category, we will click the Open Window button, and as the name itself says, a new window will be opened in our browser.
Now imagine that we need to perform some actions on that new window, and this is a situation where window handles come in play.

If you would try to perform your actions without using the window handles, the WebDriver instance will stay focused on our parent window, none of the elements in the newly opened child window would be available to you, and the test would fail due to the element not being located.

In order to successfully automate this scenario, we will first locate our parent window, then get all other opened windows/tabs. After that we need to switch to the child window, perform our action and finally switch back to the parent window, so let’s start.

We will create a simple test case where we will open the webpage, assert the title of our parent window, open a child window and switch to it using Window Handles and finally assert the child window’s title to make sure that we switched to that child window.

First of all, we will create the parentWindow variable and store the parent’s window handle in that variable later.

// We stored the parent WindowHandle inside this variable
public String parentWindow;

To store the parent window handle, we will modify the predefined open() method in our Page Object file by adding the driver.getWindowHandle() method.

public HomePo open(String url) {
        this.driver.get(url);

        // Get the parent WindowHandle and store it in parentWindow variable
        this.parentWindow = this.driver.getWindowHandle();

        return this;
    }

This way, we will have the parent window handles stored right after the page is opened.
Next, we will create our openChildWindow() method, which will click the link that is generating the additional (child) window.

public HomePo openChildWindow() {
        // Open the Child Window
        this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.openwindow)).click();

        return this;
    }

Finally, we will create the switchToChildWindow() method. In this method, we will store the window handles of both opened windows and use a simple for loop to iterate through them and finally switch to the required window if the condition is met.

Important: While trying to get all the window handles, you may encounter some timing issues (e.g. the page has not been fully loaded, not recognized by WebDriver and not stored, especially using the Mozzila Firefox Driver. This is where the driver.wait.until(ExpectedConditions.numberOfWindowsToBe()) method comes in place. If we know that we will have two windows opened, we can use this method to wait until both windows are opened and loaded.

   public HomePo switchToChildWindow(Integer numOfWindows) {
        // Wait untill the number of open windows is matching
        this.wait.until(ExpectedConditions.numberOfWindowsToBe(numOfWindows));
        
    // Get the opened browser windows and store them as a Set of Strings
        Set<String> allWindows = this.driver.getWindowHandles();

    // Iterate through the set and switch to the child window
        for (String window : allWindows) {
            if (window != this.parentWindow) {
                driver.switchTo().window(window);
            }
        }
        return this;
    }

Coming to the actual Test, we will instantiate our Page Object file, open our demo web page and assert the parent window’s ( "Practice | Let’s Kode It”) title.
Afterward, we will call the openChildWindow() and switchToChildWindow() method and assert the child window’s (“Let’s Kode It”) title to verify that we successfully switched to it. When calling the switchToChildWindow() we will provide the number of windows that we expect to be opened (2)

 @Test
    public void SwitchTo() {
        WebDriver driver = getDriver();
        // Instantiate the PO file and open the web page
        HomePo home = new HomePo(driver).open("https://letskodeit.teachable.com/p/practice");

        // Assert the title of the Parent Window
        Assert.assertEquals(home.getTitle(), "Practice | Let's Kode It");

        // Open the child Window
        home.openChildWindow();

        // Switch to Child Window
        home.switchToChildWindow(2);

        // Assert the title of the Child Window
        Assert.assertEquals(home.getTitle(), "Let's Kode It");

    }

Another scenario that you could face is where multiple browser tabs are opened and you need to switch to a specific, let’s say third or fourth tab.

One of the solutions here is to store all the tabs into an ArrayList using the getWindowHandles() method and then, using the index number assigned for a specific tab, switch to it tab using the driver.switchTo.window() method.

In the following example, we will use this demo site to switch to a specific tab.
First, in our PageObject file, we will create three methods that will open up separate (Login, Buttons, and ToDo) tabs in the browser.

public MainPo openLoginTab() {
    this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.LOGIN_PORTAL)).click();

    return this;
}

public MainPo openButtonsTab() {
    this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.BUTTON_CLICKS)).click();

    return this;
}

public MainPo openToDoTab() {
    this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.TO_DO_LIST)).click();

    return this;
}

Afterward, we will create the .getTabsAndSwitchTo(int index) method, which will take the number of expected opened tabs and the index number of the tab that we want to switch to as a parameter. We will get all tabs using the .getWindowHandles() method, and store them into an ArrayList. Furthermore, we are adding the driver.switchTo().window(allTabs.get(index)) method that uses the provided index number to switch to the corresponding tab.

public MainPo getTabsAndSwitchTo(int numOfTabs, int index) {
        // Before executing the .getWindowHandles method, wait for 4 tabs to be opened
        this.wait.until(ExpectedConditions.numberOfWindowsToBe(numOfTabs));

        // Get all tabs and store them into an ArrayList
        ArrayList<String> allTabs = new ArrayList<String>(driver.getWindowHandles());

        // Switch to desired tab stored in the ArrayList using index number
        driver.switchTo().window(allTabs.get(index));

        return this;
    }

We will use the assert page title to make sure that we are in the right place.

@Test
    public void SwitchToButtonTab()  {
        WebDriver driver = getDriver();

        // Inatantiate the PO file and open the web page
        MainPo main = new MainPo(driver);
        main.open("http://webdriveruniversity.com/index.html");

        // Open the Login, Button, and ToDo tabs
        main.openLoginTab().openButtonsTab().openToDoTab();

        // Switch to the second (Button) tab
        main.getTabsAndSwitchTo(4, 2);
        

        // Assert the title
        Assert.assertEquals(main.getTitle(), "WebDriver | Button Clicks");
    }

Conclusion:
Handling multiple browser windows and switching between tabs is a must-known topic in test automation area. In this article, we demonstrated two ways to handle it. There are more ways to accomplish this task, but using the .getWindowHandles() method approach is the safest way to do it. Happy Testing!


Recommended way to switching tabs (and closing tabs)