Selenium:在javascript代码中关闭棘手的javascript弹出窗口

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Selenium:在javascript代码中关闭棘手的javascript弹出窗口相关的知识,希望对你有一定的参考价值。

我知道如何用Selenium关闭弹出窗口,但这个非常棘手。这是发生了什么。单击按钮后会打开此弹出窗口。当我执行此代码时:

WebElement button = driver.findElement(...);
log.info("step 1");
button.click();
log.info("step 2");
Alert alert = driver.switchTo().alert();
alert.accept();
WebElement nextButton = driver.findElement(...);
nextButton.click();

第2步部分未出现在日志中。单击后Eclipse会冻结,但单击完成后会在页面上显示以下弹出窗口。

这就是我认为发生的事情。该按钮实际上有以下javascript onclick代码:

continueButton();return;

现在弹出窗口在continueButton()函数内启动。

所以我想我的java代码只是冻结在这里等待Javascript完成这个功能并执行上面的返回。但是由于有这个弹出窗口阻止javascript进行,我实际上无法关闭窗口,因为我无法关闭窗口。如果我手动执行,则在日志中显示第2步,并继续执行java代码。

有没有办法解决这个问题,因为我无法更改页面源代码?

我试过的是分别执行javascript部分;而不是点击:

jsexecutor.execute("continueButton();")
log.info("step 1");
Alert alert = driver.switchTo().alert();
alert.accept();
jsexecutor.execute("return;")

但这完全符合相同的行为。弹出窗口显示但步骤1不在日志中,因此java执行只是卡住了。

答案

当你调用switchTo().alert()时,你需要处理某些事实,然后当你调用findElement(...)来调用click()上的nextbutton时,你需要处理它。当调用JS Alert时,你必须等待Alerthtml中正确渲染。类似地,一旦你AcceptAlert你必须等待预定的按钮是clickable如下:

log.info("step 1");
driver.findElement(By.xpath("xpathExpression_of_button")).click();
new WebDriverWait(driver,5).until(ExpectedConditions.alertIsPresent());
log.info("step 2");
driver.switchTo().alert().accept();
new WebDriverWait(driver,5).until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath("xpathExpression_of_nextButton")))).click();
另一答案

最后这是我的解决方案。在进行触发弹出窗口并阻止我的代码的点击之前,我创建一个等待几秒钟的线程,然后获取弹出窗口并单击它的关闭按钮:

    DelayedClicker delayedClicker = new DelayedClicker(getDriver(),
            xpath, 30, log,
            EnumXpath.POPUP_WINDOW_TITLE, null);
    delayedClicker.start();
    WebElement button = getDriver()
            .findElement(...)));
    button.click();

在线程中

    Thread.sleep(delay * 1000);
    if (windowTitle != null)
        switchWindowByTitle(windowTitle);
    if (frameTitle != null)
        switchFrameByTitle(frameTitle);
    WebElement button = driver.findElement(By.xpath(xpath));
    button.click();

当然,在两个不同的线程中使用相同的webdriver是完全混乱的,但在这种情况下它似乎是唯一的方法。在我的代码被阻止之前,我启动了Thread。然后线程杀死弹出窗口,从而解锁代码并消失。

以上是关于Selenium:在javascript代码中关闭棘手的javascript弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何在 selenium 3 中关闭 Marionette/gecko 驱动程序日志

如何在 Python / Selenium 中关闭麦克风/相机弹出窗口?

目标窗口在硒中关闭

Windows处理如果我尝试在python中关闭当前窗口,则关闭整个浏览器

在JavaScript中关闭窗口

如何阻止用户在 Javascript 中关闭窗口?