selenium-webdriver
Aspettare
Ricerca…
Tipi di attesa in Selenium WebDriver
Durante l'esecuzione di qualsiasi applicazione Web è necessario prendere in considerazione il tempo di caricamento. Se il tuo codice tenta di accedere a qualsiasi elemento che non è ancora stato caricato, WebDriver genererà un'eccezione e il tuo script si fermerà.
Esistono tre tipi di attese:
- Attese implicite
- Attese esplicite
- Attese fluide
Le attese implicite vengono utilizzate per impostare il tempo di attesa in tutto il programma, mentre le attese esplicite vengono utilizzate solo su parti specifiche.
Attesa implicita
Un'attesa implicita è di dire a WebDriver di interrogare il DOM per una certa quantità di tempo quando si cerca di trovare un elemento o elementi se non sono immediatamente disponibili. Le attese implicite sono fondamentalmente il tuo modo di dire a WebDriver la latenza che vuoi vedere se l'elemento web specificato non è presente che WebDriver sta cercando. L'impostazione predefinita è 0. Una volta impostata, l'attesa implicita viene impostata per la durata dell'istanza dell'oggetto WebDriver. L'attesa implicita viene dichiarata nella parte di istanziazione del codice utilizzando il seguente snippet.
Esempio in Java :
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// You need to import the following class - import java.util.concurrent.TimeUnit;
Esempio in C # :
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15));
Quindi in questo caso, stai dicendo a WebDriver che dovrebbe aspettare 15 secondi nel caso in cui l'elemento specificato non sia disponibile sull'interfaccia utente (DOM).
Attesa esplicita
Potresti incontrare istanze quando alcuni elementi richiedono più tempo per essere caricati. L'impostazione di attesa implicita per questi casi non ha senso poiché il browser attenderà inutilmente lo stesso tempo per ogni elemento, aumentando il tempo di automazione. L'attesa esplicita aiuta qui aggirando l'attesa implicita del tutto per alcuni elementi specifici.
Le attese esplicite sono attese intelligenti che sono confinate a un particolare elemento web. Usando le attese esplicite stai praticamente dicendo a WebDriver al massimo è di aspettare X unità di tempo prima che si arrenda.
Le attese esplicite vengono eseguite utilizzando le classi WebDriverWait e ExpectedConditions. Nell'esempio seguente, dovremo attendere fino a 10 secondi per un elemento il cui id è username per diventare visibile prima di passare al comando successivo. Ecco i passaggi.
Esempio 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”);
La classe ExpectedConditions ha alcune condizioni comuni predefinite per attendere un elemento. Fare clic qui per visualizzare l'elenco di queste condizioni nell'associazione Java.
Esempio 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 questo esempio, il sistema attenderà per 10 secondi finché l'elemento non sarà visibile. Se l'elemento non sarà visibile dopo il timeout, il WebDriver genererà un'eccezione WebDriverTimeoutException
.
Nota: se l'elemento è visibile prima del timeout di 10 secondi, il sistema procederà immediatamente per ulteriori processi.
Aspetta fluente
Diversamente dall'attesa implicita ed esplicita, l'attesa fluente utilizza due parametri. Valore di timeout e frequenza di polling. Diciamo che abbiamo il valore di timeout come 30 secondi e la frequenza di polling di 2 secondi. WebDriver controllerà l'elemento ogni 2 secondi fino al valore di timeout (30 secondi). Dopo che il valore di timeout è stato superato senza alcun risultato, viene generata un'eccezione. Di seguito è riportato un codice di esempio che mostra l'implementazione dell'attesa fluente.
Esempio 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"));
}
});
Un altro vantaggio dell'utilizzo dell'attesa fluente è che possiamo ignorare determinati tipi di eccezioni (ad esempio NoSuchElementExceptions) durante l'attesa. A causa di tutte queste disposizioni, l'attesa fluente è utile nelle applicazioni AJAX e negli scenari in cui il tempo di carico degli elementi oscilla spesso. L'uso strategico dell'attesa fluente migliora in modo significativo gli sforzi di automazione.
Diversi tipi di condizioni di attesa esplicite
Nell'attesa esplicita, ci si aspetta che una condizione si verifichi. Ad esempio, si desidera attendere fino a quando un elemento è cliccabile.
Ecco una dimostrazione di alcuni problemi comuni.
Si prega di notare: In tutti questi esempi è possibile utilizzare qualsiasi By
come un localizzatore, come il classname
, xpath
, link text
, tag name
o cssSelector
Attendi fino a quando l'elemento è visibile
Ad esempio, se il tuo sito web richiede un po 'di tempo per essere caricato, puoi aspettare fino a quando la pagina completa il caricamento e il tuo elemento è visibile sul WebDriver.
C #
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));
Giava
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element-id")));
Attendi fino a quando l'elemento non è più visibile
Come prima, ma invertito.
C #
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("element-id")));
Giava
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("element-id")));
Attendere fino a quando il testo è presente nell'elemento specificato
C #
IWebElement element = driver.FindElement(By.Id("element-id"));
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.TextToBePresentInElement(element, "text"));
Giava
WebElement element = driver.findElement(By.id("element-id"));
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));
Se vai al link indicato sopra, vedrai tutte le condizioni di attesa lì.
La differenza tra l'utilizzo di queste condizioni di attesa è nel loro parametro di input.
Ciò significa che devi passare il WebElement se il suo parametro di input è WebElement, devi passare il locator degli elementi se prende il locator By come parametro di input.
Scegli con saggezza il tipo di condizione di attesa che desideri utilizzare.
In attesa di richieste Ajax da completare
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);
}
}
}
}
Questo esempio è utile per le pagine in cui vengono fatte richieste ajax, qui usiamo IJavaScriptExecutor
per eseguire il nostro codice JavaScript. Poiché è all'interno di un ciclo while
, continuerà a funzionare fino a ajaxIsComplete == true
e quindi l'istruzione return viene eseguita.
Controlliamo che tutte le richieste ajax siano complete confermando che jQuery.active
è uguale a 0
. Questo funziona perché ogni volta che viene fatta una nuova richiesta jQuery.active
viene incrementato e ogni volta che una richiesta viene completata viene decrementato, da questo possiamo dedurre che quando jQuery.active == 0
tutte le richieste jQuery.active == 0
devono essere completate.
Aspetta fluente
L'attesa fluente è una superclasse di attesa esplicita ( WebDriverWait
) che è più configurabile poiché può accettare un argomento per la funzione di attesa. Trascorrerò un'attesa implicita , dal momento che è una buona pratica evitarla.
Utilizzo (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;
}
});
Quando usi Explicit wait con i suoi valori predefiniti è semplicemente un FluentWait<WebDriver>
con valori predefiniti di: DEFAULT_SLEEP_TIMEOUT = 500;
e ignorando NotFoundException
.
Aspetta fluente
Ogni istanza di FluentWait definisce la quantità massima di tempo di attesa per una condizione, nonché la frequenza con cui controllare la condizione. Inoltre, l'utente può configurare l'attesa per ignorare determinati tipi di eccezioni durante l'attesa, come NoSuchElementExceptions durante la ricerca di un elemento nella pagina. È associato al driver.
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"));