Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium
You are pretty correct when you say:
WindowHandles would be sorted like the oldest windows first and the newest windows last. But this is not the case: It is totaly random!
In a discussion, Simon clearly mentioned that:
While the datatype used for storing the list of handles may be ordered by insertion, the order in which the WebDriver implementation iterates over the window handles to insert them has no requirement to be stable. The ordering is arbitrary.
So, we will induce an WebDriverWait
and then collect the window handles every time we open a new tab/window and finally iterate through the window handles and switchTo().window(newly_opened)
as required:
Please adjust the
Test Environment
if needed [My configuration -Selenium
: 3.5.3,IEDriverServer
: 3.5.0.0 (64-bit),IE
: v10.0]
Java:
package demo;
import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class NEW_TAB_Handling {
public static void main(String[] args) {
System.setProperty("webdriver.ie.driver", "C:\\Utility\\BrowserDrivers\\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
driver.get("http://www.google.com");
String first_tab = driver.getWindowHandle();
System.out.println("Working on Google");
((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
WebDriverWait wait = new WebDriverWait(driver,5);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> s1 = driver.getWindowHandles();
Iterator<String> i1 = s1.iterator();
while(i1.hasNext())
{
String next_tab = i1.next();
if (!first_tab.equalsIgnoreCase(next_tab))
{
driver.switchTo().window(next_tab);
System.out.println("Working on Facebook");
}
}
String second_tab = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open('http://youtube.com/');");
wait.until(ExpectedConditions.numberOfWindowsToBe(3));
Set<String> s2 = driver.getWindowHandles();
Iterator<String> i2 = s2.iterator();
while(i2.hasNext())
{
String next_tab = i2.next();
if (!first_tab.equalsIgnoreCase(next_tab) && !second_tab.equalsIgnoreCase(next_tab))
{
driver.switchTo().window(next_tab);
System.out.println("Working on Youtube");
}
}
driver.quit();
System.out.println("Quit the WebDriver instance");
}
}
Console Output:
Working on Google
Working on Facebook
Working on Youtube
Quit the WebDriver instance
Outro
You can find the python based discussion in Open web in new tab Selenium + Python
How to handle new window, which opened automatically in new tab?
If it's a new window to count the number of WindowHandles you need to induce WebDriverWait for numberOfWindowsToBe(2)
and you can use the following code block:
String mainWindowHandler = driver.getWindowHandle(); // store mainWindowHandler for future references
//line of code that opens a new TAB / Window
new WebDriverWait(driver, 5).until(ExpectedConditions.numberOfWindowsToBe(2)); //induce WebDriverWait
Set<String> handles = driver.getWindowHandles();
Iterator<String> iterator = handles.iterator();
while (iterator.hasNext())
{
String subWindowHandler = iterator.next();
if (!mainWindowHandler.equalsIgnoreCase(subWindowHandler))
{
driver.switchTo().window(subWindowHandler);
}
}
References
You can find a couple of relevant detailed discussions in:
- Selenium switch focus to tab, which opened after clicking link
- Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium
- org.openqa.selenium.WebDriverException: invalid argument: 'handle' must be a string while window handling with Selenium and Java in Linux
Switch tabs using Selenium WebDriver with Java
psdbComponent.clickDocumentLink();
ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.get(0));
This code perfectly worked for me. Try it out. You always need to switch your driver to new tab, before you want to do something on new tab.
Related Topics
How to Remove Elements from a Generic List While Iterating Over It
Process.Start: How to Get the Output
What Does the =≫ Operator Mean in a Property
Identify If a String Is a Number
Why Did I Get the Compile Error "Use of Unassigned Local Variable"
How to Pass Table Value Parameters to Stored Procedure from .Net Code
How to Find Out Which Process Is Locking a File Using .Net
How to Write Unicode Characters to the Console
Do Httpclient and Httpclienthandler Have to Be Disposed Between Requests
The Located Assembly'S Manifest Definition Does Not Match the Assembly Reference
Convert Webpage to Image from Asp.Net
How to Find the Text Within a Div in the Source of a Web Page Using C#
How to Create an Excel (.Xls and .Xlsx) File in C# Without Installing Microsoft Office
How to Check If a File Is in Use
How to Handle Both a Single Item and an Array For the Same Property Using Json.Net
What Is the Purpose of "Return Await" in C#
Why Are Cdecl Calls Often Mismatched in the "Standard" P/Invoke Convention