it-swarm.com.de

Selenium: Lässt den Webtreiber warten, bis die Seite aktualisiert ist, bevor ein weiterer Test ausgeführt wird

Ich schreibe Testfälle mit Selenium Web Driver in TestNG und habe ein Szenario, in dem ich mehrere Tests nacheinander durchführe (siehe unten).

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

Bei beiden Tests handelt es sich um AJAX Aufrufe, bei denen ein Dialogfeld geöffnet, Tests ausgeführt, dann das Dialogfeld geschlossen und oben auf der Seite eine Benachrichtigung angezeigt wird und nach jedem erfolgreichen Test wird die Seite aktualisiert .

Das Problem ist: Test2 warten Sie nicht auf die Seite zu aktualisieren/neu laden. Angenommen, wenn Test1 erfolgreich abgeschlossen wurde, startet Test2 vor der Seitenaktualisierung (dh es öffnet das Dialogfeld, führt Szenarien usw. aus), während die Seite aktualisiert wird (was nach der erfolgreichen Ausführung von Test1 zwangsläufig der Fall war). Seit die Seite aktualisiert wird, ist das aufgrund von Test2 geöffnete Dialogfeld nicht mehr vorhanden und Test2 schlägt fehl.

(Außerdem weiß ich nicht, wie lange es dauern wird, die Seite zu aktualisieren. Daher möchte ich Thread.sleep (xxxx) nicht verwenden, bevor Test2 ausgeführt wird.)

Ich glaube auch nicht

driver.navigate().refresh()

wird mein Problem lösen, indem es vor Test2 gestellt wird, da in diesem Fall meine Seite zweimal aktualisiert wird. Das Problem ist die Aktualisierung, die über den Code erfolgt (was ungewiss ist, da dies 1 Sek. Oder 3 Sek. Oder 5 Sek. Dauern kann).

28
Bhuvan

Wenn Sie darauf warten, dass Element präsentiert wird

In Selenium rc haben wir dies mit Selenium.WaitForCondition("Selenium.isElementPresent(\"fContent\")", "desiredTimeoutInMilisec") gemacht.

Im Web-Treiber kann U damit dasselbe erreichen

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

Auf diese Weise können Sie warten, bis Ihr Element vorhanden ist, bevor Sie test2 ausführen.

AKTUALISIERTE :

Wenn Sie auf das Laden der Seite warten, können Sie im Web-Treiber diesen Code verwenden:

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

Hier ist eine bessere und getestete Version der WaitForPageLoad-Implementierung in 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

wenn Sie eine URL-Änderung auslösen könnten, würde dies funktionieren 

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