Sök…


Typer av vänta i Selenium WebDriver

När du kör någon webbapplikation är det nödvändigt att ta hänsyn till laddningstid. Om din kod försöker komma åt något element som ännu inte är inläst kommer WebDriver att kasta ett undantag och ditt skript kommer att stanna.

Det finns tre typer av väntan -

  • Implicit Waits
  • Vänligen
  • Flytande väntar

Implicita väntningar används för att ställa in väntetiden i hela programmet, medan uttryckliga väntningar endast används på specifika delar.


Implicit vänta

En implicit väntan är att be WebDriver att polla DOM under en viss tid när man försöker hitta ett element eller element om de inte är tillgängliga direkt. Implicita väntningar är i princip ditt sätt att berätta för WebDriver den latens som du vill se om ett specifikt webbelement inte är närvarande som WebDriver letar efter. Standardinställningen är 0. När den är inställd ställs den implicita väntan in för livstiden för WebDriver-objektinstansen. Implicit väntan deklareras i koden för inställning av koden med följande kodstycke.

Exempel i Java :

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

Exempel i C # :

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

Så i det här fallet berättar du för WebDriver att det bör vänta 15 sekunder i fall där ett specificerat element inte är tillgängligt i UI (DOM).


Vänta

Du kan stöta på fall då något element tar mer tid att ladda. Att ställa implicita väntan på sådana fall är inte vettigt eftersom webbläsaren kommer att vänta onödigt samma gång för varje element, vilket ökar automatiseringstiden. Explicit wait help hjälper här genom att kringgå implicit wait helt och hållet för vissa specifika element.

Explicit waits är intelligenta waits som är begränsade till ett visst webbelement. Med hjälp av uttryckliga väntningar berättar du i grund och botten för WebDriver att det är att vänta på X-enheter innan det ger upp.

Explicit waits görs med klasserna WebDriverWait och ExpectedConditions. I exemplet nedan väntar vi upp till 10 sekunder på att ett element vars id är användarnamn blir synligt innan vi fortsätter till nästa kommando. Här är stegen.

Exempel i 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”);

ExpectedConditions-klassen har några fördefinierade vanliga villkor för att vänta på ett element. Klicka här för att se en lista över dessa villkor i Java-bindning.

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

I det här exemplet väntar systemet i 10 sekunder tills elementet är synligt. Om elementet inte kommer att synas efter timeout kommer WebDriver att kasta en WebDriverTimeoutException .

Observera: Om elementet är synligt före 10 sekunders timeout kommer systemet omedelbart att fortsätta för ytterligare process.


Flytande vänta

Till skillnad från implicit och uttrycklig vänta använder flytande vänta två parametrar. Timeout-värde och pollingfrekvens. Låt oss säga att vi har timeoutvärde som 30 sekunder och pollingfrekvens som 2 sekunder. WebDriver kontrollerar efter element efter varannan sekund tills timeout-värde (30 sekunder). Efter att timeout-värdet har överskridits utan något resultat kastas undantag. Nedan är en provkod som visar implementering av flytande väntan.

Exempel i 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"));
    }
});

En annan fördel med att använda flytande vänta är att vi kan ignorera specifika typer av undantag (t.ex. NoSuchElementExceptions) medan vi väntar. På grund av alla dessa bestämmelser är flytande väntan användbar i AJAX-applikationer såväl som i scenarier när elementbelastningstiden ofta varierar. Strategisk användning av flytande vänta förbättrar automatiskt ansträngningarna.


Olika typer av uttryckliga väntningsförhållanden

I uttrycklig väntan förväntar du dig att ett tillstånd ska hända. Till exempel vill du vänta tills ett element är klickbart.

Här är en demonstration av några vanliga problem.

Observera: I alla dessa exempel kan du använda någon By som en locator, såsom classname , xpath , link text , tag name eller cssSelector


Vänta tills elementet är synligt

Om det till exempel tar lite tid att ladda din webbplats kan du vänta tills sidan har laddats, och ditt element är synligt för 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")));

Vänta tills elementet inte syns längre

Samma som tidigare, men omvänd.

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

Vänta tills texten finns i det angivna elementet

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

Om du går till den angivna länken ovan ser du alla väntetillstånd där.

Skillnaden mellan användningen av dessa väntningsförhållanden finns i deras inmatningsparameter.

Det betyder att du måste skicka WebElement om dess inmatningsparameter är WebElement, du måste skicka elementet locator om det tar By locator som sin inmatningsparameter.

Välj klokt vilken typ av väntetillstånd du vill använda.

Väntar på att Ajax-begäran ska slutföras

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

Detta exempel är användbart för sidor där ajax-förfrågningar görs, här använder vi IJavaScriptExecutor att köra vår egen JavaScript-kod. Eftersom det är inom en while slinga kommer det att fortsätta att köra tills ajaxIsComplete == true och så returneras uttalandet.

Vi kontrollerar att alla ajax-förfrågningar är fullständiga genom att bekräfta att jQuery.active är lika med 0 . Detta fungerar eftersom varje gång en ny ajax-begäran görs jQuery.active ökas och varje gång en begäran kompletterar den minskas, från detta kan vi dra slutsatsen att när jQuery.active == 0 måste alla ajax-förfrågningar vara fullständiga.

Flytande vänta

Fluent wait är en superklass av explicit wait ( WebDriverWait ) som är mer konfigurerbar eftersom den kan acceptera ett argument till wait-funktionen. Jag ska vidarebefordra implicit väntan, eftersom det är en bästa praxis att undvika det.

Användning (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;
  }
});

När du använder Explicit wait with its default är det helt enkelt en FluentWait<WebDriver> med standardvärden av: DEFAULT_SLEEP_TIMEOUT = 500; och ignorera NotFoundException .

Flytande vänta

Varje FluentWait-instans definierar den maximala tiden att vänta på ett tillstånd, liksom frekvensen för att kontrollera tillståndet. Dessutom kan användaren konfigurera vänta för att ignorera specifika typer av undantag under väntan, till exempel NoSuchElementExceptions när han söker efter ett element på sidan. Det är associerat med drivrutinen.

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow