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.
Réponses
Trop de publicités?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);
}
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 )
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")
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