Zoeken…


Soorten wachten in Selenium WebDriver

Tijdens het uitvoeren van een webtoepassing moet rekening worden gehouden met de laadtijd. Als uw code toegang probeert te krijgen tot een element dat nog niet is geladen, genereert WebDriver een uitzondering en stopt uw script.

Er zijn drie soorten wachttijden:

  • Impliciete wachttijden
  • Expliciete wachttijden
  • Vloeiend wacht

Impliciete wachttijden worden gebruikt om de wachttijd in het hele programma in te stellen, terwijl expliciete wachttijden alleen op specifieke porties worden gebruikt.


Impliciet wachten

Een impliciete wachttijd is om WebDriver te vertellen de DOM een bepaalde tijd te pollen bij het proberen een element of elementen te vinden als deze niet onmiddellijk beschikbaar zijn. Impliciete wachttijden zijn in principe uw manier om WebDriver de latentie te vertellen die u wilt zien als het opgegeven webelement niet aanwezig is waarnaar WebDriver op zoek is. De standaardinstelling is 0. Eenmaal ingesteld, wordt het impliciete wachten ingesteld voor de levensduur van de objectinstantie van WebDriver. Impliciet wachten wordt in het instantiëringsgedeelte van de code verklaard met behulp van het volgende fragment.

Voorbeeld in Java :

driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// You need to import the following class - import java.util.concurrent.TimeUnit;

Voorbeeld in C # :

driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15));

Dus in dit geval vertelt u WebDriver dat het 15 seconden moet wachten in het geval dat een gespecificeerd element niet beschikbaar is in de UI (DOM).


Expliciet wachten

U kunt instanties tegenkomen wanneer een element meer tijd nodig heeft om te laden. Impliciet wachten instellen voor dergelijke gevallen heeft geen zin, omdat de browser onnodig voor elk element op dezelfde tijd wacht, waardoor de automatiseringstijd toeneemt. Expliciet wachten helpt hier door impliciet wachten helemaal te omzeilen voor enkele specifieke elementen.

Expliciete wachttijden zijn intelligente wachttijden die beperkt zijn tot een bepaald webelement. Door expliciet te wachten, vertelt u WebDriver in feite dat het maximaal X eenheden van tijd moet wachten voordat het opgeeft.

Expliciete wachttijden worden uitgevoerd met de klassen WebDriverWait en ExpectedConditions. In het onderstaande voorbeeld wachten we tot 10 seconden totdat een element waarvan de ID gebruikersnaam is, zichtbaar wordt voordat we verdergaan met de volgende opdracht. Hier zijn de stappen.

Voorbeeld in Java :

//Import these two packages:
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

//Declare a WebDriverWait variable. In this example, we will use myWaitVar as the name of the variable.
WebDriverWait myWaitVar = new WebDriverWait(driver, 30);

//Use myWaitVar with ExpectedConditions on portions where you need the explicit wait to occur. In this case, we will use explicit wait on the username input before we type the text tutorial onto it.
myWaitVar.until(ExpectedConditions.visibilityOfElementLocated(By.id(“username”)));
driver.findElement(By.id(“username”)).sendKeys(“tutorial”);

De klasse ExpectedConditions heeft een aantal vooraf gedefinieerde algemene voorwaarden om op een element te wachten. Klik hier voor een lijst van deze voorwaarden in Java-binding.

Voorbeeld in C # :

using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.PhantomJS;

// You can use any other WebDriver you want, such as ChromeDriver.
using (var driver = new PhantomJSDriver())
{
    driver.Navigate().GoToUrl("http://somedomain/url_that_delays_loading");

    // We aren't going to use it more than once, so no need to declare this a variable.
    new WebDriverWait(driver, TimeSpan.FromSeconds(10))
        .Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));

    // After the element is detected by the previous Wait, 
    // it will display the element's text
    Console.WriteLine(driver.FindElement(By.Id("element-id")).Text);
}

In dit voorbeeld wacht het systeem 10 seconden totdat het element zichtbaar is. Als het element na de time-out niet zichtbaar is, gooit de WebDriver een WebDriverTimeoutException .

Let op: als het element zichtbaar is vóór de time-out van 10 seconden, gaat het systeem onmiddellijk verder voor verder proces.


Vloeiend wachten

In tegenstelling tot impliciet en expliciet wachten, gebruikt vloeiend wachten twee parameters. Time-outwaarde en polling-frequentie. Laten we zeggen dat we een time-outwaarde hebben van 30 seconden en een polling-frequentie van 2 seconden. WebDriver controleert na elke 2 seconden op het element tot de time-outwaarde (30 seconden). Nadat de time-outwaarde zonder enig resultaat is overschreden, wordt een uitzondering gegenereerd. Hieronder is een voorbeeldcode die de implementatie van vloeiend wachten laat zien.

Voorbeeld in Java :

Wait wait = new FluentWait(driver).withTimeout(30, SECONDS).pollingEvery(2, SECONDS).ignoring(NoSuchElementException.class);


WebElement testElement = wait.until(new Function() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(By.id("testId"));
    }
});

Een ander voordeel van vloeiend wachten is dat we specifieke soorten uitzonderingen (bijv. NoSuchElementExceptions) tijdens het wachten kunnen negeren. Vanwege al deze voorzieningen is vloeiend wachten nuttig in AJAX-toepassingen en in scenario's waarin de laadtijd van elementen vaak fluctueert. Strategisch gebruik van vloeiend wachten verbetert de automatisering aanzienlijk.


Verschillende soorten expliciete wachtvoorwaarden

In expliciet wachten, verwacht je dat er een toestand zal gebeuren. U wilt bijvoorbeeld wachten tot een element klikbaar is.

Hier is een demonstratie van enkele veel voorkomende problemen.

Let op: in al deze voorbeelden kunt u elke By als locator gebruiken, zoals classname , xpath , link text , tag name of cssSelector


Wacht tot het element zichtbaar is

Als het bijvoorbeeld even duurt voordat uw website is geladen, kunt u wachten tot de pagina is geladen en uw element zichtbaar is voor de WebDriver.

C #

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));

Java

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element-id")));

Wacht tot het element niet meer zichtbaar is

Hetzelfde als voorheen, maar dan omgekeerd.

C #

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("element-id")));

Java

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("element-id")));

Wacht tot tekst aanwezig is in het opgegeven element

C #

IWebElement element = driver.FindElement(By.Id("element-id"));

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.TextToBePresentInElement(element, "text"));

Java

WebElement element = driver.findElement(By.id("element-id"));

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));

Als u naar de bovenstaande link gaat, ziet u daar alle wachtcondities.

Het verschil tussen het gebruik van deze wachtcondities zit in de invoerparameter.

Dat betekent dat u het WebElement moet doorgeven als de invoerparameter WebElement is, u moet de elementlocator doorgeven als het de By-locator als invoerparameter neemt.

Kies verstandig wat voor soort wachttoestand u wilt gebruiken.

Wachten op afronding van Ajax-aanvragen

C #

using OpenQA.Selenium
using OpenQA.Selenium.Chrome;
using System.Threading;

namespace WebDriver Tests
{
    class WebDriverWaits
    {
        static void Main()
        {
            IWebDriver driver = new ChromeDriver(@"C:\WebDriver");
            
            driver.Navigate().GoToUrl("page with ajax requests");
            CheckPageIsLoaded(driver);

            // Now the page is fully loaded, you can continue with further tests.
        }

        private void CheckPageIsLoaded(IWebDriver driver)
        {
            while (true)
            {
                bool ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
                if (ajaxIsComplete)
                    return;
                Thread.Sleep(100);
            }
        }
    }
}

Dit voorbeeld is handig voor pagina's waar ajax-aanvragen worden gedaan, hier gebruiken we de IJavaScriptExecutor om onze eigen JavaScript-code uit te voeren. Omdat het binnen een while lus is, blijft het lopen tot ajaxIsComplete == true en dus wordt de return-opdracht uitgevoerd.

We controleren of alle ajax-aanvragen zijn voltooid door te bevestigen dat jQuery.active gelijk is aan 0 . Dit werkt omdat elke keer dat een nieuw Ajax-verzoek wordt gedaan, jQuery.active wordt opgehoogd en elke keer dat een verzoek wordt aangevuld, dit wordt verlaagd. jQuery.active == 0 kunnen we afleiden dat wanneer jQuery.active == 0 alle Ajax-aanvragen moeten zijn voltooid.

Vloeiend wachten

Vloeiend wachten is een superklasse van expliciet wachten ( WebDriverWait ) die meer configureerbaar is omdat het een argument voor de WebDriverWait kan accepteren. Ik zal impliciet wachten doorgeven, omdat het een best practice is om het te vermijden.

Gebruik (Java):

Wait wait = new FluentWait<>(this.driver)
        .withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
        .pollingEvery(500, TimeUnit.MILLISECONDS)
        .ignoring(StaleElementReferenceException.class)
        .ignoring(NoSuchElementException.class)
        .ignoring(ElementNotVisibleException.class);

WebElement foo = wait.until(ExpectedConditions.presenceOfElementLocated(By.yourBy));

// or use your own predicate:
WebElement foo = wait.until(new Function() {
  public WebElement apply(WebDriver driver) {
    return element.getText().length() > 0;
  }
});

Wanneer u Expliciet wachten gebruikt met de standaardwaarden, is dit gewoon een FluentWait<WebDriver> met standaardwaarden van: DEFAULT_SLEEP_TIMEOUT = 500; en het negeren van NotFoundException .

Vloeiend wachten

Elke FluentWait-instantie definieert de maximale wachttijd voor een voorwaarde, evenals de frequentie waarmee de voorwaarde wordt gecontroleerd. Bovendien kan de gebruiker het wachten configureren om specifieke typen uitzonderingen tijdens het wachten te negeren, zoals NoSuchElementExceptions bij het zoeken naar een element op de pagina. Het is gekoppeld aan het stuurprogramma.

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS) //actuall wait for the element to pe present
.pollingEvery(5, SECONDS) //selenium will keep looking for the element after every 5seconds
.ignoring(NoSuchElementException.class); //while ignoring this condition
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("username"));


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow