How To Handle NoSuchWindowException In Selenium

How To Handle NoSuchWindowException In Selenium

·

14 min read

In today’s digital landscape, websites are brimming with dynamic content, captivating users with interactive experiences. A notable feature is the frequent emergence of new windows and tabs triggered by specific actions taken by users. These dynamic elements play a vital role in enhancing user engagement and providing seamless navigation.

As an automation tester, encountering scenarios where multiple windows or tabs need to be handled within an end-to-end flow is a common occurrence. Successfully managing this dynamic behavior becomes essential to ensure the accuracy and reliability of your automated tests.

However, this becomes highly challenging as automated tests tend to fail and make your test scripts less reliable. Your automation testing script should be able to manage many windows for better testing. In such situations, switching focus to perform any action on the necessary window or tab becomes an unsaid requirement.

Selenium offers various methods to work with multiple windows. But any slightest mistake, like using an invalid window handle, switching to a closed window, etc., can lead to NoSuchWindowException in the automation script. We will discuss more about these in the next sections.

NoSuchWindowException occurs when the WebDriver tries to interact with a window that is not available at that moment. This could be due to a closed window or the window in focus being different.

In this Selenium Java tutorial, we will discuss how to handle NoSuchWindowException in Selenium. We will discuss the most common reasons for the same and the best practices to handle it. The practical implementation of these practices using Selenium Java will help you to learn how to handle NoSuchWindowException in your automation scripts to make tests run smoothly and reliably.

So, Let’s get started.

What is a window and window handle?

In Selenium, a window refers to a graphical user interface (GUI) window or a web browser window/tab, in particular while working with web automation. When Selenium WebDriver launches a web browser, it opens a new window in which the webpage gets loaded.

Each window is represented by a unique ID called a window handle. It allows the WebDriver to interact with the window and its elements. These handles are also used to switch between different windows, manipulate the size and position of the window, and perform other actions on the window and its contents.

If you have multiple browser windows open, you can use this method to retrieve a set of all the window handles. In this blog, Selenium with Java language has been used for demonstration and to provide code samples.

driver.getWindowHandles()


    Returns a Set<String> containing handles of all the windows

To switch to a specific window by passing in its handle:

driver.switchTo().window("<random_window_handle>")

To switch to the main window back:

    driver.switchTo().defaultContent()

To understand these methods better, consider the following test scenario.

We want to reach the Twitter page and click on the Login button. This button is available on the page loaded in a new window. This new window, Window2 is loaded by clicking the Follow button on the previous/main window, Window1.

Now, if we want the test scenario to pass, the driver focus must be switched first to Window2 once it is loaded. If you try to switch driver focus before the load is completed, it will raise a NoSuchWindowException.

Which are the most wanted automation testing tools in 2023 that have climbed the top of the ladder so far? Let’s take a look!

What is a NoSuchWindowException in Selenium?

NoSuchWindowException is one of the most frequently encountered exceptions in Selenium WebDriver while working with multiple windows/tabs. The NoSuchWindowException is raised when the WebDriver cannot find the desired browser window or tab that it needs to interact with.

This exception would occur if there are multiple open windows and WebDriver is looking for one with incorrect window handles. Another reason could be that the required window is closed already and is no longer available.

The NoSuchWindowException can also occur if there is a problem with the browser itself, like it has crashed due to some previous actions or has become unresponsive.

An important thing to note here is that handling multiple frames in Selenium is slightly different than handling multiple windows in Selenium. As for frames, the methods provided to switch are different, and similarly, the expectation raised in case a frame is not found is NoSuchFrameException.

Perform browser automation testing platform on the most powerful cloud infrastructure. Leverage LambdaTest automation testing for faster, reliable and scalable experience on cloud.

Reasons for NoSuchWindowException in Selenium

This exception can occur for many reasons while working with multiple windows. A few of the most common ones are.

  • Closure of window

  • Driver focuses on another window

  • Invalid window handle

  • Window load timing issue

Demonstration: How to fix NoSuchWindowException in Selenium?

To demonstrate the best practices for handling NoSuchWindowException in Selenium, we will create a Java project with Maven and TestNG framework using Selenium 4.

Test Scenario — 1 (Demonstrate NoSuchWindowException)

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo.

  2. Click Follow on Twitter.

  3. Get a list of all window handles and print them on the console.

  4. Try to switch to the new window using an invalid window handle.

  5. Verify NoSuchWindowException is raised.

Test Scenario — 2 (Handle NoSuchWindowException using Try-Catch)

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo

  2. Click Follow on Twitter.

  3. Get a list of all window handles and print them on the console.

  4. Start the try block.

  5. Try to switch to the new window using an invalid window handle.

  6. Verify NoSuchWindowException is raised and caught inside the catch block.

Test Scenario — 3 (Handle NoSuchWindowException using Explicit Wait)

  1. Navigate to https://www.lambdatest.com/selenium-playground/window-popup-modal-demo

  2. Click Follow on Twitter.

  3. Add Explicit Wait using Expected Conditions to wait until the number of windows is 2.

  4. Fetch a list of all window handles and store them in a variable.

  5. Start a loop to switch to each window using the window handle one by one.

  6. Switch to the new window using the window handle.

  7. Check if this is the required window by verifying its title.

  8. If it is a match, break the loop. If not, repeat Steps 6 and 7 till the required window is found.

  9. Click on the Login button on the new window.

This blog uses the Eclipse IDE for demonstration purposes, but feel free to use any IDE of your preference. The implementation process remains identical until the creation of a Maven project, regardless of the IDE you choose.

As we are working with Selenium web automation, we would start by adding Selenium dependency along with TestNG, which will be used for test execution to the pom.xml of the project.

After the project is created and dependencies are added, the final pom.xml would be like the one below.

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
       <groupId>NoSuchWindowException</groupId>
       <artifactId>NoSuchWindowException</artifactId>
       <version>0.0.1-SNAPSHOT</version>
       <build>
           <sourceDirectory>src</sourceDirectory>
           <plugins>
               <plugin>
                   <artifactId>maven-compiler-plugin</artifactId>
                   <version>3.8.1</version>
                   <configuration>
                       <release>19</release>
                   </configuration>
               </plugin>
           </plugins>
       </build>
       <dependencies>
           <dependency>
               <groupId>org.seleniumhq.selenium</groupId>
               <artifactId>selenium-java</artifactId>
               <version>4.8.3</version>
           </dependency>
           <dependency>
               <groupId>org.testng</groupId>
               <artifactId>testng</artifactId>
               <version>7.7.1</version>
               <scope>test</scope>
           </dependency>
       </dependencies>
    </project>

Next, add a new Java test file TestNoSuchWindowException.java under src.test package. Once added the project structure would look like this.

We will add our test cases to this to see how to prevent NoSuchWindowException from occurring in our Selenium automation scripts.

In this blog, we will harness the power of a Selenium cloud grid like LambdaTest to perform Selenium Java testing. LambdaTest is a digital experience testing cloud that exponentially increases your browser coverage by running your Java automation testing scripts with Selenium on a cloud of 3000+ desktop and mobile environments.

A complete Manual testing tutorial covering all aspects of Manual testing, including strategies and best practices.

After adding all the WebDriver configurations and test case examples to demonstrate the fix for NoSuchWindowException, the completed file should look like the below:

 package test;


    import java.net.*;
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.Set;


    import org.openqa.selenium.remote.RemoteWebDriver;
    import org.testng.annotations.*;
    import org.openqa.selenium.By;
    import org.openqa.selenium.NoSuchWindowException;
    import org.openqa.selenium.safari.`Options;
    import org.openqa.selenium.support.ui.*;


    public class TestNoSuchWindowException {


       public RemoteWebDriver driver = null;


       String username = System.getenv("LT_USERNAME") == null ? "<lambdatest_username>" : System.getenv("LT_USERNAME");
       String accessKey = System.getenv("LT_ACCESS_KEY") == null ? "<lambdatest_accesskey>" : System.getenv("LT_ACCESS_KEY");


       @BeforeTest
       public void setup()
       {
           try {
               SafariOptions safariOptions = new SafariOptions();
               safariOptions.setPlatformName("MacOS Big sur");
               safariOptions.setBrowserVersion("14.0");

               HashMap<String, Object> ltOptions = new HashMap<String, Object>();
               ltOptions.put("build", "NoSuchWindowException in Selenium");
               ltOptions.put("name", "Handling NoSuchWindowException");
               ltOptions.put("w3c", true);
               safariOptions.setCapability("LT:Options", ltOptions);

               driver = new RemoteWebDriver(
                       new URL("https://" + username + ":" + accessKey + "@hub.lambdatest.com/wd/hub"), safariOptions);
           } catch (MalformedURLException e) {
               e.printStackTrace();
           }
            driver.get("https://www.lambdatest.com/selenium-playground/window-popup-modal-demo");
       }


       @AfterTest
       public void tearDown() {
           driver.quit();
       }


       @Test
       public void testNoSuchWindowException()
       {  
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();

           Set<String> handles = driver.getWindowHandles();
           for(String handle : handles)
           {
               System.out.println("Valid handle value : " + handle);
               //adding -updated to valid handle value to demonstrate exception
               //due to invalid handle value
               driver.switchTo().window(handle + "-updated");
           }
       }


       @Test
       public void testNoSuchWindowException_fix()
       {  
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();

           WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15));
           wait.until(ExpectedConditions.numberOfWindowsToBe(2));
           System.out.println("Verified total windows are 2");

           System.out.println("Fetching window handles of all windows");
           Set<String> handles = driver.getWindowHandles();


           System.out.println("Switching to each window one by one to verify if it is required one");
           for(String handle : handles)
           {
               System.out.println("Switching to window with handle : " + handle);
               driver.switchTo().window(handle);
               //using window title to reach to required window
               if(driver.getTitle().equals("Profile / Twitter"))
               {
                   System.out.println("Reached required window");
                   break;
               }
           }
           driver.findElement(By.xpath("//*[@data-testid='login']")).click();
           System.out.println("Clicked Login button successfully");
       }

       @Test
       public void testNoSuchWindowException_fix_tryCatch()
       {
           System.out.println("Clicking on Follow button");
           driver.findElement(By.xpath("//*[@title='Follow @Lambdatesting on Twitter']")).click();
           try
           {
               Set<String> handles = driver.getWindowHandles();
               for(String handle : handles)
               {
                   System.out.println("Valid handle value : " + handle);
                   //adding -updated to valid handle value to get exception
                   //due to invalid handle value
                   System.out.println("Invalid handle value used : " + handle + "-updated");
                   driver.switchTo().window(handle + "-updated");
               }
           } catch (NoSuchWindowException ex) {
               System.out.println("We are inside catch block");
               System.out.println("NoSuchWindowException has been caught.");
           }
       }
    }

CodeWalkthrough

Step 1. We start by creating an instance of RemoteWebDriver as we will execute the code on the cloud Selenium Grid.

Step 2. Navigate to the LambdaTest Profile section once you create your account to fetch the username and access key. These will be used to make a connection to their cloud grid.

You can also configure the username and access key as environment variables using the following commands and directly fetch them in code.

For macOS and Linux:

export LT_USERNAME=LT_USERNAME
    export LT_ACCESS_KEY=LT_ACCESS_KEY

For Windows:

set LT_USERNAME=LT_USERNAME
    set LT_ACCESS_KEY=LT_ACCESS_KEY

We can also fetch the required browser capabilities to use the LambdaTest platform by navigating to their Automation Capabilities Generator. This helps by offering ready-to-use code for setting up browser capabilities that can be used in execution.

Step 3. Create a base method and name it as setup() and annotate with @BeforeTest annotation in TestNG. This method will be used for driver setup and opening the webpage before each test.

In this blog, we have used Selenium 4, which supports SafariOptions class. In this function, an object of the same is created to define browser properties like browser version, OS version, etc. It also accepts the variables required for LambdaTest execution as a capability.

These variables are used to set values like build, name, or any other browser property, which will help to identify the run on the LambdaTest Dashboard or modify behavior.

Step 4. Finally, an instance of RemoteWebDriver is created to connect to the LambdaTest Cloud grid using the safariOptions, and your Lambdatest username and the access key.

Step 5. Finally, navigate to the sample website under test, which will have a new window open on clicking a button.

Step 6. Add a method as tearDown() and annotate it with @AfterTest annotation. This will be used to close the session after each test case.

Need a great solution for Safari browser testing on Windows? Forget about emulators or simulators — use real online browsers. Try LambdaTest for free!

Test Scenario: NoSuchWindowException in Selenium

Step 1. Add the first test case and name it as testNoSuchWindowException(). In this test, we try to simulate the NoSuchWindowException in Selenium by using an invalid window handle.

Step 2. We start by clicking the Follow button, which will open a new window.

For this, we use the driver.findElement() method in Selenium and use XPath as a web element locator.

Step 3. Next, fetch the list of all window handles using driver.getWindowHandles() and store them in a variable. This traverses through the window handles list and prints valid handle values.

Step 4. Lastly, our attempt to switch to the newly opened window involves passing an invalid window handle. For this, the valid handle value from the previous step is manipulated to demonstrate the exception.

Step 5. On executing this, you can observe that the test case fails with NoSuchWindowException in Selenium as the window handle passed is invalid, and Selenium cannot locate a window using the same.

In the following sections, we will see the implementation of some of the best practices to prevent this NoSuchWindowException in Selenium from happening.

Elevate Your Mobile App Testing Quality: Make the most of your mobile application testing & Test on LambdaTest Cloud for Comprehensive Testing, Bug Detection & More.

Fixing NoSuchWindowException in Selenium using Try-Catch

As discussed in the best practices sections, one of the most used ways to handle NoSuchWindowException in Selenium is using the try-catch block.

Step 1. For this, add another test case to the Java file and name it testNoSuchWindowException_fix_tryCatch().

Step 2. Click the Follow button, which is expected to open a new window.

Step 3. In this approach, code that would lead to an exception on switching to a new window, like the previous scenario, is used.

The only difference is that we place this code inside the try block. This will help to catch the exception and prevent abrupt behavior from the automation script.

Step 4. This is followed by a catch block. This helps to catch the exception if it occurs and perform any subsequent actions. It also helps to terminate the code gracefully in such cases.

Step 5. Executing the above code, you will get the following output. In this, you can see that NoSuchWindowException is raised but is handled gracefully inside the catch block.

But it is very important to note that even if the exception is handled, you cannot perform any action on the new window. This is because the exception was raised, which means either the window handle is incorrect or the window does not exist.

You can always add a retry in such a case to try again the previous action, which should launch the window or check if the handle is correct and try to switch again.

Run your Selenium Testing scripts on the LambdaTest cloud grid. Test on 3000+ desktop & mobile environments. Try it for free!

Fixing NoSuchWindowException in Selenium using Window Handles and Waits

Step 1. Next, add a new test case and name it testNoSuchWindowException_fix(). We will use this to demonstrate how using Waits and Window Handles properly helps us to prevent NoSuchWindowException from happening.

Step 2. We start by clicking on the button, which is expected to open a new window.

Step 3. As we click on the button, the expectation here is that now the total number of windows should be 2 like below.

To handle the exception, we use explicit waits in Selenium to wait until the number of windows is equal to 2 and then move forward with the flow.

Step 4: For this, create an object of WebDriverWait class and pass the driver object and the duration for which we want to wait for the maximum time.

Using this object with the until() function, we add an ExpectedConditions to wait for the number of windows to be 2. The driver waits for a maximum of 5 seconds for this condition to happen.

If the number of windows is validated, we move forward else the driver throws an error to show that condition is not fulfilled.

Step 5. Next, fetch the window handle for all the open windows. We will be storing this in a Set.

Step 6. We will traverse through this list of handles and switch to each window one by one until the required window is found.

Step 7. To check if the current window is required or not, we check by matching the title of the required window with the current window. If it’s a match, break the loop and continue. If not, switch to the next window using the handle and continue the same flow.

Step 8. When the required window is found in WebDriver focus, click on the login button, and the success message is printed.

Executing the above test case, we get an output like the one below.

From the output screenshot, you can see that we had successfully verified that 2 windows are present using waits. Then we switch driver focus to the required new window and can successfully click on the Login button without encountering an exception.

Best practices to handle NoSuchWindowException in Selenium

From the demonstration section, it is quite clear that NoSuchWindowException in Selenium can be easily handled in your automation script by following some of the best practices.

Let us have a look at these in a bit more detail.

  • Using explicit waits

  • Using valid window handles

  • Switching to the correct window

  • Using a try-catch block

  • Keeping track of window handles

Conclusion

In conclusion, NoSuchWindowException is a common exception in Selenium that can occur when working with multiple windows or tabs. However, with the right knowledge of best practices to handle the same, we can make automation tests run smoothly and reliably. In this blog, we discussed the common reasons that can lead to NoSuchWindowException in Selenium. We also learned the best practices to handle the same and did some hands-on practice on how to add these approaches to your automation scripts. So, now it is for you to get started and, with a little attention to the powers of Selenium, prevent NoSuchWindowException in your scripts.