web-dev-qa-db-fra.com

Selenium: Comment faire en sorte que le pilote Web attende l'actualisation de la page avant d'effectuer un autre test

J'écris des cas de test à l'aide de Selenium Web Driver dans TestNG et j'ai un scénario dans lequel j'exécute plusieurs tests de manière séquentielle (voir ci-dessous).

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

Les deux tests sont des appels AJAX dans lesquels une boîte de dialogue s'ouvre, les tests s'exécutent, puis la boîte de dialogue se ferme, puis un message de notification apparaît en haut de la page et après chaque test réussi, la page est actualisée .

Le problème est le suivant: Test2 n'attendez pas que la page se rafraîchit/se recharge. Supposons que lorsque Test1 sera terminé avec succès, Test2 démarrera avant l'actualisation de la page (c'est-à-dire qu'il ouvre la boîte de dialogue, exécute des scénarios, etc.) pendant que la page s'actualise (ce qui devait arriver après l'exécution réussie de Test1). Depuis l'actualisation de la page, la boîte de dialogue ouverte en raison de Test2 n'est plus présente, puis Test2 échoue.

(En outre, je ne sais pas combien de temps il faudra pour actualiser la page. Par conséquent, je ne souhaite pas utiliser Thread.sleep (xxxx) avant d'exécuter Test2 )

Aussi, je ne pense pas 

driver.navigate().refresh()

résoudra mon problème en le mettant avant Test2 car dans ce cas, ma page sera rafraîchie deux fois. Le problème est l'actualisation qui passe par le code (ce qui est incertain car cela peut prendre 1 ou 3 ou 5 secondes)

28
Bhuvan

Si vous attendez la présentation de l’élément, alors

Dans Selenium rc, nous avions l'habitude de faire cela en utilisant Selenium.WaitForCondition("Selenium.isElementPresent(\"fContent\")", "desiredTimeoutInMilisec")

En web driver U peut réaliser la même chose en utilisant ceci

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

De cette façon, vous pouvez attendre que votre élément soit présent avant d'exécuter votre test2.

MIS À JOUR :

Si vous attendez le chargement de la page, vous pouvez utiliser ce code dans le pilote 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);
    }
}
21
Abhishek_Mishra

Ici est une version améliorée et testée de l'implémentation de WaitForPageLoad en 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

si vous pouviez déclencher un changement d'URL cela fonctionnerait 

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