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

问题描述 投票:0回答:12

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

有什么方法可以连接并聚焦到新打开的浏览器窗口吗?

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

java selenium-webdriver webdriver new-window
12个回答
131
投票

您可以按如下方式在窗口之间切换:

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

13
投票

只是为了添加内容...

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

使用

driver.switchTo().defaultContent();


12
投票

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

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
投票

我使用迭代器和 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);
            }

3
投票

Surya,你的方法行不通,因为两个原因:

  1. 在测试评估期间无法关闭驱动程序,因为在切换到活动元素之前它将失去焦点,并且您将得到 NoSuchWindowException。
  2. 如果在 ChromeDriver 上运行测试,您将不会得到一个窗口,而是在应用程序中单击时得到的选项卡。由于 SeleniumDriver 无法使用选项卡,只能在窗口之间切换,因此它会在单击打开新选项卡时挂起,并在超时时崩溃。

3
投票

修改 IE 注册表:

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

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

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

摘自 MSDN 博客:

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

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

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

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


互联网选项:

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

代码:

浏览器: IE11 x64(缩放:100%)
操作系统:Windows 7 x64
硒: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 检查,以确保您不会切换到父窗口,因为 

Set<T>

 在 Java 中没有保证顺序
WebDriverWait
 似乎增加了成功的机会,如下文所述。

引自

Luke Inman-Semerau:(Selenium 开发者)

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

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

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


相关帖子:

  • Selenium 切换到新选项卡 IE
  • 如何使用 selenium (java) 在 IE 中打开新选项卡并在中打开 url 该选项卡(不是 窗)

2
投票
您可以使用:

driver.SwitchTo().Window(WindowName);

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


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

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

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

0
投票
这是

Python版本,

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

-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); } }
    
© www.soinside.com 2019 - 2024. All rights reserved.