30

我正在使用 TestNG 中的 Selenium Web 驱动程序编写测试用例,并且我有一个场景,我正在按顺序运行多个测试(请参阅下文)

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

这两个测试都是 AJAX 调用,其中打开一个对话框,执行测试,然后关闭对话框,然后在页面顶部显示一条通知消息,每次成功测试后页面刷新

问题是: Test2 不要等待页面刷新/重新加载。假设当 Test1 成功完成时, Test2 将在页面刷新之前启动(即它打开对话框,执行场景等)同时页面刷新(这必然发生在成功执行 Test1 之后)。现在由于页面刷新,由于 Test2 打开的对话框不再存在,然后 Test2 失败。

(另外,我不知道刷新页面需要多长时间。因此,我不想在执行 Test2 之前使用 Thread.sleep(xxxx)

另外,我不认为

driver.navigate().refresh()

将通过将它放在 Test2 之前解决我的问题,因为在这种情况下,我的页面将被刷新两次。问题是通过代码发生的刷新(不确定,因为它可能需要 1 秒或 3 秒或 5 秒)

4

3 回答 3

22

如果您正在等待元素呈现,那么

在 selenium rc 中,我们曾经使用selenium.WaitForCondition("selenium.isElementPresent(\"fContent\")", "desiredTimeoutInMilisec")

在 web 驱动程序中,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 之前等待您的元素出现。

更新 :

如果您正在等待页面加载,那么在 Web 驱动程序中,您可以使用以下代码:

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);
    }
}
于 2012-11-06T05:15:18.617 回答
16

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;
    }
}
于 2013-07-27T12:21:00.773 回答
0

如果您可以触发 URL 更改,这将起作用:

WebDriverWait wait = new WebDriverWait(yourDriver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.UrlContains("/url-fragment"));
于 2017-08-07T04:45:59.160 回答