93

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

有什么方法可以连接并关注新打开的浏览器窗口?

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

4

11 回答 11

127

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

// 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)
于 2012-03-07T07:59:41.630 回答
13

只是为了增加内容......

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

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

于 2013-01-22T09:03:17.297 回答
12

此脚本可帮助您从父窗口切换到子窗口并返回 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
          }
       }
于 2013-06-24T12:26:57.287 回答
3

Surya,你的方式行不通,原因有二:

  1. 你不能在测试评估期间关闭驱动程序,因为它会在切换到活动元素之前失去焦点,你会得到 NoSuchWindowException。
  2. 如果在 ChromeDriver 上运行测试,您将不会看到一个窗口,而是在您的应用程序中单击选项卡。由于SeleniumDriver 不能与 tabs 一起使用,只能在窗口之间切换,它会在单击打开新选项卡的位置时挂起,并在超时时崩溃。
于 2012-07-31T10:20:54.267 回答
3

修改 IE 的注册表:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
  2. 右键→新建→字符串值→值名称:TabProcGrowth(如果不存在则创建)
  3. TabProcGrowth(右键单击)→修改...→数值数据:0

来源: Internet Explorer 8-10 中的 Selenium WebDriver 窗口切换问题

就我而言,IE 在注册表编辑后开始检测新的窗口句柄。

取自 MSDN 博客:

选项卡进程增长:设置 IE 创建新选项卡进程的速率。

“Max-Number”算法:这指定了在特定强制完整性级别 (MIC) 的单个帧进程的单个隔离会话可以执行的最大选项卡进程数。相对值是:

  • TabProcGrowth=0 :标签和框架在同一个进程中运行;MIC 级别的帧不统一。
  • TabProcGrowth =1:给定框架进程的所有选项卡在给定 MIC 级别的单个选项卡进程中运行。

来源: 打开新选项卡可能会使用 Internet Explorer 8.0 启动新进程


互联网选项:

  • 安全 → 取消勾选为所有区域启用保护模式(Internet、本地 Intranet、受信任站点、受限站点)
  • 高级→安全→取消勾选启用增强保护模式

代码:

浏览器: IE11 x64(缩放:100%)
操作系统: 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);

上面的代码包含一个 if-check 以确保您没有切换到父窗口,因为Set<T>在 Java 中没有保证顺序WebDriverWait正如以下陈述所支持的那样,似乎增加了成功的机会。

引自Luke Inman-Semerau:(Selenium 开发人员)

浏览器可能需要一些时间来确认新窗口,并且您可能会在弹出窗口出现之前陷入您的 switchTo() 循环。

您自动假定 getWindowHandles() 返回的最后一个窗口将是最后一个打开的窗口。这不一定是真的,因为它们不能保证以任何顺序返回。

来源: 无法处理 IE 中的弹出窗口,控件未转移到弹出窗口


相关文章:

于 2017-08-13T14:07:30.133 回答
2

你可以使用:

driver.SwitchTo().Window(WindowName);

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

于 2012-03-06T19:38:08.603 回答
2

我使用迭代器和 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);
            }
于 2012-06-01T21:28:08.313 回答
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();
}
于 2018-05-27T02:03:45.367 回答
0

此功能适用于 Selenium 4 及更高版本。

// 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);
于 2021-11-09T05:51:56.403 回答
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);
            }
于 2018-01-10T09:09:25.213 回答
-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);
  }

}
于 2014-10-06T12:08:20.263 回答