By Volodymyr Prysiazhniuk


2012-03-06 17:29:37 8 Comments

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.

11 comments

@Dominic Giallombardo 2018-05-27 02:03:45

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();
}

@silver 2017-08-13 14:07:30

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:

@Ran Adler 2018-01-10 09:09:25

 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);
            }

@vins 2017-06-06 22:20:08

I like the way of automatic windows switching which i could control using the page objects.

When there are multiple windows open, any method from this page object, will get executed on a browser window which has the matching title.

@Window(".* some windows title goes here .*")
public class ToolsQANewWindow {

    // your page object code

}

Check here for the detailed steps - http://www.testautomationguru.com/selenium-webdriver-automatic-switching-between-browser-windows-using-guice-method-interceptor/

@silver 2017-08-13 14:10:24

You simply linked to a webpage. Your code snippet is not of any much help.

@Surya 2012-03-07 07:59:41

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)

@silver 2017-08-13 10:13:27

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.

@Elmue 2017-08-14 03:34:27

@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.

@silver 2017-08-26 03:23:50

@Elmue 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.

@Elmue 2017-08-26 18:21:05

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!

@silver 2017-08-27 04:56:15

@Elmue 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.

@Elmue 2017-08-28 16:28:26

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?

@silver 2017-08-28 18:07:46

@Elmue 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.

@silver 2017-08-28 18:12:10

@Elmue 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.

@EPadronU 2017-10-23 16:41:50

Quick question: if the implementation is in fact a LinkedHashSet, shouldn't that means that the order is preserved?

@joshmcode 2018-03-23 18:11:10

@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: stackoverflow.com/a/40337065/3757322

@Keith Tyler 2018-08-01 18:45:40

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?

@Ran Adler 2014-10-06 12:08:20

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);
  }

}

@Prashanth Sams 2013-06-24 12:26:57

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
          }
       }

@Ripon Al Wasim 2016-02-25 12:41:54

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.CON‌​TROL + "w");

@user1999663 2013-01-22 09:03:17

Just to add to the content ...

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

use driver.switchTo().defaultContent();

@Invy 2012-07-31 10:20:54

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.

@Ben 2014-02-26 00:02:10

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.

@Ben 2015-12-07 23:23:01

@Elmue 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.

@Elmue 2015-12-10 16:28:13

I was wrong and deleted my comment. You can delete your answer too.

@StatusQuo 2012-06-01 21:28:08

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);
            }

@paul 2014-06-25 08:39:00

It is failing to switch to new tabs, however it performs clicks on desired new tab. Why?

@Hugo 2015-10-20 07:42:04

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 newwin

@Breeze91 2012-03-06 19:38:08

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.

@Volodymyr Prysiazhniuk 2012-03-07 06:34:05

thank you for suggestion, is there any way, how I can set window name mask? Like "WinName*", where * - any symbol.

@Volodymyr Prysiazhniuk 2012-03-07 06:50:03

My implicitly is 10 seconds, but in 2 sec's it gives me exception NoSuchWindowException.

Related Questions

Sponsored Content

32 Answered Questions

39 Answered Questions

[SOLVED] Can't start Eclipse - Java was started but returned exit code=13

9 Answered Questions

2 Answered Questions

[SOLVED] Switch to new browser opened after click on a button [Python][Selenium]

1 Answered Questions

Not able to click on a button in a new window

  • 2015-10-01 20:05:13
  • AJIMUDDIN
  • 194 View
  • 1 Score
  • 1 Answer
  • Tags:   selenium webdriver

1 Answered Questions

Cannot Switch to new browser Window after click button C# Selenium

  • 2015-07-29 10:23:59
  • Екатерина Швырева
  • 245 View
  • 0 Score
  • 1 Answer
  • Tags:   c# selenium

1 Answered Questions

[SOLVED] Open new window after click button

2 Answered Questions

[SOLVED] How can we switch to new opened tab with webdriver

1 Answered Questions

1 Answered Questions

Sponsored Content