Kontynuując naszą przygodę z automatyzacją nie sposób pominąć kilka dobrych praktyk związanych z lokalizacją oraz wykonywaniem akcji na elementach, do których chcemy odwołać się w naszych testach.
Poniższy tekst zawiera najważniejsze kwestie związane z podstawowym wykorzystaniem klasy WebElement, my jednak zapraszamy Was do zapoznania się z materiałem filmowym. Znajdziecie w nim m.in.: rozwinięcie lokalizacji elementów oraz akcji przeprowadzanych na nich, przykłady poparte kodem, kilka dodatkowych dobrych praktyk związanych nie tylko z klasą WebElement, ale również z rozbudową struktury projektu w celu uzyskania bardziej czytelnej struktury.
A więc zaczynajmy!
Podstawa merytoryczna
Jedną z nieodłącznych części naszych testów jest klasa “WebElement”. Pisząc nasze testy, gdy wymagane jest wykonanie konkretnej akcji na wybranym elemencie znajdującym się na analizowanej przez nas stronie musimy posiłkować się klasą WebElement.
Pomińmy na ten moment dodatkowe rozwiązania wspomagające wykonywanie akcji na wybranym elemencie oraz ich lokalizację. Opowiemy o nich w jednym z przyszłych materiałów. W takim przypadku dzięki klasie WebElement generalnie będziemy wykonywać wszystkie najważniejsze operacje związane z interakcją z elementami na testowanej stronie.
Chcąc stosować dobre praktyki związane z wybraną klasą musimy znać jej przeznaczenie oraz podstawy do jej wykorzystania.
A więc powiedzmy sobie na początek czym jest klasa WebElement, a raczej poprawnie mówiąc “Interfejs WebElement”.
Interfejs WebElement reprezentuje element w kodzie HTML. Wszystkie wywołania metod dla interfejsu WebElement sprawdzają czy element znajduje się nadal w podanym miejscu. Oczywiście akcja ta przeprowadzana jest aby upewnić się, że odwołanie do elementu jest nadal poprawne. Zasadniczo określa to, czy element jest nadal dołączony do DOM. Jeżeli akcja (weryfikacja) ta się nie powiedzie, zostanie zwrócony StaleElementReferenceException, a wszystkie przyszłe wywołania tej instancji zakończą się niepowodzeniem.
Lokalizacja
Kiedy chcemy odnaleźć wybrany element i odwołać się do niego w naszym teście musimy posłużyć się jedną z podstawowych metod dla interfejsu WebElement.
Metoda, o której mowa to: findElement(By by). Służy ona do odnalezienia (pierwszego elementu ) przez podaną metodę.
Korzystając z w/w metody możemy posłużyć się kilkoma lokatorami, które umożliwią nam odnalezienie wybranego elementu na testowanej stronie, są to:
- Id
- Name
- CssSelector
- XPath
- LinkText
- PartialLinkText
- ClassName
- TagName
id:
By id(String);
Zgodnie z przyjętymi standardami atrybut “id” jest unikalny z tego też względu jest on najlepszym lokatorem.
Dobre praktyki wskazują by używać go zawsze wtedy, kiedy występuje taka możliwość.
Przykład:
driver.findElement(By.id("email"));
Name:
By name(String);
przeszukujemy strukturę strony w celu odnalezienia elementu po wartości atrybutu name w kodzie HTML testowanej strony. Jest to jedna z alternatyw gdy nie posiadamy unikalnego atrybutu “id”.
Pamiętajmy że wykorzystanie selektora “name” wiąże się z pewnym ryzykiem m.in.: gdy staramy się odwołać do elementu który który jest wielokrotnie powielony na testowanej stronie np. przycisk logowania, a co za tym idzie będzie miał taką samą wartość dla atrybutu.
Przykład:
driver.findElement(By.name("login"));
CssSelector:
By cssSelector(String);
Rozwiązanie to bazuje na kaskadowych arkuszach stylów. Dobrą praktyką jest używanie selektora css jako alternatywy dla XPath. Mocną stroną w porównaniu do XPath jest prostsza budowa selektora css, jak również szybsze odnajdywanie elementów podczas przeszukiwania struktury testowanej strony.
Przykład:
driver.findElement(By.cssSelector("input#login"));
XPath:
By xpath(String);
Dzięki temu rozwiązaniu przeszukujemy strukturę testowanej strony wykorzystując względną lub bezwzględną ścieżkę do wybranego elementu.
Zdarzają się sytuacje, w których elementy na testowanej stronie nie są jednoznacznie oznaczone przez id lub name i zachodzi konieczność zlokalizowania takiego elementu za pomocą XPath’ów.
Dobre praktyki mówią jednak, by korzystanie z selektora XPath było ostatecznością. Słaba strona tego rozwiązania ujawnia się gdy np. w ścieżce do naszego elementu zostaną poczynione zmiany, w takim przypadku XPath również ulegnie zmianie, a co za tym idzie będzie to skutkować błędem w kodzie naszego testu.
Drugą wadą wykorzystania XPath’ów w naszym kodzie jest szybkość lokalizowania elementów. Skomplikowana budowa XPath’a, oraz konieczność przeszukiwania całej struktury HTML DOM stawia to rozwiązanie na dalszym polu w porównaniu do innych rozwiązań.
Przykład dla ścieżki względnej:
//*[@id="password"]
Przykład dla ścieżki bezwzględnej:
/html/body/section/header/div/div/div/form/div[5]/div[1]/label
Więcej informacji na temat XPath’ów znajdziecie tutaj >>
LinkText:
By linkText(String);
To rozwiązanie lokalizuje element po jego treści. Należy pamiętać, że wpisując tekst, po którym chcemy szukać, musi on w 100% odpowiadać tekstowi na elemencie. Nawet brakująca spacja spowoduje błąd. Dobrze jest pamiętać o możliwym ryzyku językowym.
Przykład:
driver.findElement(By.linkText("Nie pamiętam hasła"));
PartialLinkTest:
By partialLinkText(String);
Jeżeli znamy tylko fragment tekstu, który zawiera element, powinniśmy użyć tego lokatora.
Pamiętajmy, by mieć świadomość związaną z możliwym ryzykiem związanym z błędami językowymi oraz możliwością wystąpienia wielu elementów na testowanej stronie które zawierają dany fragment tekstu.
Przykład:
driver.findElement(By.partialLinkText("pamiętam"));
ClassName:
By className(String);
Przeszukujemy strukturę strony w celu odnalezienia elementu wykorzystując nazwę klasy.
Pamiętajmy jednak, że klasa nie musi być unikalna w wybranym dokumencie. Nawet jeżeli jest ona obecna w danej chwili to w przyszłości może zostać dodany kolejny element z taką samą klasą, co może skutkować problemami w naszych testach.
Przykład:
driver.findElement(By.className("icons-switch"));
TagName:
By tagName(String);
możemy zlokalizować elementy w strukturze testowanej strony po ich tagach HTML-owych.
Przykład:
driver.findElement(By.tagName("title"));
Akcje
Jak widzimy wyżej, interfejs WebElement daje nam szereg opcji do wykorzystania, gdy potrzebujemy odnaleźć wybrany element w strukturze testowanej strony.
Co jednak dalej...? Czy to wszystko...?
Co w przypadku, gdy na wyszukanym elemencie w strukturze testowanej strony chcemy przeprowadzić jakąś akcję?
I w tym przypadku wykorzystując obiekty WebElement otrzymujemy szereg różnego typu rozwiązań.
Prostą akcję na wybranym elemencie możemy wykonać korzystając z jednej linii kodu: driver.findElement(By by)).name_of_action();
Jak widzimy w tym momencie przeszukujemy strukturę testowanej strony, a następnie wykonujemy akcję na odnalezionym elemencie.
Przedstawmy sobie zatem kilka podstawowych akcji, które wykorzystywane są podczas tworzenia testów automatycznych.
Click: click();
Wykorzystując tą akcje możemy dosłownie kliknąć w odnaleziony element, w taki sposób jak zrobilibyśmy to np. przyciskiem myszki.
Pamiętajmy, że w przypadku gdy kliknięcie w element spowoduje przejście na inną stronę, powinniśmy usunąć wszystkie odniesienia do tego elementu, w innym przypadku każda akcja na tym elemencie zwróci nam: StaleElementReferenceException
Istnieją również pewne warunki wstępne, które muszą być spełnione by użyć wybranej akcji:
- Wybrany element w który chcemy kliknąć musi być widoczny;
- Element na którym wykonujemy tą akcję musi mieć szerokość oraz wysokość większą od 0.
Pamiętajmy również, gdy akcja kliknięcia wykonana jest przez wysłanie natywnego zdarzenia (domyślnego dla większości przeglądarek / platform) wtedy metoda nie zaczeka aż zostanie załadowana następna strona i musimy to dodatkowo zweryfikować, np. oczekując pewien okres czasu.
Przykład:
driver.findElement(By.id("login")).click();
SendKeys: sendKeys();
Metoda ta używana jest do symulacji wpisywania znaków na klawiaturze przez użytkownika w wybrane pole. Jeżeli w jakimś przypadku wartość dla wykonywanej akcji wynosi “null” wtedy zostanie zwrócony: java.lang.IllegalArgumentException
Przykład:
driver.findElement(By.id("email")).sendKeys(String);
Clear: clear();
Jeżeli element na którym chcemy wykonać tą akcję jest polem tekstowym (INPUT oraz TEXTAREA) wtedy pozwoli ona nam na wyczyszczenie pola z wprowadzonych wartości. Akcja ta natomiast nie ma zastosowania w przypadku innych elementów. Pamiętajmy jednak, że nie wykonujemy tutaj akcji dla klawiatury bądź myszki. Jeżeli chcemy wykonać akcję np. dla klawiatury powinniśmy raczej wykorzystać akcję: sendKeys(); dla klawisza backspace
Przykład:
driver.findElement(By.id("email")).clear();
GetText: getText();
Akcja ta pozwala nam na pobranie tekstu umieszczonego wewnątrz (pomiędzy tagami) elementu, w tym również podelementów. Pamiętajmy by akcja została wykonana poprawnie, tekst musi być widoczny, nie przysłonięty np. przez CSS.
Przykład:
driver.findElement(By.className("required_text")).getText();
W tej chwili, gdy poznaliśmy podstawy związane z wykorzystaniem interfejsu WebElement możemy bez większych problemów wykorzystać tą wiedzę do napisania testów automatycznych.
Pamiętajmy o dobrych praktykach oraz zasadach wykorzystywania interfejsu WebElement, a także akcji dostępnych dla obiektów WebElement, a w miarę upływu czasu zdobywając praktykę nasze testy będą coraz lepsze.
Na tym kończymy dzisiejszy materiał, jeszcze raz zapraszając Was do zapoznania się z materiałem filmowym udostępnionym na naszym kanale.
Dla przypomnienia, znajdziecie tam m.in.: przykłady testów poparte kodem w środowisku InteliiJ, omówienie lokalizatorów oraz akcji dostępnych dla obiektów WebElement również z dodatkowymi przykładami nie opisanymi w powyższym artykule, i inne.
Trzymajcie się, HEJ!
Autor: Krzysztof Kołodziejczyk