Where WindowName is a string representing the name of the window you want to switch focus to. Call this function again with the name of the original window to get back to it when you are done.
// Store the current window handle
String winHandleBefore = driver.getWindowHandle();
// Perform the click operation that opens new window
// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
driver.switchTo().window(winHandle);
}
// Perform the actions on new window
// Close the new window, if that window no more required
driver.close();
// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);
// Continue with original browser (first window)
I use iterator and a while loop to store the various window handles and then switch back and forth.
//Click your link
driver.findElement(By.xpath("xpath")).click();
//Get all the window handles in a set
Set <String> handles =driver.getWindowHandles();
Iterator<String> it = handles.iterator();
//iterate through your windows
while (it.hasNext()){
String parent = it.next();
String newwin = it.next();
driver.switchTo().window(newwin);
//perform actions on new window
driver.close();
driver.switchTo().window(parent);
}
Surya, your way won't work, because of two reasons:
you can't close driver during evaluation of test as it will loose focus, before switching to active element, and you'll get NoSuchWindowException.
if test are run on ChromeDriver you`ll get not a window, but tab on click in your application. As SeleniumDriver can't act with tabs, only switchs between windows, it hangs on click where new tab is being opening, and crashes on timeout.
For my case, IE began detecting new window handles after the registry edit.
Taken from the MSDN Blog:
Tab Process Growth : Sets the rate at which IE creates New Tab processes.
The "Max-Number" algorithm: This specifies the maximum number of tab processes that may be executed for a single isolation session for a single frame process at a specific mandatory integrity level (MIC). Relative values are:
TabProcGrowth=0 : tabs and frames run within the same process; frames are not unified across MIC levels.
TabProcGrowth =1: all tabs for a given frame process run in a single tab process for a given MIC level.
public static String openWindow(WebDriver driver, By by) throws IOException {
String parentHandle = driver.getWindowHandle(); // Save parent window
WebElement clickableElement = driver.findElement(by);
clickableElement.click(); // Open child window
WebDriverWait wait = new WebDriverWait(driver, 10); // Timeout in 10s
boolean isChildWindowOpen = wait.until(ExpectedConditions.numberOfWindowsToBe(2));
if (isChildWindowOpen) {
Set<String> handles = driver.getWindowHandles();
// Switch to child window
for (String handle : handles) {
driver.switchTo().window(handle);
if (!parentHandle.equals(handle)) {
break;
}
}
driver.manage().window().maximize();
}
return parentHandle; // Returns parent window if need to switch back
}
/* How to use method */
String parentHandle = Selenium.openWindow(driver, by);
// Do things in child window
driver.close();
// Return to parent window
driver.switchTo().window(parentHandle);
The above code includes an if-check to make sure you are not switching to the parent window as Set<T> has no guaranteed ordering in Java. WebDriverWait appears to increase the chance of success as supported by below statement.
The browser may take time to acknowledge the new window, and you may
be falling into your switchTo() loop before the popup window appears.
You automatically assume that the last window returned by
getWindowHandles() will be the last one opened. That's not necessarily
true, as they are not guaranteed to be returned in any order.
main you can do :
String mainTab = page.goToNewTab ();
//do what you want
page.backToMainPage(mainTab);
What you need to have in order to use the main
private static Set<String> windows;
//get all open windows
//return current window
public String initWindows() {
windows = new HashSet<String>();
driver.getWindowHandles().stream().forEach(n -> windows.add(n));
return driver.getWindowHandle();
}
public String getNewWindow() {
List<String> newWindow = driver.getWindowHandles().stream().filter(n -> windows.contains(n) == false)
.collect(Collectors.toList());
logger.info(newWindow.get(0));
return newWindow.get(0);
}
public String goToNewTab() {
String startWindow = driver.initWindows();
driver.findElement(By.cssSelector("XX")).click();
String newWindow = driver.getNewWindow();
driver.switchTo().window(newWindow);
return startWindow;
}
public void backToMainPage(String startWindow) {
driver.close();
driver.switchTo().window(startWindow);
}
So the problem with a lot of these solutions is you're assuming the window appears instantly (nothing happens instantly, and things happen significantly less instantly in IE). Also you're assuming that there will only be one window prior to clicking the element, which is not always the case. Also IE will not return the window handles in a predictable order. So I would do the following.
public String clickAndSwitchWindow(WebElement elementToClick, Duration
timeToWaitForWindowToAppear) {
Set<String> priorHandles = _driver.getWindowHandles();
elementToClick.click();
try {
new WebDriverWait(_driver,
timeToWaitForWindowToAppear.getSeconds()).until(
d -> {
Set<String> newHandles = d.getWindowHandles();
if (newHandles.size() > priorHandles.size()) {
for (String newHandle : newHandles) {
if (!priorHandles.contains(newHandle)) {
d.switchTo().window(newHandle);
return true;
}
}
return false;
} else {
return false;
}
});
} catch (Exception e) {
Logging.log_AndFail("Encountered error while switching to new window after clicking element " + elementToClick.toString()
+ " seeing error: \n" + e.getMessage());
}
return _driver.getWindowHandle();
}
This feature works with Selenium 4 and later versions.
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB);
// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW);