Skip to main content

_java

TL;DR - Show Me The Code

4-work-with-multiple-windows/code/java/src/test/java/com/elemental/selenium/MultipleWindowsTest.java
package com.elemental.selenium;

import java.time.Duration;
import java.util.List;
import java.util.ArrayList;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.WebDriverWait;

public class MultipleWindowsTest {
WebDriver driver;
WebDriverWait wait;

@BeforeEach
public void beforeEach() {
driver = new FirefoxDriver();
wait = new WebDriverWait(driver, Duration.ofSeconds(2));
}

@AfterEach
public void afterEach() {
if (driver != null) {
driver.quit();
}
}

@Test
public void multipleWindows() throws InterruptedException {
driver.get("https://the-internet.herokuapp.com/windows");
driver.findElement(By.cssSelector(".example a")).click();
List<String> windowHandles = new ArrayList<>(driver.getWindowHandles());
driver.switchTo().window(windowHandles.get(0));
Assertions.assertEquals("The Internet", driver.getTitle());
driver.switchTo().window(windowHandles.get(1));
// Waiting for the new window to have a title, then we consider it is loaded
wait.until(driver -> !driver.getTitle().isEmpty());
Assertions.assertEquals("New Window", driver.getTitle());
}

@Test
public void multipleWindowsRedux() throws InterruptedException {
driver.get("https://the-internet.herokuapp.com/windows");
// Get initial window handle
String firstWindow = driver.getWindowHandle();
// Create a newWindow variable
String newWindow = "";
// Trigger new window to open
driver.findElement(By.cssSelector(".example a")).click();
// Grab all window handles
List<String> windowHandles = new ArrayList<>(driver.getWindowHandles());
// Iterate through window handles collection
// Find the new window handle, storing it in the newWindow variable
for (String window : windowHandles) {
if (!window.equals(firstWindow)) {
newWindow = window;
}
}
// Switch to the first window & verify
driver.switchTo().window(firstWindow);
Assertions.assertEquals("The Internet", driver.getTitle());
// Switch to the new window & verify
driver.switchTo().window(newWindow);
// Waiting for the new window to have a title, then we consider it is loaded
wait.until(driver -> !driver.getTitle().isEmpty());
Assertions.assertEquals("New Window", driver.getTitle());
}

}

Code Walkthrough

Importing Libraries, Setup and Teardown

First let's import our requisite classes (for annotations (e.g., org.junit.After, etc.), driving the browser with Selenium (e.g., org.openqa.selenium.WebDriver, etc.), and matchers for our assertions (e.g., org.junit.jupiter.api.Assertions, etc.)), Selenium's wait functions (e.g., org.openqa.selenium.support.ui.WebDriverWait, etc.), and start our class with some setup and teardown methods.

Next, we'll start our class off with some setup and teardown methods, covered in lines 20 to 31.

Example 1

Line 34 shows a test that exercises new window functionality from an application. In this case, we'll be using the new window example from the-internet.

After loading the page we click the link which spawns a new window. We then grab the window handles (a.k.a. unique identifier strings which represent each open browser window) and switch between them based on their order (assuming that the first one is the originating window, and that the second one is the new window). We round this test out by performing a simple check against the title of the page to make sure Selenium is focused on the correct window.

While this may seem like a good approach it can present problems later because the order of the window handles is not consistent across all browsers. Some return it in the order opened, others alphabetically.

Here's a more resilient approach. One that will work across all browsers.

Example 2

Line 46 shows that after loading the page we store the window handle in a variable (e.g., firstWindow) and then proceed with clicking the new window link.

Now that we have two windows open we grab all the window handles and search through them to find the new window handle (e.g., the handle that doesn't match the one we've already stored). We store the new window result in another variable (e.g., newWindow) and then switch between the windows, checking the page title each time to make sure the correct window is in focus.

For more information about switching windows (and tabs) visit the official Selenium documentation page.

Executing the Test

Before executing the test, we need to make sure the required dependencies are declared on the pom.xml file.

Toggle to see the pom.xml file.
4-work-with-multiple-windows/code/java/pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.elemental.selenium</groupId>
<artifactId>tips</artifactId>
<version>1.0.0</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.25.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.11.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

Finally, we can run the test by executing mvn test from the command-line.