67 votes

Comment faire en sorte que le sélénium attend la réponse ajax?

Comment faire en sorte que sélenium attende le chargement d’un widget de calendrier, par exemple? Pour le moment, je ne fais que Thread.sleep(2500) après avoir exporté le test dans un programme Junit.

45voto

Neil Aitken Points 5023

j'utiliserais

 waitForElementPresent(locator)
 

Cela attendra que l'élément soit présent dans le DOM.

Si vous devez vérifier que l’élément est visible, vous ferez peut-être mieux avec

 waitForElementHeight(locator)
 

28voto

Un plus générale solution que d'attendre pour un élément serait d'attendre que toutes les connexions au serveur de fermer. Cela vous permettra d'attendre que tous les appels ajax pour finir, même si elles n'ont pas de rappel et donc n'affecte pas la page. Plus de détails peuvent être trouvés ici.

À l'aide de C# et de jQuery, j'ai créé la méthode suivante pour attendre que tous les appels AJax pour compléter (si quelqu'un a une manière plus directe de l'accès JS variables à partir de C#, s'il vous plaît commentaire):

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);
}

16voto

Nimo Points 527

Si vous utilisez python, vous pouvez utiliser cette fonction, qui clique sur le bouton et attend le changement de 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)
 

(CREDIT: basé sur cette réponse de débordement de pile )

4voto

toutpt Points 1700

Avec webdriver aka selenium2, vous pouvez utiliser la configuration d'attente implicite comme indiqué sur http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits

Utiliser 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"));
 

Ou en utilisant 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")
 

1voto

Amir Shenouda Points 431

J'ai eu une situation similaire, je voulais attendre pour les requêtes ajax ainsi que le panneau de chargement aurait disparu, j'ai inspecté le html avant et après la demande, il existe un div pour l'ajax panneau de chargement, le dix est affiché lors de la requête ajax, et caché après la demande se termine. J'ai créé une fonction pour attendre le panneau à afficher, puis attendre qu'il soit caché


public void WaitForModalPanel()
{
    string element_xpath = ".//*[@id='ajaxLoadingModalPanelContainer'  and not(contains(@style,'display: none'))]";
    WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 2, 0));
    wait.Until(ExpectedConditions.ElementIsVisible(By.XPath(element_xpath)));
    element_xpath = ".//*[@id='ajaxLoadingModalPanelContainer' and contains(@style,'DISPLAY: none')]";
    wait.Until(ExpectedConditions.ElementExists(By.XPath(element_xpath)));
}

Vérifiez ce pour plus de détails

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X