Czy ktoś może mi pozwolić, jak mogę sprawić, by selen zaczekał do całkowitego załadowania strony? Chcę czegoś ogólnego, wiem, że mogę skonfigurować WebDriverWait i wywołać coś w rodzaju „find”, aby poczekać, ale nie posuwam się tak daleko. Muszę tylko sprawdzić, czy strona ładuje się pomyślnie i przejść do następnej strony, aby przetestować.
Znalazłem coś w .net, ale nie mogłem sprawić, by działało w Javie ...
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Czy ktoś myśli?
Odpowiedzi:
Wypróbuj ten kod:
Powyższy kod będzie czekał do 10 sekund na załadowanie strony. Jeśli ładowanie strony przekroczy czas, wyrzuci plik
TimeoutException
. Łapiesz wyjątek i spełniasz swoje potrzeby. Nie jestem pewien, czy kończy ładowanie strony po zgłoszeniu wyjątku. nie próbowałem jeszcze tego kodu. Chcę po prostu spróbować.To jest ukryte oczekiwanie. Jeśli ustawisz to raz, zakres będzie obowiązywał do momentu zniszczenia instancji sterownika sieciowego.
Więcej informacji można znaleźć w dokumentacji
WebDriver.Timeouts
.źródło
Twoje sugerowane rozwiązanie czeka tylko na sygnał DOM
readyState
complete
. Ale Selenium domyślnie próbuje czekać na te (i trochę więcej) ładunków strony za pomocą metoddriver.get()
ielement.click()
. Już się blokują, czekają na pełne załadowanie strony i te powinny działać poprawnie.Problemem są oczywiście przekierowania za pośrednictwem żądań AJAX i uruchomionych skryptów - Selenium nie może ich przechwycić, nie czeka na ich zakończenie. Ponadto nie można ich niezawodnie złapać
readyState
- czeka chwilę, co może być przydatne, ale będzie sygnalizować nacomplete
długo przed pobraniem całej zawartości AJAX.Nie ma ogólnego rozwiązania, które sprawdziłoby się wszędzie i dla każdego, dlatego jest to trudne i każdy używa czegoś innego.
Ogólna zasada polega na tym, że WebDriver wykona swoją część, następnie użyj niejawnego oczekiwania, a następnie użyj jawnego oczekiwania dla elementów, które chcesz potwierdzić na stronie, ale jest o wiele więcej technik, które można zrobić. Na testowanej stronie powinieneś wybrać ten (lub kombinację kilku z nich), który działa najlepiej w Twoim przypadku.
Zobacz moje dwie odpowiedzi dotyczące tego, aby uzyskać więcej informacji:
źródło
element.click()
połączeń.Oto działająca wersja Java przykładu, który podałeś:
Przykład dla c #:
źródło
import com.google.common.base.Predicate
Oto moja próba stworzenia całkowicie ogólnego rozwiązania w Pythonie:
Po pierwsze, ogólna funkcja „czekaj” (jeśli chcesz, użyj WebDriverWait, uważam je za brzydkie):
Następnie rozwiązanie opiera się na fakcie, że selen rejestruje (wewnętrzny) numer identyfikacyjny dla wszystkich elementów na stronie, w tym elementu najwyższego poziomu
<html>
. Gdy strona odświeża się lub ładuje, otrzymuje nowy element html z nowym identyfikatorem.Więc zakładając, że chcesz kliknąć link z tekstem „mój link”, na przykład:
Aby uzyskać więcej ogólnych pomocników w języku Pythonic, wielokrotnego użytku, możesz utworzyć menedżera kontekstu:
A potem możesz go użyć do praktycznie każdej interakcji z selenem:
Myślę, że to jest kuloodporne! Co myślisz?
Więcej informacji w poście na ten temat tutaj
źródło
Miałem podobny problem. Musiałem poczekać, aż mój dokument będzie gotowy, ale także do zakończenia wszystkich połączeń Ajax. Drugi warunek okazał się trudny do wykrycia. W końcu sprawdziłem aktywne połączenia Ajax i zadziałało.
JavaScript:
Pełna metoda C #:
źródło
document.readyState == 'complete' && jQuery.active == 0
React?źródło
W przypadku C # NUnit musisz przekonwertować WebDriver na JSExecuter, a następnie wykonać skrypt, aby sprawdzić, czy stan document.ready jest kompletny, czy nie. Sprawdź poniższy kod w celach informacyjnych:
Będzie to czekać, aż warunek zostanie spełniony lub upłynie limit czasu.
źródło
Przy początkowym ładowaniu strony zauważyłem, że "Maksymalizacja" okna przeglądarki praktycznie czeka na zakończenie ładowania strony (łącznie ze źródłami)
Zastąpić:
Z:
niż używać:
Spowoduje to załadowanie strony, zaczekanie na zakończenie, zmaksymalizowanie i skupienie się na niej. Nie wiem, dlaczego tak jest, ale działa.
Jeśli chcesz poczekać na załadowanie strony po kliknięciu na następny lub jakikolwiek inny wyzwalacz nawigacji po stronie inny niż „Nawiguj ()”, odpowiedź Bena Dyera (w tym wątku) załatwi sprawę.
źródło
Spójrz na framework sieciowy gobelinów . Możesz tam pobrać kod źródłowy .
Chodzi o to, aby zasygnalizować gotowość strony za pomocą atrybutu body w html. Możesz wykorzystać ten pomysł zignorować skomplikowane sprawy sądowe.
Następnie utwórz rozszerzenie webdrivera Selenium (zgodnie z frameworkiem tapestry)
Użyj rozszerzenia ElementIsDisplayed napisanego przez Alistera Scotta .
I wreszcie stwórz test:
źródło
Odpowiedź Bena Dryera nie została skompilowana na moim komputerze (
"The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait"
).Działająca wersja Java 8:
Wersja Java 7:
źródło
Wypróbowałem ten kod i działa dla mnie. Wywołuję tę funkcję za każdym razem, gdy przechodzę do innej strony
źródło
W Nodejs możesz to uzyskać dzięki obietnicom ...
Jeśli napiszesz ten kod, możesz być pewien, że strona jest w pełni załadowana, gdy dotrzesz do wtedy ...
Jeśli napiszesz ten kod, będziesz nawigować, a selen poczeka 3 sekundy ...
Z dokumentacji Selenium:
this.get (url) → Thenable
Planuje polecenie przejścia do podanego adresu URL.
Zwraca obietnicę, która zostanie rozwiązana po zakończeniu ładowania dokumentu .
Dokumentacja selenu (Nodejs)
źródło
Czas oczekiwania na zdarzenie document.ready nie jest całkowitym rozwiązaniem tego problemu, ponieważ ten kod jest nadal w stanie wyścigu: czasami ten kod jest uruchamiany przed przetworzeniem zdarzenia kliknięcia, więc zwraca się bezpośrednio, ponieważ przeglądarka nie została uruchomiona ładowanie nowej strony jeszcze.
Po krótkich poszukiwaniach znalazłem post na temat kozła testowego Obay , który ma rozwiązanie tego problemu. Kod C # tego rozwiązania wygląda mniej więcej tak:
`Uruchamiam tę metodę bezpośrednio po pliku driver.navigate.gotourl, aby jak najszybciej uzyskać odwołanie do strony. Baw się dobrze!
źródło
normalnie, gdy selen otwiera nową stronę za pomocą kliknięcia lub przesłania lub pobrania metod, będzie czekał, aż strona zostanie załadowana, ale problem polega na tym, że gdy strona ma wywołanie xhr (ajax), nigdy nie będzie czekać na załadowanie xhr, więc stworzenie nowej metody monitorowania xhr i czekania na nich to będzie dobrze.
if $.active == 0
więc nie ma aktywnego wywołania xhrs (które działa tylko z jQuery). dla wywołania javascript ajax musisz stworzyć zmienną w swoim projekcie i zasymulować ją.źródło
Możesz napisać logikę, aby sobie z tym poradzić. Mam napisać metodę, która zwróci
WebElement
i ta metoda zostanie wywołana trzykrotnie lub możesz zwiększyć czas i dodać zerową kontrolęWebElement
Oto przykładźródło
Wykonałem kod javascript, aby sprawdzić, czy dokument jest gotowy. Zaoszczędziło mi wiele czasu na debugowaniu testów selenu dla witryn, które mają renderowanie po stronie klienta.
}
źródło
źródło
Tak jak Rubanov napisał dla C #, ja piszę to dla Javy i jest to:
źródło
W Javie spodoba się poniżej: -
źródło
return document.readyState == 'loaded' || return document.readyState == 'complete'
Poniższy kod prawdopodobnie powinien działać:
źródło
Jeśli masz wolne połączenie ze stroną lub siecią, istnieje prawdopodobieństwo, że żadne z powyższych nie zadziała. Wypróbowałem je wszystkie i jedyne, co mi zadziałało, to zaczekanie na ostatni widoczny element na tej stronie. Weźmy na przykład stronę internetową Bing. Umieścili ikonę KAMERY (przycisk wyszukiwania według obrazu) obok głównego przycisku wyszukiwania, który jest widoczny dopiero po załadowaniu całej strony. Jeśli wszyscy to zrobili, wszystko, co musimy zrobić, to użyć jawnego oczekiwania, jak w powyższych przykładach.
źródło
źródło
Oto coś podobnego w Rubim:
źródło
Możesz uśpić wątek do ponownego załadowania strony. To nie jest najlepsze rozwiązanie, ponieważ musisz oszacować, jak długo trwa ładowanie strony.
źródło
Sprawdziłem ładowanie strony zakończone, pracuję w Selenium 3.14.0
źródło
Dla osób, które muszą czekać na pojawienie się określonego elementu. (używany C #)
Następnie, jeśli chcesz poczekać, na przykład jeśli w DOM istnieje class = "komunikat o błędzie", po prostu wykonaj:
Dla id będzie to
WaitForElement(driver, By.Id("yourid"));
źródło
Używasz Angulara? Jeśli tak, możliwe, że webdriver nie rozpoznaje zakończenia wywołań asynchronicznych.
Polecam zajrzeć do Paul Hammants ngWebDriver . Przydałaby się metoda waitForAngularRequestsToFinish ().
źródło