How to switch to the new browser window, which opens after click on the button?
Asked Answered
I

12

96

I have situation, when click on button opens the new browser window with search results.

Is there any way to connect and focus to new opened browser window?

And work with it, then return back to original (first) window.

Impetus answered 6/3, 2012 at 17:29 Comment(1)
We can do the switch automatically - check here for the advanced usage - testautomationguru.com/…Alcoholize
C
133

You can switch between windows as below:

// 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)
Colleague answered 7/3, 2012 at 7:59 Comment(12)
I can confirm accepted solution consistently works in Chrome but not in IE. The new window handle is not recognized in IE. @Elmue is incorrect because getWindowHandles() returns a Set and a Set does not guarantee ordering. The last element is not always the last window. I am surprised his comment gets a lot of upvotes.Sean
@silver: I have no idea what you are talking about. In my code WindowHandles returns a ReadOnlyCollection<string> for which I can guarantee that the last entry is always the latest opened window. I tested that. If this works perfectly in C#, but is implemented wrongly in Java you should report that as a bug.Flathead
@Flathead This is a Java thread. Please read Luke's (Selenium developer) response regarding getWindowHandles(). It is a known behavior (not bug) of the method and the Java Set<T> in particular. Therefore, switchTo().window(handles[handles.length-1]) is not guaranteed in Java. A C# solution cannot be claimed to be correct.Sean
The comment of Luke does not say anything new. "You cannot assume that the last window returned by getWindowHandles() will be the last one opened". This clearly says that this is a msidesign in Java. Why not report this as a bug so they fix it? How do I get the LAST OPENED window in Java then? At least this page has no usefull answer! It is simply a shame for Selenium (like a lot of other misdesigns). "A C# solution cannot be claimed to be correct." A very clever comment! C# works but it is not correct. Java does not work, but you defend the misdesign!Flathead
@Flathead That's a known behavior of the Java Set<T>, it's the LinkedHashSet<T> that retains insertion order. Seeing getWindowHandles() simply returns a Set<T>, it's a FACT it has no order. Getting the last opened window by chance doesn't mean that's what it actually does. This will become more important when you have more than just 2 windows open. Your solution may work in C#, but again, this is a Java question. Your answer is invalid for this thread.Sean
Well, I see that Iam wasting my time here. You still did not understand. Why does Java code return a Set<T>? There are other containers in Java that can be used instead, which maintain the order. If Selenium folks fix this, it will work in C# AND in Java. Is this really so difficult to understand?Flathead
@Flathead For the 3rd (and final) time, your answer is false for Java as supported by docs and dev which can MISLEAD people. Post an answer where you say it's for C#, no problem. Raise an issue card in GitHub for Java, go ahead. Simply your answer is not applicable for the language TAGGED in the thread and people may think otherwise. If you cannot make the distinction, your comprehension is lacking.Sean
@Flathead By the way, you are also wrong in saying driver.close() closes both windows. It only closes the current. driver.quit() kills all instances. I can see somebody already pointed this out to you. Your comment is full of mistakes. Have a good day.Sean
Quick question: if the implementation is in fact a LinkedHashSet, shouldn't that means that the order is preserved?Phebe
@silver You have to change the IE security settings and then I was able to make this work in IE. Take a look at this answer here: https://mcmap.net/q/219342/-unable-to-get-new-window-handle-with-selenium-webdriver-in-java-on-ieNewbold
I see this code used for this problem, but it looks to me like it will switch to all other windows and ultimately settle on the one that comes last in the getWindowHandles() iterator. But where does it say that getWindowHandles() iterator reliably returns handles in order of creation?Tereus
How do we handle if I open a new browser throught another instance? Instead of clicking the buttonAgeold
A
13

Just to add to the content ...

To go back to the main window(default window) .

use driver.switchTo().defaultContent();

Anywheres answered 22/1, 2013 at 9:3 Comment(0)
I
12

This script helps you to switch over from a Parent window to a Child window and back cntrl to Parent window

String parentWindow = driver.getWindowHandle();
Set<String> handles =  driver.getWindowHandles();
   for(String windowHandle  : handles)
       {
       if(!windowHandle.equals(parentWindow))
          {
          driver.switchTo().window(windowHandle);
         <!--Perform your operation here for new window-->
         driver.close(); //closing child window
         driver.switchTo().window(parentWindow); //cntrl to parent window
          }
       }
Ibeam answered 24/6, 2013 at 12:26 Comment(1)
driver.close() will work for new window. If it is new Tab then use the code to close the new tab: driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "w");Selfeffacement
P
3

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);
            }
Presidentship answered 1/6, 2012 at 21:28 Comment(2)
It is failing to switch to new tabs, however it performs clicks on desired new tab. Why?Canova
is there any reason this code may cause the test to become very slow? It seems that after this bit of code it takes about 10 minutes to perform any actions in the newwinGorham
D
3

Surya, your way won't work, because of two reasons:

  1. you can't close driver during evaluation of test as it will loose focus, before switching to active element, and you'll get NoSuchWindowException.
  2. 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.
Decompose answered 31/7, 2012 at 10:20 Comment(3)
You can actually use the call for driver.close() since you are switching window handles on the driver and calling for the window that you are currently on to close. I use it regularly in my code when dealing with multiple windows. driver.Quit() is the call that will kill the test. In Chromedriver you can still call for getWindowHandles() to get your list of available windows. I cant think of a reason to use a tab in a web test.Mctyre
@Flathead The original question stated that a click opens up a second window creating a multiple window handles. I can make the call driver.close(); and have my window that currently has focus close. I can then switch to any other active window of my choosing. driver.close() and driver.quit() do not share the same functionality. A call for driver.quit() will kill the active driver instance whereas close only kills the current window handle. Also, I have yet to see any call that solely opens a tab after a click is called when the javascript on the website creates a new window.Mctyre
I was wrong and deleted my comment. You can delete your answer too.Flathead
S
3

Modify registry for IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
  2. Right-click → New → String Value → Value name: TabProcGrowth (create if not exist)
  3. TabProcGrowth (right-click) → Modify... → Value data: 0

Source: Selenium WebDriver windows switching issue in Internet Explorer 8-10

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.

Source: Opening a New Tab may launch a New Process with Internet Explorer 8.0


Internet Options:

  • Security → Untick Enable Protected Mode for all zones (Internet, Local intranet, Trusted sites, Restricted sites)
  • Advanced → Security → Untick Enable Enhanced Protected Mode

Code:

Browser: IE11 x64 (Zoom: 100%)
OS: Windows 7 x64
Selenium: 3.5.1
WebDriver: IEDriverServer x64 3.5.1

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.

Quoted from Luke Inman-Semerau: (Developer for Selenium)

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.

Source: Unable to handle a popup in IE,control is not transferring to popup window


Related Posts:

Sean answered 13/8, 2017 at 14:7 Comment(0)
B
2

You could use:

driver.SwitchTo().Window(WindowName);

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.

Bunny answered 6/3, 2012 at 19:38 Comment(2)
thank you for suggestion, is there any way, how I can set window name mask? Like "WinName*", where * - any symbol.Impetus
My implicitly is 10 seconds, but in 2 sec's it gives me exception NoSuchWindowException.Impetus
C
0
 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);
            }
Choir answered 10/1, 2018 at 9:9 Comment(0)
T
0

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();
}
Telmatelo answered 27/5, 2018 at 2:3 Comment(0)
C
0

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);
Cattery answered 9/11, 2021 at 5:51 Comment(0)
A
0

Here is the Python version,

#Store the current window handle
win_handle_before = driver.current_window_handle

#Perform the click operation that opens new window


#Switch to new window opened
for win_handle in driver.window_handles:
    driver.switch_to.window(win_handle)

#Perform the actions on new window


#Close the new window, if that window no more required
driver.close()

#Switch back to the original browser (first window)
driver.switch_to.window(win_handle_before)

#Continue with original browser (first window)
Airboat answered 20/3, 2023 at 4:38 Comment(0)
C
-1

If you have more then one browser (using java 8)

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TestLink {

  private static Set<String> windows;

  public static void main(String[] args) {

    WebDriver driver = new FirefoxDriver();
    driver.get("file:///C:/Users/radler/Desktop/myLink.html");
    setWindows(driver);
    driver.findElement(By.xpath("//body/a")).click();
    // get new window
    String newWindow = getWindow(driver);
    driver.switchTo().window(newWindow);

    // Perform the actions on new window
    String text = driver.findElement(By.cssSelector(".active")).getText();
    System.out.println(text);

    driver.close();
    // Switch back
    driver.switchTo().window(windows.iterator().next());


    driver.findElement(By.xpath("//body/a")).click();

  }

  private static void setWindows(WebDriver driver) {
    windows = new HashSet<String>();
    driver.getWindowHandles().stream().forEach(n -> windows.add(n));
  }

  private static String getWindow(WebDriver driver) {
    List<String> newWindow = driver.getWindowHandles().stream()
        .filter(n -> windows.contains(n) == false).collect(Collectors.toList());
    System.out.println(newWindow.get(0));
    return newWindow.get(0);
  }

}
Choir answered 6/10, 2014 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.