Pracuję na Java Selenium-WebDriver. dodałem
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
i
WebElement textbox = driver.findElement(By.id("textbox"));
ponieważ załadowanie interfejsu użytkownika zajmuje mi kilka sekund. Więc ustawiłem 2 sekundy implicitwait. ale nie udało mi się zlokalizować pola tekstowego elementu
Następnie dodaję Thread.sleep(2000);
Teraz działa dobrze. Który z nich jest lepszy?
Odpowiedzi:
Cóż, istnieją dwa typy oczekiwania: jawne i niejawne oczekiwanie. Idea jawnego czekania jest taka
Pojęcie niejawnego oczekiwania to
Można uzyskać różnicę w szczegółach tutaj .
W takich sytuacjach wolałbym użyć jawnego czekania (
fluentWait
w szczególności):fluentWait
funkcja zwraca znaleziony element sieciowy. Z dokumentacji na tematfluentWait
: Implementacja interfejsu Wait, która może mieć skonfigurowany limit czasu i interwał odpytywania w locie. Każda instancja FluentWait definiuje maksymalny czas oczekiwania na warunek, a także częstotliwość sprawdzania warunku. Ponadto użytkownik może skonfigurować oczekiwanie, aby ignorować określone typy wyjątków podczas oczekiwania, takie jak NoSuchElementExceptions podczas wyszukiwania elementu na stronie. Szczegóły znajdziesz tutajWykorzystanie
fluentWait
w twoim przypadku jest następujące:To podejście IMHO jest lepsze, ponieważ nie wiesz dokładnie, ile czasu czekać, aw interwale odpytywania możesz ustawić dowolną wartość czasu, przez którą obecność elementu zostanie zweryfikowana. Pozdrowienia.
źródło
import com.google.common.base.Function;
nieimport java.util.function.Function;
Function
zostało użyte. Na początku nie było to dla mnie oczywiste. Dziękuję za odpowiedź.driver -> driver.findElement(locator)
. Podczas korzystania z tego w ogóle nie potrzebujesz instrukcji importu..withTimeout(Duration.ofSeconds(30)).pollingEvery(Duration.ofSeconds(5))
zamiast:.withTimeout(30, TimeUnit.SECONDS).pollingEvery(5, TimeUnit.SECONDS)
Ten wątek jest nieco starszy, ale pomyślałem, że opublikuję to, co obecnie robię (w toku).
Chociaż nadal trafiam w sytuacje, w których system jest mocno obciążony i kiedy klikam przycisk przesyłania (np. Login.jsp), wszystkie trzy warunki (patrz poniżej) wracają,
true
ale następna strona (np. Home.jsp) nie t zacząłem jeszcze ładować.Jest to ogólna metoda oczekiwania, która pobiera listę ExpectedConditions.
Zdefiniowałem różne ExpectedConditions wielokrotnego użytku (trzy poniżej). W tym przykładzie trzy oczekiwane warunki to document.readyState = 'complete', brak „wait_dialog” i brak „spinners” (elementy wskazujące na dane asynchroniczne są żądane).
Tylko pierwszy z nich można zastosować ogólnie do wszystkich stron internetowych.
W zależności od strony mogę użyć jednego lub wszystkich z nich:
Istnieją również predefiniowane ExpectedConditions w następującej klasie: org.openqa.selenium.support.ui.ExpectedConditions
źródło
Jeśli używasz webdriverJs (node.js),
Powyższy kod powoduje, że przeglądarka czeka przez 5 sekund po kliknięciu przycisku.
źródło
Używanie
Thread.sleep(2000);
to bezwarunkowe czekanie. Jeśli twój test ładuje się szybciej, nadal będziesz musiał czekać. Więc w zasadzie używanieimplicitlyWait
jest lepszym rozwiązaniem.Jednak nie widzę powodu, dla którego
implicitlyWait
nie działa w Twoim przypadku. Czy zmierzyłeś, czyfindElement
faktycznie zajmuje to dwie sekundy przed rzuceniem wyjątku? Jeśli tak, czy możesz spróbować użyć warunkowego oczekiwania WebDriver, jak opisano w tej odpowiedzi?źródło
Lubię używać niestandardowych warunków. Oto kod w Pythonie:
Zawsze, gdy musisz czekać, możesz to zrobić jawnie, sprawdzając istnienie określonego elementu (taki element może się różnić w zależności od strony).
find_elements_by_id
lista zwrotów - pusta czy nie, wystarczy sprawdzić.źródło
kliknięcie wydaje się blokować? - oto inny sposób czekania, jeśli używasz WebDriverJS:
Powyższy kod czeka po kliknięciu przycisku na załadowanie następnej strony, a następnie pobiera źródło następnej strony.
źródło
Niejawnie czekaj i Thread.sleep Oba są używane tylko do synchronizacji, ale różnica polega na tym, że możemy użyć Niejawnie poczekaj na cały program, ale Thread.sleep będzie działać tylko dla tego pojedynczego kodu. gdy za każdym razem Twoja strona internetowa będzie odświeżana, oznacza to, że użyj wątku. uśpiony w tym czasie .. będzie o wiele lepiej :)
Oto mój kod:
źródło
Czasami zdaje się, że niejawne oczekiwanie zostaje zastąpione, a czas oczekiwania zostaje skrócony. [@ eugene.polschikov] miał dobrą dokumentację na temat powodów. Podczas testowania i kodowania z Selenium 2 odkryłem, że niejawne oczekiwania są dobre, ale czasami trzeba czekać jawnie.
Lepiej jest unikać bezpośredniego wzywania wątku do snu, ale czasami nie ma na to dobrego sposobu. Istnieją jednak inne opcje oczekiwania dostępne w Selenium, które pomagają. waitForPageToLoad i waitForFrameToLoad okazały się szczególnie przydatne.
źródło
Niejawne oczekiwanie: Podczas niejawnego oczekiwania, jeśli sterownik sieciowy nie może go natychmiast znaleźć ze względu na jego dostępność, WebDriver będzie czekał przez wspomniany czas i nie będzie próbował ponownie znaleźć elementu w określonym przedziale czasu. Po upływie określonego czasu spróbuje przeszukać element jeszcze raz, po raz ostatni przed rzuceniem wyjątku. Domyślne ustawienie to zero. Po ustawieniu czasu sterownik sieciowy czeka na okres wystąpienia obiektu WebDriver.
Jawne oczekiwanie: może wystąpić wystąpienie, gdy załadowanie określonego elementu trwa dłużej niż minutę. W takim przypadku na pewno nie lubisz ustawiać ogromnego czasu na niejawne oczekiwanie, ponieważ jeśli to zrobisz, twoja przeglądarka będzie czekać w tym samym czasie na każdy element. Aby uniknąć takiej sytuacji, możesz po prostu ustawić oddzielny czas tylko dla wymaganego elementu. Postępując zgodnie z tym, domyślny czas oczekiwania przeglądarki byłby krótki dla każdego elementu i długi dla określonego elementu.
źródło
Czasami niejawne oczekiwanie zawodzi, mówiąc, że element istnieje, ale tak naprawdę nie jest.
Rozwiązaniem jest uniknięcie używania driver.findElement i zastąpienie go metodą niestandardową, która niejawnie używa jawnego oczekiwania. Na przykład:
Istnieją dodatkowe powody, dla których należy unikać niejawnego oczekiwania, inne niż sporadyczne, sporadyczne awarie (patrz ten link ).
Możesz użyć tej metody „elementu” w taki sam sposób jak driver.findElement. Na przykład:
Jeśli naprawdę chcesz poczekać kilka sekund na rozwiązanie problemu lub inną rzadką okazję, możesz utworzyć metodę pauzy podobną do tej, którą oferuje Selenium IDE:
źródło
Odpowiedź : poczekaj kilka sekund, zanim widoczność elementu za pomocą Selenium WebDriver przejdzie przez poniższe metody.
implicitlyWait () : instancja WebDriver czeka na pełne załadowanie strony. Myślisz, że czekanie na pełne załadowanie strony trwa od 30 do 60 sekund.
ExplicitlyWait WebDriverWait () : instancja WebDriver czeka na pełne załadowanie strony.
Uwaga : użyj ExplicitlyWait WebDriverWait () do obsługi dowolnego określonego elementu WebElement.
źródło
Użyj działań -
Zobacz metodę pauzy Actions # .
źródło
Wolę, aby następujący kod czekał 2 sekundy.
źródło
jest gorzej: będąc statycznym czekaniem, skrypt testowy będzie wolniejszy.
to jest dynamiczne oczekiwanie
Wreszcie proponuję
z pewnymi predefiniowanymi warunkami:
źródło
Pomogło mi to, ale należy zająć się wyjątkiem InterruptedException. Więc lepiej otocz go próbą złapania:
LUB
Dodaj deklarację rzutów:
Wolałbym drugi, ponieważ można go używać
sleep()
tyle razy, ile chce i unikać powtarzaniatry
icatch
blokowania za każdym razem,sleep()
gdy został użyty.źródło