如何切换到单击按钮后打开的新浏览器窗口?

时间:2012-03-06 17:29:37

标签: java selenium selenium-webdriver webdriver new-window

我有情况,当点击按钮打开带有搜索结果的新浏览器窗口时。

有没有办法连接并关注新打开的浏览器窗口?

使用它,然后返回到原始(第一个)窗口。

11 个答案:

答案 0 :(得分:97)

您可以在窗口之间切换,如下所示:

// 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)

答案 1 :(得分:11)

只是添加内容......

返回主窗口(默认窗口)。

使用driver.switchTo().defaultContent();

答案 2 :(得分:10)

此脚本可帮助您从父窗口切换到子窗口,然后将cntrl切换回父窗口

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

答案 3 :(得分:3)

苏里亚,你的方式不行,原因有二:

  1. 在评估测试时你无法关闭驱动程序,因为它将失去焦点,然后切换到活动元素,你将获得NoSuchWindowException。
  2. 如果在ChromeDriver上运行测试,则不会显示窗口,而是在应用程序中单击选项卡。由于 SeleniumDriver无法使用标签,只能在窗口之间切换,它会在新标签正在打开的位置单击,并在超时时崩溃。

答案 4 :(得分:2)

我使用iterator和while循环来存储各种窗口句柄,然后来回切换。

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

答案 5 :(得分:2)

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:

答案 6 :(得分:1)

您可以使用:

driver.SwitchTo().Window(WindowName);

其中WindowName是一个字符串,表示要将焦点切换到的窗口的名称。再次使用原始窗口的名称调用此函数,以便在完成后返回该功能。

答案 7 :(得分: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);
            }

答案 8 :(得分:0)

因此,许多这些解决方案的问题在于您假设窗口立即显示(没有任何事情立即发生,并且IE中的事情发生的时间明显减少)。此外,您假设在单击元素之前只有一个窗口,但情况并非总是如此。 IE也不会以可预测的顺序返回窗口句柄。所以我会做以下事情。

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

答案 9 :(得分:-1)

如果您有多个浏览器(使用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);
  }

}

答案 10 :(得分:-2)

我喜欢使用页面对象控制自动窗口切换的方式。

当有多个窗口打开时,此页面对象中的任何方法都将在具有匹配标题的浏览器窗口上执行。

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

    // your page object code

}

点击此处查看详细步骤 - http://www.testautomationguru.com/selenium-webdriver-automatic-switching-between-browser-windows-using-guice-method-interceptor/

相关问题