使用Selenium处理弹出窗口

8

我有一个情况,点击链接网页会打开一个弹出窗口。在弹出窗口打开后,焦点在弹出窗口中,主窗口被禁用。我无法将控件转移到弹出窗口。 请查看以下代码。

driver.findElement(By.linkText("Click me")).click();// when this line of code is reached then a popup window opens.

System.out.println("After Clicking me"); // After the popup window opens this line of code is never executed.

我无法将控制权从父窗口转移到弹出窗口。 我知道以下命令。

driver.switchTo().window("popup window");

但这并没有太大帮助。请帮我一下。
4个回答

10
这是我在处理弹出窗口并关闭它返回主窗口时使用的代码。当然,这里为了回答问题而进行了简化。它保留了原始窗口(主窗口)的句柄,以便区分其他窗口。
由于本开发者在开发过程中曾遇到代码在窗口实际打开之前运行的问题,因此需要使用显式的 WebDriverWait。这可能不是一个理想的情况。
function manipulatePopUp(final WebDriver driver, final WebDriverWait wait) {
    final String mainWindowHandle = driver.getWindowHandle();
    driver.findElement(By.id("linkThatOpensPopUp")).click();

    wait.until(new ExpectedConditions<Boolean>() {
        @Override
        public Boolean apply(WebDriver d) {
            return (d.getWindowHandles().size() != 1);
        }
    });

    for (String activeHandle : driver.getWindowHandles()) {
        if (!activeHandle.equals(mainWindowHandle)) {
            driver.switchTo().window(activeHandle);
        }
    }

    driver.close();
    driver.switchTo().window(mainWindowHandle);
}

请问您能否更详细地解释一下wait.until方法的语法和其中的逻辑? - Code Enthusiastic
1
顺便提一下,driver.getWindowHandles() 返回的是一个 Set 而不是 List。 - Code Enthusiastic
等待基本上会不断循环,直到驱动程序具有多个句柄,从而为我提供适当的时间来确保弹出窗口现在已准备好进行交互。 - aimbire
这是一种舒适的方式,可以确保一旦进入for()循环,它将一直循环,直到找到一个不是我的主窗口为止。 - aimbire
+1 非常优雅。只有几个错别字:应该是新的 ExpectedCondition(单数)。上面的评论是正确的,我使用了 for (Iterator<String> it = driver.getWindowHandles().iterator(); it.hasNext(); ) { ... } - kcostilow

9

driver.findElement(By.linkText("点击我")).click();// 当执行到这行代码时,会弹出一个窗口。

System.out.println("点击后"); // 弹出窗口后,此行代码不会被执行。

这行代码不会被执行,因为程序正在等待处理弹出的窗口。

在这种情况下,getWindowHandles()函数可以正常工作。

例子:

//handle of the master window before clicking the link
String master = driver.getWindowHandle();

driver.findElement(By.linkText("Click me")).click();

//logic for waiting for the popup, checking the size to become greater than 1 or breaking after sometime to avoid the infinite loop.
int timeCount = 1;

do
{
   driver.getWindowHandles();
   Thread.sleep(200);
   timeCount++;
   if ( timeCount > 50 ) 
   {
       break;
   }
}
while ( driver.getWindowHandles().size == 1 );

//Assigning the handles to a set
Set<String> handles = driver.getWindowHandles();
//Switching to the popup window.
for ( String handle : handles )
{
    if(!handle.equals(master))
    {
         driver.switchTo().window(handle);
    }
}

现在驱动程序已切换到弹出窗口。如果弹出窗口有一个框架,则在识别其中的元素之前需要先切换到该框架。


0
public class socialSignOn extends masterBaseClassNewSiteStage {

    @Test
    public void testSocialSignOn() throws Throwable {
        openParticularUrl("/my-lfc/join/user-details?user_type=free");

        driver.findElement(By.cssSelector("#socialSignOn > div.left.socialLogin.googleButton")).click();

        String MainWindow = driver.getWindowHandle();

        for (String activeHandle : driver.getWindowHandles()) {
            if (!activeHandle.equals(MainWindow)) {
                driver.switchTo().window(activeHandle);
            }
        }
        driver.findElement(By.cssSelector("#Email")).sendKeys("");
        driver.findElement(By.cssSelector("#next")).click();
        pauseFiveSeconds();
        driver.findElement(By.cssSelector("#Passwd")).sendKeys("");
        driver.findElement(By.cssSelector("#signIn")).click();
        pauseOneSecond();
        driver.switchTo().window(MainWindow);
        pauseTenSeconds();
        closeDriver();
    }
}

-1
// delay : max number of seconds
new WebDriverWait(driver, delay * 1000).until(ExpectedConditions.alertIsPresent());
drive`enter code here`r.switchTo().alert().accept();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接