如何让selenium等待ajax响应?

Zom*_*ies 60 ajax selenium unit-testing

如何让selenium等待加载日历小部件之类的东西?现在我只是Thread.sleep(2500)在将测试用例导出到junit程序之后做了一个.

Nei*_*ken 42

我会用

waitForElementPresent(locator)
Run Code Online (Sandbox Code Playgroud)

这将等到元素出现在DOM中.

如果您需要检查元素是否可见,您可能会更好地使用

waitForElementHeight(locator)
Run Code Online (Sandbox Code Playgroud)

  • 如果ajax只刷新已存在的值,该怎么办? (33认同)
  • 如果ajax重定向并且selenium不知道怎么办?如何使用它? (17认同)

Mor*_*sen 25

比等待元素更通用的解决方案是等待关闭服务器的所有连接.这将允许您等待所有ajax调用完成,即使它们没有任何回调,因此不会影响页面.更多细节可以在这里找到.

使用C#和jQuery,我创建了以下方法来等待所有的AJax调用完成(如果有人有更直接的方法从C#访问JS变量,请注释):

internal void WaitForAjax(int timeOut = 15)
{
    var value = "";
    RepeatUntil(
        () => value = GetJavascriptValue("jQuery.active"), 
        () => value == "0", 
        "Ajax calls did not complete before timeout"
    );
}

internal void RepeatUntil(Action repeat, Func<bool> until, string errorMessage, int timeout = 15)
{
    var end = DateTime.Now + TimeSpan.FromSeconds(timeout);
    var complete = false;

    while (DateTime.Now < end)
    {
        repeat();
        try
        {
            if (until())
            {
                complete = true;
                break;
            }
        }
        catch (Exception)
        { }
        Thread.Sleep(500);
    }
    if (!complete)
        throw new TimeoutException(errorMessage);
}

internal string GetJavascriptValue(string variableName)
{
    var id = Guid.NewGuid().ToString();
    _selenium.RunScript(String.Format(@"window.$('body').append(""<input type='text' value='""+{0}+""' id='{1}'/>"");", variableName, id));
    return _selenium.GetValue(id);
}
Run Code Online (Sandbox Code Playgroud)

  • this.selenium.GetEval("(window.jQuery || {active:0}).active")比输入框更直接.如果jQuery不在页面上,它也不会出错. (5认同)

Nim*_*imo 11

如果使用python,您可以使用此函数,单击按钮并等待DOM更改:

def click_n_wait(driver, button, timeout=5):
    source = driver.page_source
    button.click()
    def compare_source(driver):
        try:
            return source != driver.page_source
        except WebDriverException:
            pass
    WebDriverWait(driver, timeout).until(compare_source)
Run Code Online (Sandbox Code Playgroud)

(信用:基于此堆栈溢出答案)

  • 不幸的是,有些页面加载动画会破坏这个技巧,因为page_source已更新,但您还没有数据. (3认同)

tou*_*tpt 6

使用webdriver aka selenium2,您可以使用http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits中提到的隐式等待配置

使用Java:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
Run Code Online (Sandbox Code Playgroud)

或者使用python:

from selenium import webdriver

ff = webdriver.Firefox()
ff.implicitly_wait(10) # seconds
ff.get("http://somedomain/url_that_delays_loading")
myDynamicElement = ff.find_element_by_id("myDynamicElement")
Run Code Online (Sandbox Code Playgroud)