Mam aplikację internetową do przetestowania z Selenium. Podczas ładowania strony działa dużo JavaScript.
Ten kod JavaScript nie jest dobrze napisany, ale nie mogę nic zmienić. Czekam więc na pojawienie się elementu w DOM zfindElement()
metodą nie jest opcją.
Chcę utworzyć ogólną funkcję w Javie, aby czekać na załadowanie strony, możliwym rozwiązaniem byłoby:
- uruchom skrypt JavaScript z WebDriver i zapisz wynik
document.body.innerHTML
w zmiennej łańcuchowejbody
. - porównaj
body
zmienną z poprzednią wersjąbody
. jeśli są takie same, ustaw przyrost licznika w przeciwnymnotChangedCount
razie ustawionynotChangedCount
na zero. - poczekaj chwilę (na przykład 50 ms).
- jeśli strona nie zmieniła się od jakiegoś czasu (na przykład 500 ms), tak
notChangedCount >= 10
wyjdź z pętli, w przeciwnym razie przejdź do pierwszego kroku.
Czy uważasz, że to prawidłowe rozwiązanie?
findElement
czeka, aż element będzie dostępny, ale czasami element jest dostępny, zanim kod javascript zostanie całkowicie zainicjowany, dlatego nie jest to opcja.Odpowiedzi:
Gdyby ktokolwiek rzeczywiście znał ogólną i zawsze stosowną odpowiedź, byłaby ona wdrożona wszędzie wieki temu i znacznie ułatwiłaby nam życie.
Jest wiele rzeczy, które możesz zrobić, ale każda z nich ma problem:
Jak powiedział Ashwin Prabhu, jeśli dobrze znasz skrypt, możesz obserwować jego zachowanie i śledzić niektóre z jego zmiennych na
window
lubdocument
itp. To rozwiązanie nie jest jednak dla wszystkich i może być używane tylko przez Ciebie i tylko na ograniczonym zestawie stron.Twoje rozwiązanie poprzez obserwację kodu HTML i to, czy był, czy nie był zmieniany przez jakiś czas, nie jest złe (istnieje również metoda bezpośredniego uzyskania oryginalnego i nieedytowanego HTML
WebDriver
), ale:setTimeout()
) i pracują wielokrotnie i mogą zmieniać kod HTML za każdym razem, gdy są uruchamiane. Poważnie, każda strona „Web 2.0” to robi. Nawet przepełnienie stosu. Możesz nadpisać najczęściej używane metody i uznać skrypty, które ich używają, za ukończone, ale ... nie możesz być pewien.innerHTML
zabawić.Istnieją narzędzia, które Ci w tym pomogą. Mianowicie Progress Listeners wraz z nsIWebProgressListener i kilkoma innymi. Obsługa tego przez przeglądarkę jest jednak straszna. Firefox zaczął próbować go obsługiwać od FF4 (wciąż się rozwija), IE ma podstawowe wsparcie w IE9.
I myślę, że wkrótce mógłbym wymyślić inne wadliwe rozwiązanie. Fakt jest taki, że nie ma jednoznacznej odpowiedzi, kiedy powiedzieć „teraz strona jest kompletna”, ponieważ odwieczne skrypty wykonują swoją pracę. Wybierz ten, który najlepiej Ci służy, ale uważaj na jego wady.
źródło
Dzięki Ashwin!
W moim przypadku powinienem poczekać na wykonanie wtyczki jquery w jakimś elemencie .. konkretnie "qtip"
w oparciu o twoją wskazówkę, zadziałało idealnie dla mnie:
Uwaga: używam Webdriver 2
źródło
Musisz poczekać na zakończenie ładowania JavaScript i jQuery. Wykonaj JavaScript, aby sprawdzić, czy
jQuery.active
jest0
idocument.readyState
jestcomplete
, co oznacza, że ładowanie JS i jQuery zostało zakończone.źródło
document.readyState == 'complete' && jQuery.active == 0
działa świetnie, ale czy jest coś takiego w React? Ponieważ te kontrole nie zostaną złapane, nadal ładowanie danych reaguje / komponentu?Czy biblioteka JS definiuje / inicjalizuje jakąś dobrze znaną zmienną w oknie?
Jeśli tak, możesz poczekać, aż zmienna się pojawi. Możesz użyć
((JavascriptExecutor)driver).executeScript(String script, Object... args)
aby przetestować ten warunek (na przykład
window.SomeClass && window.SomeClass.variable != null
:) i zwrócić wartość logicznątrue
/false
.Zawiń to w a
WebDriverWait
i poczekaj, aż skrypt powrócitrue
.źródło
Miałem ten sam problem. To rozwiązanie działa dla mnie z WebDriverDoku:
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
źródło
Jeśli wszystko, co musisz zrobić, to poczekać, aż kod HTML na stronie ustabilizuje się, zanim spróbujesz wejść w interakcję z elementami, możesz okresowo sondować DOM i porównywać wyniki, jeśli DOM są takie same w podanym czasie ankiety, złoty. Coś takiego, w którym przekazujesz maksymalny czas oczekiwania i czas między ankietami strony przed porównaniem. Proste i skuteczne.
źródło
Poniższy kod działa idealnie w moim przypadku - moja strona zawiera rozbudowane skrypty java
Źródło - jak czekać na załadowanie / gotowość strony w Selenium WebDriver
źródło
Można zastosować dwa warunki, aby sprawdzić, czy strona została załadowana przed znalezieniem dowolnego elementu na stronie:
Użycie poniższego readyState będzie czekać do załadowania strony
Poniżej JQuery będzie czekać, aż dane nie zostaną załadowane
Po tym JavaScriptCode spróbuj znaleźćOut webElement.
źródło
Poprosiłem moich programistów, aby utworzyli zmienną JavaScript „isProcessing”, do której mam dostęp (w obiekcie „ae”), którą ustawiają, gdy wszystko zaczyna działać, i jest jasne, gdy wszystko jest gotowe. Następnie uruchamiam go w akumulatorze, który sprawdza go co 100 ms, aż osiągnie pięć z rzędu, co daje łącznie 500 ms bez żadnych zmian. Jeśli minie 30 sekund, zgłaszam wyjątek, ponieważ do tego czasu coś powinno się wydarzyć. To jest w C #.
źródło
Aby zrobić to poprawnie, musisz obsłużyć wyjątki.
Oto jak mam czekać na iFrame. Wymaga to, aby klasa testowa JUnit przekazała wystąpienie RemoteWebDriver do obiektu strony:
UWAGA: Tutaj możesz zobaczyć cały mój przykład roboczy .
źródło
W przypadku
nodejs
biblioteki Selenium użyłem następującego fragmentu. W moim przypadku, szukałem dwóch obiektów, które zostały dodane do okna, które w tym przykładzie<SOME PROPERTY>
,10000
jest milisekund czasu oczekiwania,<NEXT STEP HERE>
jest to, co dzieje się po właściwości znajdują się w oknie.ź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
Oto z mojego własnego kodu:
Window.setTimeout jest wykonywany tylko wtedy, gdy przeglądarka jest bezczynna.
Tak więc rekurencyjne wywołanie funkcji (42 razy) zajmie 100 ms, jeśli przeglądarka nie jest aktywna, i dużo więcej, jeśli przeglądarka jest zajęta czymś innym.
Jako bonus, licznik można zresetować na document.readyState lub na wywołaniach jQuery Ajax lub jeśli są uruchomione animacje jQuery (tylko jeśli Twoja aplikacja używa jQuery do wywołań ajax ...)
...
...
EDYCJA: Zauważyłem, że executeAsyncScript nie działa dobrze, jeśli ładuje się nowa strona, a test może przestać odpowiadać w nieskończoność, lepiej zamiast tego użyć tego.
źródło
Nie wiem, jak to zrobić, ale w moim przypadku koniec ładowania i renderowania strony pasuje do FAVICON wyświetlanego w zakładce Firefox.
Więc jeśli uda nam się pobrać obraz ikony ulubionych w przeglądarce internetowej, strona jest w pełni załadowana.
Ale jak to wykonać ...
źródło
U mnie działa niejawne oczekiwanie.
Zapoznaj się z tą odpowiedzią Selenium c # Webdriver: Czekaj, aż element będzie obecny
źródło
Oto jak to robię:
źródło
Podoba mi się twój pomysł przeszukiwania kodu HTML, aż będzie stabilny. Mogę dodać to do własnego rozwiązania. Poniższe podejście jest w C # i wymaga jQuery.
Jestem programistą projektu testowego SuccessFactors (SaaS), w którym nie mamy żadnego wpływu na programistów ani na cechy DOM za stroną internetową. Produkt SaaS może potencjalnie zmienić swój podstawowy projekt DOM 4 razy w roku, więc trwają poszukiwania solidnych, wydajnych sposobów testowania z Selenium (w tym NIE testowania z Selenium, jeśli to możliwe!)
Oto, czego używam do określenia „gotowa strona”. Obecnie działa we wszystkich moich własnych testach. To samo podejście działało również w przypadku dużej wewnętrznej aplikacji internetowej Java kilka lat temu i było solidne przez ponad rok, gdy opuściłem projekt.
Driver
to instancja WebDriver, która komunikuje się z przeglądarkąDefaultPageLoadTimeout
jest wartością limitu czasu w taktach (100ns na takt)W dalszej części zwróć uwagę na kolejność czekania w metodzie
PageReady
(dokument Selenium gotowy, Ajax, animacje), co ma sens, jeśli się nad tym zastanowić:Coś takiego, jak podejście do porównywania DOM, może być użyte między 1 a 2, aby dodać kolejną warstwę niezawodności.
źródło