如何使用Selenium WebDriver处理ModalDialog?

14

请查看以下链接,以更好地了解如何使用selenium2.0处理模态对话框或弹出窗口。http://www.thoughtworks-studios.com/twist/2.3/help/how_do_i_handle_popup_in_selenium2.html - HemChe
@Hemanth 我知道这是一个老问题,但那个链接已经失效了;它带我到一个页面,说Twist的支持在2015年12月结束了。 - F1Krazy
@F1Krazy,是的,我写了上面的评论已经有6年了。你能告诉我这个问题的被接受的答案是否对你有帮助吗?如果没有,让我知道,我可以给你提供其他的方法。 - HemChe
9个回答

22

使用以下方法切换到模型框架

driver.switchTo().frame("ModelFrameTitle");
或者
driver.switchTo().activeElement()

希望这会奏效。


我已经尝试了两种方法,但都没有起作用。您可以尝试一下并让我知道结果吗? - Jasmine.Olivra
3
@Jasmine.Olivra,您已经接受了答案,但同时说“none of this working”。那么对您来说它是否有效? - Alex Okrushko
我正在使用Python做同样的事情,但我的语句是:driver.switch_to_window(activeElement())... 然而,我遇到了错误:driver.switch_to_window(activeElement())。你能提供一些提示吗? - engineer
@Jasmine.Olivra 如果它不起作用,那你为什么接受了这个答案? - Code Enthusiastic
1
@engineer 如果您想在Python中向活动元素发送“键”,请使用driver.switch_to.active_element.send_keys("keys")。但是,如果这是一个客户端操作系统文件对话框,我所发现的唯一互动方式就是使用此方法。 - PhilWilliammee
driver.switchTo().activeElement() :+1驱动器.switchTo().activeElement() :+1 - bugCracker

1

R语言解决方案(RSelenium):我有一个弹出对话框(动态生成),因此在原始页面源代码中无法检测到。以下是对我有效的方法:

remDr$sendKeysToActiveElement(list(key = "tab"))
Sys.sleep(5)
remDr$sendKeysToActiveElement(list(key = "enter"))
Sys.sleep(15)

date_filter_frame <- remDr$findElement(using = "tag name", 'iframe')
date_filter_frame$highlightElement()

Sys.sleep(5)

remDr$switchToFrame(date_filter_frame)

Sys.sleep(2)

date_filter_element <- remDr$findElement(using = "xpath", paste0("//*[contains(text(), 'Week to Date')]"))
date_filter_element$highlightElement()

1
尝试下面的代码。它在IE中可以工作,但在FF22中不能。 如果控制台中打印发现模态对话框,则已识别并切换模态对话框。
 public class ModalDialog {

        public static void main(String[] args) throws InterruptedException {
            // TODO Auto-generated method stub
            WebDriver driver = new InternetExplorerDriver();
            //WebDriver driver = new FirefoxDriver();
            driver.get("http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/showModalDialog2.htm");
            String parent = driver.getWindowHandle();
            WebDriverWait wait = new WebDriverWait(driver, 10);
            WebElement push_to_create = wait.until(ExpectedConditions
                    .elementToBeClickable(By
                            .cssSelector("input[value='Push To Create']")));
            push_to_create.click();
            waitForWindow(driver);
            switchToModalDialog(driver, parent);

        }

        public static void waitForWindow(WebDriver driver)
                throws InterruptedException {
            //wait until number of window handles become 2 or until 6 seconds are completed.
            int timecount = 1;
            do {
                driver.getWindowHandles();
                Thread.sleep(200);
                timecount++;
                if (timecount > 30) {
                    break;
                }
            } while (driver.getWindowHandles().size() != 2);

        }

        public static void switchToModalDialog(WebDriver driver, String parent) { 
                //Switch to Modal dialog
            if (driver.getWindowHandles().size() == 2) {
                for (String window : driver.getWindowHandles()) {
                    if (!window.equals(parent)) {
                        driver.switchTo().window(window);
                        System.out.println("Modal dialog found");
                        break;
                    }
                }
            }
        }

    }

1
你使用的不是模态对话框,而是一个独立的窗口。
请使用以下代码:
private static Object firstHandle;
private static Object lastHandle;

public static void switchToWindowsPopup() {
    Set<String> handles = DriverManager.getCurrent().getWindowHandles();
    Iterator<String> itr = handles.iterator();
    firstHandle = itr.next();
    lastHandle = firstHandle;
    while (itr.hasNext()) {
        lastHandle = itr.next();
    }
    DriverManager.getCurrent().switchTo().window(lastHandle.toString());
}

public static void switchToMainWindow() {
    DriverManager.getCurrent().switchTo().window(firstHandle.toString());

0

我已经尝试过了,它对你有效。

String mainWinHander = webDriver.getWindowHandle();

// code for clicking button to open new window is ommited

//Now the window opened. So here reture the handle with size = 2
Set<String> handles = webDriver.getWindowHandles();

for(String handle : handles)
{
    if(!mainWinHander.equals(handle))
    {
        // Here will block for ever. No exception and timeout!
        WebDriver popup = webDriver.switchTo().window(handle);
        // do something with popup
        popup.close();
    }
}

0

假设期望只是会弹出两个窗口(一个为父窗口,另一个为弹出窗口),那么只需等待两个窗口弹出,找到另一个窗口的句柄并切换到它。

WebElement link = // element that will showModalDialog()

// Click on the link, but don't wait for the document to finish
final JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript(
    "var el=arguments[0]; setTimeout(function() { el.click(); }, 100);",
  link);

// wait for there to be two windows and choose the one that is 
// not the original window
final String parentWindowHandle = driver.getWindowHandle();
new WebDriverWait(driver, 60, 1000)
    .until(new Function<WebDriver, Boolean>() {
    @Override
    public Boolean apply(final WebDriver driver) {
        final String[] windowHandles =
            driver.getWindowHandles().toArray(new String[0]);
        if (windowHandles.length != 2) {
            return false;
        }
        if (windowHandles[0].equals(parentWindowHandle)) {
            driver.switchTo().window(windowHandles[1]);
        } else {
            driver.switchTo().window(windowHandles[0]);
        }
        return true;
    }
});

0

不对,模态窗口需要由JavaScriptExecutor处理,因为大多数模态窗口是由窗口模型构成的。一旦模态窗口出现,控制权就会转移到模态窗口并单击预期的元素。

必须要导入 javascriptexector

例如下面这样:

Javascriptexecutor js =(Javascriptexecutor).driver;
js.executescript(**<element to be clicked>**);

0

尝试使用这段代码,包括您的对象名称和变量以使其正常工作。

Set<String> windowids = driver.getWindowHandles();
Iterator<String> iter= windowids.iterator();
for (int i = 1; i < sh.getRows(); i++)
{   
while(iter.hasNext())
{
System.out.println("Main Window ID :"+iter.next());
}
driver.findElement(By.id("lgnLogin_UserName")).clear();
driver.findElement(By.id("lgnLogin_UserName")).sendKeys(sh.getCell(0, 
i).getContents());
driver.findElement(By.id("lgnLogin_Password")).clear();
driver.findElement(By.id("lgnLogin_Password")).sendKeys(sh.getCell(1, 
i).getContents());
driver.findElement(By.id("lgnLogin_LoginButton")).click();
Thread.sleep(5000L);
            windowids = driver.getWindowHandles();
    iter= windowids.iterator();
    String main_windowID=iter.next();
    String tabbed_windowID=iter.next();
    System.out.println("Main Window ID :"+main_windowID);
    //switch over to pop-up window
    Thread.sleep(1000);
    driver.switchTo().window(tabbed_windowID);
    System.out.println("Pop-up window Title : "+driver.getTitle());

0

附言1:即使这个问题太旧了,我也要发表我的意见。

    public void PressEnterKey()
    {
        var simulator = new InputSimulator();
        simulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
    }

你可以创建一个类似上面的方法,并在需要的地方调用它。
附注2 - 你也可以更改键盘输入(如向上箭头、向下箭头、向下翻页等)。

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