it-roy-ru.com

Selenium: как заставить веб-драйвер ждать обновления страницы перед выполнением другого теста

Я пишу тестовые случаи, используя Selenium web Driver в TestNG, и у меня есть сценарий, в котором я запускаю несколько тестов последовательно (см. Ниже)

@Test(priority =1)
public void Test1(){
}
@Test(priority =2)
public void Test2(){ 
}

Оба теста являются вызовами AJAX, когда открывается диалоговое окно, выполняется тестирование, затем диалоговое окно закрывается, а затем в верхней части страницы появляется уведомление и после каждого успешного теста страница обновляется .

Проблема в том, что: Test2 не ждет, пока страница обновится/перезагрузится. Предположим, что когда Test1 будет успешно завершен, Test2 запустится до обновления страницы (то есть откроет диалоговое окно, выполнит сценарии и т.д.), А страница обновится (что должно было произойти после успешного выполнения Test1). Теперь, когда страница обновляется, диалоговое окно, открытое из-за Test2, больше не присутствует, а затем Test2 дает сбой.

(Кроме того, я не знаю, сколько времени займет обновление страницы. Поэтому я не хочу использовать Thread.sleep (xxxx) перед выполнением Test2 )

Кроме того, я не думаю, 

driver.navigate().refresh()

решит мою проблему, поставив ее перед Test2, так как в этом случае моя страница будет обновляться дважды. Проблема заключается в обновлении, которое происходит через код (что неясно, так как это может занять 1 секунду, 3 секунды или 5 секунд).

28
Bhuvan

Если вы ожидаете элемента, чтобы представить то

В Selenium rc мы делали это с помощью Selenium.WaitForCondition("Selenium.isElementPresent(\"fContent\")", "desiredTimeoutInMilisec")

В веб-драйвере U можно добиться того же, используя этот

WebDriverWait myWait = new WebDriverWait(webDriver, 45);
ExpectedCondition<Boolean> conditionToCheck = new ExpectedCondition<Boolean>()
{
    @Override
    public Boolean apply(WebDriver input) {
        return (input.findElements(By.id("fContent")).size() > 0);
    }
};
myWait.until(conditionToCheck);

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

ОБНОВЛЕНО:

Если вы ожидаете загрузки страницы, то в веб-драйвере вы можете использовать этот код:

public void waitForPageLoaded(WebDriver driver)
{
    ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() 
    {
        public Boolean apply(WebDriver driver)
        {
            return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
        }
    };
    Wait<WebDriver> wait = new WebDriverWait(driver,30);
    try
    {
        wait.until(expectation);
    }
    catch(Throwable error)
    {
        assertFalse("Timeout waiting for Page Load Request to complete.",true);
    }
}
21
Abhishek_Mishra

Здесь является лучшей и проверенной версией реализации WaitForPageLoad в C # .Net

public void WaitForPageLoad(int maxWaitTimeInSeconds) {
    string state = string.Empty;
    try {
        WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(maxWaitTimeInSeconds));

        //Checks every 500 ms whether predicate returns true if returns exit otherwise keep trying till it returns ture
        wait.Until(d = > {

            try {
                state = ((IJavaScriptExecutor) _driver).ExecuteScript(@"return document.readyState").ToString();
            } catch (InvalidOperationException) {
                //Ignore
            } catch (NoSuchWindowException) {
                //when popup is closed, switch to last windows
                _driver.SwitchTo().Window(_driver.WindowHandles.Last());
            }
            //In IE7 there are chances we may get state as loaded instead of complete
            return (state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase));

        });
    } catch (TimeoutException) {
        //sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls
        if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))
            throw;
    } catch (NullReferenceException) {
        //sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls
        if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))
            throw;
    } catch (WebDriverException) {
        if (_driver.WindowHandles.Count == 1) {
            _driver.SwitchTo().Window(_driver.WindowHandles[0]);
        }
        state = ((IJavaScriptExecutor) _driver).ExecuteScript(@"return document.readyState").ToString();
        if (!(state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase)))
            throw;
    }
}
15
Vishnu

если бы вы могли вызвать изменение URL, это будет работать 

WebDriverWait wait = new WebDriverWait(yourDriver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.UrlContains("/url-fragment"));
0
Kieran