selenium-webdriver
Czekać
Szukaj…
Rodzaje oczekiwania w Selenium WebDriver
Podczas uruchamiania dowolnej aplikacji internetowej należy wziąć pod uwagę czas ładowania. Jeśli Twój kod spróbuje uzyskać dostęp do dowolnego elementu, który nie został jeszcze załadowany, WebDriver zgłosi wyjątek i skrypt się zatrzyma.
Istnieją trzy rodzaje Oczekiwania -
- Implikowane oczekiwania
- Jawne oczekiwania
- Płynne oczekiwania
Niejawne oczekiwania są używane do ustawiania czasu oczekiwania w całym programie, podczas gdy jawne oczekiwania są używane tylko w określonych częściach.
Implicit Wait
Domniemane oczekiwanie polega na tym, aby WebDriver odpytywał DOM przez pewien czas podczas próby znalezienia elementu lub elementów, jeśli nie są one natychmiast dostępne. Niejawne oczekiwania są w zasadzie sposobem informowania WebDriver o opóźnieniu, które chcesz sprawdzić, jeśli określony element WWW nie jest obecny, którego szuka WebDriver. Domyślne ustawienie to 0. Po ustawieniu domyślny czas oczekiwania jest ustawiany na czas życia instancji obiektu WebDriver. Niejawne oczekiwanie jest zadeklarowane w części kodu wystąpienia przy użyciu następującego fragmentu kodu.
Przykład w Javie :
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// You need to import the following class - import java.util.concurrent.TimeUnit;
Przykład w języku C # :
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(15));
W tym przypadku informujesz WebDriver, że powinien poczekać 15 sekund, jeśli określony element nie jest dostępny w interfejsie użytkownika (DOM).
Jawne czekanie
Możesz napotkać sytuacje, gdy załadowanie jakiegoś elementu zajmuje więcej czasu. Ustawienie niejawnego oczekiwania na takie przypadki nie ma sensu, ponieważ przeglądarka niepotrzebnie czeka na ten sam czas dla każdego elementu, co wydłuża czas automatyzacji. Jawne czekanie pomaga tutaj, pomijając całkowicie niejawne czekanie na niektóre określone elementy.
Jawne oczekiwania to inteligentne oczekiwania ograniczone do określonego elementu sieci. Używając jawnych oczekiwań, w zasadzie mówisz WebDriverowi, że musi poczekać X jednostek czasu, zanim się podda.
Jawne oczekiwania są wykonywane przy użyciu klas WebDriverWait i ExpectedConditions. W poniższym przykładzie poczekamy do 10 sekund, aż element, którego id jest nazwa użytkownika, stanie się widoczny, zanim przejdziemy do następnego polecenia. Oto kroki.
Przykład w Javie :
//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”);
Klasa ExpectedConditions ma pewne predefiniowane wspólne warunki oczekiwania na element. Kliknij tutaj, aby zobaczyć listę tych warunków w powiązaniu Java.
Przykład w języku 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);
}
W tym przykładzie system będzie czekać 10 sekund, aż element będzie widoczny. Jeśli element nie będzie widoczny po upływie limitu czasu, WebDriver zgłosi WebDriverTimeoutException
.
Uwaga: jeśli element jest widoczny przed upływem 10 sekund, system natychmiast przejdzie do dalszego procesu.
Płynne czekanie
W przeciwieństwie do oczekiwania niejawnego i jawnego, płynne oczekiwanie wykorzystuje dwa parametry. Wartość limitu czasu i częstotliwość odpytywania. Powiedzmy, że mamy wartość limitu czasu wynoszącą 30 sekund, a częstotliwość odpytywania - 2 sekundy. WebDriver będzie sprawdzać obecność elementu co 2 sekundy, aż do przekroczenia limitu czasu (30 sekund). Po przekroczeniu limitu czasu bez rezultatu zgłaszany jest wyjątek. Poniżej znajduje się przykładowy kod, który pokazuje wdrożenie płynnego oczekiwania.
Przykład w Javie :
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"));
}
});
Kolejną zaletą płynnego oczekiwania jest to, że możemy zignorować określone typy wyjątków (np. NoSuchElementExceptions) podczas oczekiwania. Ze względu na wszystkie te przepisy, płynne oczekiwanie jest pomocne w aplikacjach AJAX, a także w scenariuszach, w których czas ładowania elementu często się zmienia. Strategiczne wykorzystanie płynnego oczekiwania znacznie poprawia automatyzację.
Różne rodzaje jawnych warunków oczekiwania
W jawnym oczekiwaniu oczekujesz wystąpienia warunku. Na przykład chcesz poczekać, aż element będzie klikalny.
Oto kilka typowych problemów.
Uwaga: We wszystkich tych przykładach można użyć dowolnego By
jako lokalizator, takich jak classname
, xpath
, link text
, tag name
lub cssSelector
Poczekaj, aż element będzie widoczny
Na przykład, jeśli ładowanie witryny zajmuje trochę czasu, możesz poczekać, aż strona się załaduje, a Twój element będzie widoczny dla WebDriver.
DO#
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("element-id")));
Jawa
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("element-id")));
Poczekaj, aż element nie będzie już widoczny
Taki sam jak poprzednio, ale odwrócony.
DO#
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.Id("element-id")));
Jawa
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("element-id")));
Poczekaj, aż tekst pojawi się w określonym elemencie
DO#
IWebElement element = driver.FindElement(By.Id("element-id"));
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.TextToBePresentInElement(element, "text"));
Jawa
WebElement element = driver.findElement(By.id("element-id"));
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));
Jeśli przejdziesz do podanego linku powyżej, zobaczysz tam wszystkie warunki oczekiwania.
Różnica między zastosowaniem tych warunków oczekiwania zależy od parametru wejściowego.
Oznacza to, że musisz przekazać WebElement, jeśli jego parametrem wejściowym jest WebElement, musisz przekazać lokalizator elementów, jeśli jako parametr wejściowy przyjmuje parametr Lokalizator By.
Wybierz mądrze, jakiego rodzaju warunku oczekiwania chcesz użyć.
Oczekiwanie na zakończenie żądań Ajax
DO#
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);
}
}
}
}
Ten przykład jest przydatny dla stron, na których wysyłane są żądania ajax, tutaj używamy IJavaScriptExecutor
do uruchomienia własnego kodu JavaScript. Jak to jest w while
pętli będzie nadal działać, dopóki ajaxIsComplete == true
, a więc instrukcja return jest wykonywany.
Sprawdzamy, czy wszystkie żądania ajax są kompletne, potwierdzając, że jQuery.active
ma wartość 0
. Działa to, ponieważ za każdym razem, gdy jest tworzone nowe żądanie ajax, jQuery.active
jest zwiększane, a za każdym razem, gdy żądanie się uzupełnia, jest zmniejszane, z tego możemy wywnioskować, że kiedy jQuery.active == 0
wszystkie żądania ajax muszą być kompletne.
Płynne czekanie
WebDriverWait
oczekiwanie to WebDriverWait
jawnego oczekiwania ( WebDriverWait
), która jest bardziej konfigurowalna, ponieważ może akceptować argument funkcji oczekiwania. Przekażę domniemane oczekiwanie, ponieważ najlepszą praktyką jest unikanie go.
Użycie (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;
}
});
Kiedy używasz Jawnego oczekiwania z ustawieniami domyślnymi, jest to po prostu FluentWait<WebDriver>
z wartościami domyślnymi: DEFAULT_SLEEP_TIMEOUT = 500;
i ignorując NotFoundException
.
Płynne czekanie
Każda instancja FluentWait określa maksymalny czas oczekiwania na warunek, a także częstotliwość sprawdzania warunku. Ponadto użytkownik może skonfigurować oczekiwanie, aby podczas oczekiwania ignorowało określone typy wyjątków, takie jak NoSuchElementExceptions, podczas wyszukiwania elementu na stronie. Jest on powiązany ze sterownikiem.
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"));