切换到新窗口并再次访问java中的相同窗口(selenium webdriver)

时间:2013-10-15 06:35:26

标签: java selenium

String Parentwindow = driver.getWindowHandle();

driver.findElement(By.xpath("//*[@id='ImageButton5']")).click();
Thread.sleep(3000);

for(String winHandle : driver.getWindowHandles())
{
    driver.switchTo().window(winHandle);
    Thread.sleep(3000);
}
System.out.println("Title of the page after - switchingTo: " + driver.getTitle());

driver.findElement(By.id("txtEnterCptCode")).sendKeys("99219");
//Thread.sleep(3000);
driver.findElement(By.id("btnSearch")).click();

我正在使用此代码切换到新窗口。但它显示错误:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to find element with id == txtEnterCptCode (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 351 milliseconds

任何人都可以帮助我。

2 个答案:

答案 0 :(得分:2)

通过调用getWindowHandles()返回的Windows句柄不保证按任何顺序排列。您的代码始终假定新打开的窗口将位于返回的句柄列表的末尾。你实际上想要以下内容:

// WARNING! Untested code written without benefit of an IDE.
// May not work exactly correctly, or even compile as-is.
String parentWindow = driver.getWindowHandle();

driver.findElement(By.xpath("//*[@id='ImageButton5']")).click();
Thread.sleep(3000);

for(String winHandle : driver.getWindowHandles()) {
  if (!parentWindow.equals(winHandle)) {
    driver.switchTo().window(winHandle);
    Thread.sleep(3000);
    break;
  }
}
System.out.println("Title of the page after - switchingTo: " + driver.getTitle());

答案 1 :(得分:0)

您也可以将这些方法添加到基类中 - 对于这类事情非常有用 -

    /**
     * Waits for a window to appear, then switches to it.
     * @param regex Regex enabled. Url of the window, or title.
     * @return
     */
    public void waitForWindow(String regex) {
        Set<String> windows = driver.getWindowHandles();

        for (String window : windows) {
            try {
                driver.switchTo().window(window);

                p = Pattern.compile(regex);
                m = p.matcher(driver.getCurrentUrl());

                if (m.find()) {
                    attempts = 0;
                    return switchToWindow(regex);
                }
                else {
                    // try for title
                    m = p.matcher(driver.getTitle());

                    if (m.find()) {
                        attempts = 0;
                        return switchToWindow(regex);
                    }
                }
            } catch(NoSuchWindowException e) {
                if (attempts <= MAX_ATTEMPTS) {
                    attempts++;

                    try {Thread.sleep(1);}catch(Exception x) { x.printStackTrace(); }

                    return waitForWindow(regex);
                } else {
                    fail("Window with url|title: " + regex + " did not appear after " + MAX_ATTEMPTS + " tries. Exiting.");
                }
            }
        }

        // when we reach this point, that means no window exists with that title..
        if (attempts == MAX_ATTEMPTS) {
            fail("Window with title: " + regex + " did not appear after 5 tries. Exiting.");
            return this;
        } else {
            System.out.println("#waitForWindow() : Window doesn't exist yet. [" + regex + "] Trying again. " + attempts + "/" + MAX_ATTEMPTS);
            attempts++;
            return waitForWindow(regex);
        }
    }

    /**
     * Switch's to a window that is already in existance.
     * @param regex Regex enabled. Url of the window, or title.
     * @return
     */
    public void switchToWindow(String regex) {
        Set<String> windows = driver.getWindowHandles();

        for (String window : windows) {
            driver.switchTo().window(window);
            System.out.println(String.format("#switchToWindow() : title=%s ; url=%s",
                    driver.getTitle(),
                    driver.getCurrentUrl()));

            p = Pattern.compile(regex);
            m = p.matcher(driver.getTitle());

            if (m.find()) return this;
            else {
                m = p.matcher(driver.getCurrentUrl());
                if (m.find()) return this;
            }
        }

        fail("Could not switch to window with title / url: " + regex);
        return this;
    }

    /**
     * Close an open window.
     * <br>
     * If you have opened only 1 external window, then when you call this method, the context will switch back to the window you were using before.<br>
     * <br>
     * If you had more than 2 windows displaying, then you will need to call {@link #switchToWindow(String)} to switch back context.
     * @param regex The title of the window to close (regex enabled). You may specify <code>null</code> to close the active window. If you specify <code>null</code> then the context will switch back to the initial window.
     * @return
     */
    public void closeWindow(String regex) {
        if (regex == null) {
            driver.close();

            if (driver.getWindowHandles().size() == 1)
                driver.switchTo().window(driver.getWindowHandles().iterator().next());

            return this;
        }

        Set<String> windows = driver.getWindowHandles();

        for (String window : windows) {
            try {
                driver.switchTo().window(window);

                p = Pattern.compile(regex);
                m = p.matcher(driver.getTitle());

                if (m.find()) {
                    switchToWindow(regex); // switch to the window, then close it.
                    driver.close();

                    if (windows.size() == 2) // just default back to the first window.
                        driver.switchTo().window(windows.iterator().next());
                } else {
                    m = p.matcher(driver.getCurrentUrl());
                    if (m.find()) {
                        switchToWindow(regex);
                        driver.close();

                        if (windows.size() == 2) driver.switchTo().window(windows.iterator().next());
                    }
                }

            } catch(NoSuchWindowException e) {
                fail("Cannot close a window that doesn't exist. ["+regex+"]");
            }
        }
        return this;
    }

这最后一个方法特别有用,因为如果窗口句柄的大小在关闭之前是2,它将自动将上下文返回到基本窗口。