【发布时间】:2012-03-24 05:37:06
【问题描述】:
我有这样的情况,当点击按钮打开带有搜索结果的新浏览器窗口时。
有什么方法可以连接并关注新打开的浏览器窗口吗?
并使用它,然后返回原始(第一个)窗口。
【问题讨论】:
-
我们可以自动切换 - 在这里查看高级用法 - testautomationguru.com/…
标签: java selenium selenium-webdriver webdriver new-window
我有这样的情况,当点击按钮打开带有搜索结果的新浏览器窗口时。
有什么方法可以连接并关注新打开的浏览器窗口吗?
并使用它,然后返回原始(第一个)窗口。
【问题讨论】:
标签: java selenium selenium-webdriver webdriver new-window
你可以使用:
driver.SwitchTo().Window(WindowName);
其中 WindowName 是一个字符串,表示您要将焦点切换到的窗口的名称。完成后使用原始窗口的名称再次调用此函数以返回它。
【讨论】:
您可以在以下窗口之间切换:
// 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)
【讨论】:
getWindowHandles() 返回一个 Set 和 a Set does not guarantee ordering。最后一个元素并不总是最后一个窗口。我很惊讶他的评论得到了很多支持。
getWindowHandles()。这是该方法的已知行为(不是错误),尤其是 Java SetswitchTo().window(handles[handles.length-1]) 在 Java 中无法保证。不能声称 C# 解决方案是正确的。我使用迭代器和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);
}
【讨论】:
Surya,你的方式行不通,原因有二:
【讨论】:
只是为了添加内容...
返回主窗口(默认窗口)。
使用driver.switchTo().defaultContent();
【讨论】:
此脚本可帮助您从 父窗口 切换到 子窗口 并返回 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
}
}
【讨论】:
如果您有多个浏览器(使用 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);
}
}
【讨论】:
来源: Selenium WebDriver windows switching issue in Internet Explorer 8-10
就我而言,IE 在注册表编辑后开始检测新窗口句柄。
标签进程增长:设置 IE 创建新标签进程的速率。
“Max-Number”算法:它指定在特定强制完整性级别 (MIC) 下,对于单个框架进程的单个隔离会话可以执行的选项卡进程的最大数量。相对值是:
- TabProcGrowth=0:标签和框架在同一个进程中运行; MIC 级别的框架没有统一。
- TabProcGrowth =1:给定框架进程的所有选项卡在给定 MIC 级别的单个选项卡进程中运行。
来源: Opening a New Tab may launch a New Process with Internet Explorer 8.0
浏览器: 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 检查,以确保您没有切换到 Set<T> has no guaranteed ordering in Java 的父窗口。 WebDriverWait 似乎增加了成功的机会,如下所述。
浏览器可能需要一些时间来确认新窗口,您可以 在弹出窗口出现之前进入你的 switchTo() 循环。
你会自动假设最后一个窗口返回 getWindowHandles() 将是最后一个打开的。那不一定 是的,因为它们不能保证按任何顺序返回。
来源:Unable to handle a popup in IE,control is not transferring to popup window
【讨论】:
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);
}
【讨论】:
因此,很多这些解决方案的问题是您假设窗口立即出现(没有立即发生,而在 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();
}
【讨论】:
此功能适用于 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);
【讨论】: