Как веб-драйвер селена узнать, когда открылось новое окно, и возобновить его выполнение? - PullRequest
24 голосов
/ 08 февраля 2012

У меня проблема с автоматизацией веб-приложения с помощью веб-драйвера selenium.

На веб-странице есть кнопка, при нажатии которой открывается новое окно.Когда я использую следующий код, он выдает OpenQA.Selenium.NoSuchWindowException: No window found

WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();

. Чтобы решить вышеуказанную проблему, я добавляю Thread.Sleep(50000); между нажатием кнопки и SwitchTo оператором.

WebDriver.FindElement(By.Id("id of the button that opens new window")).Click();
Thread.Sleep(50000); //wait
//Switch to new window
_WebDriver.SwitchTo().Window("new window name");
//Click on button present on the newly opened window
_WebDriver.FindElement(By.Id("id of button present on newly opened window")).Click();

Это решило проблему, но я не хочу использовать оператор Thread.Sleep(50000);, потому что, если открытию окна требуется больше времени, код может дать сбой, а если окно открывается быстро, то это делает ненужным медленное тестирование.

Есть ли способ узнать, когда окно открылось, а затем тест может возобновить свое выполнение?

Ответы [ 5 ]

27 голосов
/ 08 февраля 2012

Вам нужно переключить элемент управления во всплывающее окно, прежде чем выполнять какие-либо операции в нем. Используя это, вы можете решить вашу проблему.

Перед открытием всплывающего окна найдите дескриптор главного окна и сохраните его.

String mwh=driver.getWindowHandle();

Теперь попробуйте открыть всплывающее окно, выполнив некоторое действие:

driver.findElement(By.xpath("")).click();

Set s=driver.getWindowHandles(); //this method will gives you the handles of all opened windows

Iterator ite=s.iterator();

while(ite.hasNext())
{
    String popupHandle=ite.next().toString();
    if(!popupHandle.contains(mwh))
    {
        driver.switchTo().window(popupHandle);
        /**/here you can perform operation in pop-up window**
        //After finished your operation in pop-up just select the main window again
        driver.switchTo().window(mwh);
    }
}
11 голосов
/ 08 февраля 2012

Вы можете подождать, пока операция завершится успешно, например, в Python:

from selenium.common.exceptions    import NoSuchWindowException
from selenium.webdriver.support.ui import WebDriverWait

def found_window(name):
    def predicate(driver):
        try: driver.switch_to_window(name)
        except NoSuchWindowException:
             return False
        else:
             return True # found window
    return predicate

driver.find_element_by_id("id of the button that opens new window").click()        
WebDriverWait(driver, timeout=50).until(found_window("new window name"))
WebDriverWait(driver, timeout=10).until( # wait until the button is available
    lambda x: x.find_element_by_id("id of button present on newly opened window"))\
    .click()
1 голос
/ 14 мая 2017

Я использую это для ожидания открытия окна, и оно работает для меня.

C # код:

public static void WaitUntilNewWindowIsOpened(this RemoteWebDriver driver, int expectedNumberOfWindows, int maxRetryCount = 100)
    {
        int returnValue;
        bool boolReturnValue;
        for (var i = 0; i < maxRetryCount; Thread.Sleep(100), i++)
        {
            returnValue = driver.WindowHandles.Count;
            boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
            if (boolReturnValue)
            {
                return;
            }
        }
        //try one last time to check for window
        returnValue = driver.WindowHandles.Count;
        boolReturnValue = (returnValue == expectedNumberOfWindows ? true : false);
        if (!boolReturnValue)
        {
            throw new ApplicationException("New window did not open.");
        }
    }

А потом я вызываю этот метод в коде

Extensions.WaitUntilNewWindowIsOpened(driver, 2);
1 голос
/ 02 октября 2013

Я наконец нашел ответ, я использовал приведенный ниже метод для переключения в новое окно,

public String switchwindow(String object, String data){
        try {

        String winHandleBefore = driver.getWindowHandle();

        for(String winHandle : driver.getWindowHandles()){
            driver.switchTo().window(winHandle);
        }
        }catch(Exception e){
        return Constants.KEYWORD_FAIL+ "Unable to Switch Window" + e.getMessage();
        }
        return Constants.KEYWORD_PASS;
        }

Чтобы перейти к родительскому окну, я использовал следующий код,

 public String switchwindowback(String object, String data){
            try {
                String winHandleBefore = driver.getWindowHandle();
                driver.close(); 
                //Switch back to original browser (first window)
                driver.switchTo().window(winHandleBefore);
                //continue with original browser (first window)
            }catch(Exception e){
            return Constants.KEYWORD_FAIL+ "Unable to Switch to main window" + e.getMessage();
            }
            return Constants.KEYWORD_PASS;
            }

Я думаю, что это поможет вам переключаться между окнами.

0 голосов
/ 08 февраля 2019

Хотя на этот вопрос уже есть ответы, ни один из них не был для меня действительно полезным, так как я не могу рассчитывать на получение какого-либо нового окна, мне нужно было фильтровать еще больше, поэтому я начал использовать решение Dadoh, но настраивал его, пока не подошел надеюсь, что с этим решением оно кому-нибудь пригодится.

public async Task<string> WaitUntilNewWindowIsOpen(string expectedWindowTitle, bool switchToWindow, int maxRetryCount = 100)
{
    string newWindowHandle = await Task.Run(() =>
    {
        string previousWindowHandle = _driver.CurrentWindowHandle;
        int retries = 0;
        while (retries < maxRetryCount)
        {
            foreach (string handle in _driver.WindowHandles)
            {
                _driver.SwitchTo().Window(handle);
                string title = _driver.Title;
                if (title.Equals(expectedWindowTitle))
                {
                    if(!switchToWindow)
                        _driver.SwitchTo().Window(previousWindowHandle);
                    return handle;
                }
            }
            retries++;
            Thread.Sleep(100);
        }
        return string.Empty;
    });
    return newWindowHandle;
}

Таким образом, в этом решении я решил передать ожидаемый заголовок окна в качестве аргумента функции, чтобы зациклить все окна и сравнить заголовок нового окна, таким образом, гарантированно вернется правильное окно. Вот пример вызова этого метода:

await WaitUntilNewWindowIsOpen("newWindowTitle", true);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...