在经过测试的Web应用程序中,弹出了几个屏幕。在几个测试中,我们最终得到三个浏览器窗口,因此还有三个Driver.WindowHandles。
要从一个WindowHandle切换到另一个WindowHandle,我们希望将Driver.WindowHandles排序为最旧的窗口优先,最新的窗口最后。但是事实并非如此:这完全是随机的!
因为windowhandle是GUID,所以我们最终以WindowHandle GUID为键创建了一个字典,并使用了浏览器窗口中加载的页面类型的值。
但这也会导致例如在关闭窗口时维护字典。
对于如此简单的事情,这似乎需要大量工作。有更好的解决方案吗?
#1 楼
您说的很正确:WindowHandles的排序方式将像最旧的窗口在前,最新的窗口在后。但这不是事实:这是完全随机的!
在一次讨论中,Simon明确提到:
While the datatype used for storing the list of handles may be ordered by insertion, the order in which the WebDriver implementation iterates over the window handles to insert them has no requirement to be stable. The ordering is arbitrary.
因此,我们将在每次打开新标签页/窗口时引入
WebDriverWait
,然后收集窗口句柄,并最终根据需要遍历窗口句柄和switchTo().window(newly_opened)
:如果需要,请调整
Test Environment
[我的配置-Selenium
:3.5.3,IEDriverServer
:3.5.0.0(64位),IE
:v10.0)Java :
package demo;
import java.util.Iterator;
import java.util.Set;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class NEW_TAB_Handling {
public static void main(String[] args) {
System.setProperty("webdriver.ie.driver", "C:\Utility\BrowserDrivers\IEDriverServer.exe");
WebDriver driver = new InternetExplorerDriver();
driver.get("http://www.google.com");
String first_tab = driver.getWindowHandle();
System.out.println("Working on Google");
((JavascriptExecutor) driver).executeScript("window.open('http://facebook.com/');");
WebDriverWait wait = new WebDriverWait(driver,5);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
Set<String> s1 = driver.getWindowHandles();
Iterator<String> i1 = s1.iterator();
while(i1.hasNext())
{
String next_tab = i1.next();
if (!first_tab.equalsIgnoreCase(next_tab))
{
driver.switchTo().window(next_tab);
System.out.println("Working on Facebook");
}
}
String second_tab = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open('http://youtube.com/');");
wait.until(ExpectedConditions.numberOfWindowsToBe(3));
Set<String> s2 = driver.getWindowHandles();
Iterator<String> i2 = s2.iterator();
while(i2.hasNext())
{
String next_tab = i2.next();
if (!first_tab.equalsIgnoreCase(next_tab) && !second_tab.equalsIgnoreCase(next_tab))
{
driver.switchTo().window(next_tab);
System.out.println("Working on Youtube");
}
}
driver.quit();
System.out.println("Quit the WebDriver instance");
}
}
控制台输出:
Working on Google
Working on Facebook
Working on Youtube
Quit the WebDriver instance
Outro
>您可以在新标签Selenium + Python中的Open web中找到基于python的讨论
评论
谢谢您的回答。但是,当有第三个或第四个窗口时,它如何工作?
–科恩·迈耶(Koen Meijer)
17年9月21日在18:21
嗨Debanjan,我最初的问题是关于3个窗口句柄。因此,我不能接受您的答案作为答案。我知道您可以在两个窗口句柄之间切换,但棘手的部分是当有两个以上的句柄时。
–科恩·迈耶(Koen Meijer)
17年9月21日在18:45
@KoenMeijer更新了“如何处理3个窗口句柄”的答案。让我知道是否能回答您的问题。
– DebanjanB
17年9月22日在7:40
谢谢Debanjan,所以您还必须跟踪对象中的所有WindowHandles。并且当您关闭窗口时,您还必须移除winodwhandle。在我看来,这很简单,需要做很多工作。这个问题还没有其他解决方案吗?
–科恩·迈耶(Koen Meijer)
17年9月23日14:41在
评论
我对C#不太熟悉,但是可以通过Java构造答案。可以满足您的问题吗?是的,没问题。