Największą przeszkodą w testowaniu ExtJS z Selenium jest to, że ExtJS nie renderuje standardowych elementów HTML, a Selenium IDE naiwnie (i słusznie) generuje polecenia skierowane do elementów, które działają tylko jako dekoracje - zbędne elementy, które pomagają ExtJS z całym pulpitem- widzieć i czuć. Oto kilka wskazówek i sztuczek, które zebrałem podczas pisania automatycznego testu Selenium dla aplikacji ExtJS.
Ogólne wskazówki
Lokalizowanie elementów
Podczas generowania przypadków testowych Selenium poprzez rejestrowanie działań użytkownika za pomocą Selenium IDE w przeglądarce Firefox, Selenium oprze zarejestrowane działania na identyfikatorach elementów HTML. Jednak w przypadku większości klikalnych elementów ExtJS używa wygenerowanych identyfikatorów, takich jak „ext-gen-345”, które prawdopodobnie zmienią się podczas kolejnej wizyty na tej samej stronie, nawet jeśli nie wprowadzono żadnych zmian w kodzie. Po zarejestrowaniu działań użytkownika na potrzeby testu należy wykonać ręcznie wszystkie czynności, które zależą od wygenerowanych identyfikatorów, i je zastąpić. Istnieją dwa rodzaje zamienników, które można wykonać:
Zastąpienie lokalizatora identyfikatora lokalizatorem CSS lub XPath
Lokalizatory CSS zaczynają się od „css =”, a lokalizatory XPath zaczynają się od „//” (przedrostek „xpath =” jest opcjonalny). Lokalizatory CSS są mniej szczegółowe i łatwiejsze do odczytania i powinny być preferowane względem lokalizatorów XPath. Jednak mogą wystąpić przypadki, w których trzeba użyć lokalizatorów XPath, ponieważ lokalizator CSS po prostu nie może ich wyciąć.
Wykonywanie JavaScript
Niektóre elementy wymagają czegoś więcej niż tylko prostych interakcji myszy / klawiatury ze względu na złożone renderowanie wykonywane przez ExtJS. Na przykład Ext.form.CombBox nie jest w rzeczywistości <select>
elementem, ale tekstem z odłączoną listą rozwijaną, która znajduje się gdzieś na dole drzewa dokumentu. Aby poprawnie zasymulować wybór ComboBox, można najpierw zasymulować kliknięcie strzałki rozwijanej, a następnie kliknięcie wyświetlonej listy. Jednak lokalizowanie tych elementów za pomocą lokalizatorów CSS lub XPath może być kłopotliwe. Alternatywą jest zlokalizowanie samego komponentu ComoBox i wywołanie na nim metod w celu zasymulowania wyboru:
var combo = Ext.getCmp('genderComboBox');
combo.setValue('female');
combo.fireEvent('select');
W Selenium runScript
polecenie może być użyte do wykonania powyższej operacji w bardziej zwięzłej formie:
with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Radzenie sobie z AJAX i Slow Rendering
Selenium ma smaki "* AndWait" dla wszystkich poleceń czekających na załadowanie strony, gdy akcja użytkownika skutkuje przejściem strony lub ponownym załadowaniem. Ponieważ jednak pobieranie AJAX nie obejmuje faktycznego ładowania strony, tych poleceń nie można używać do synchronizacji. Rozwiązaniem jest wykorzystanie wizualnych wskazówek, takich jak obecność / brak wskaźnika postępu AJAX lub wygląd wierszy w siatce, dodatkowe komponenty, linki itp. Na przykład:
Command: waitForElementNotPresent
Target: css=div:contains('Loading...')
Czasami element pojawia się dopiero po pewnym czasie, w zależności od tego, jak szybko ExtJS renderuje komponenty po tym, jak akcja użytkownika powoduje zmianę widoku. Zamiast używać arbitralnych opóźnień przy pause
poleceniu, idealną metodą jest zaczekanie, aż interesujący nas element znajdzie się w naszym zasięgu. Na przykład, aby kliknąć element po odczekaniu, aż się pojawi:
Command: waitForElementPresent
Target: css=span:contains('Do the funky thing')
Command: click
Target: css=span:contains('Do the funky thing')
Poleganie na arbitralnych przerwach nie jest dobrym pomysłem, ponieważ różnice czasowe wynikające z uruchamiania testów w różnych przeglądarkach lub na różnych komputerach spowodują, że przypadki testowe będą niestabilne.
Elementy nieklikalne
Niektórych elementów nie można wywołać click
poleceniem. Dzieje się tak, ponieważ detektor zdarzeń znajduje się w kontenerze, obserwując zdarzenia myszy w elementach podrzędnych, które ostatecznie pojawiają się w nadrzędnym. Kontrolka karty jest jednym z przykładów. Aby kliknąć zakładkę, musisz zasymulować mouseDown
zdarzenie na etykiecie zakładki:
Command: mouseDownAt
Target: css=.x-tab-strip-text:contains('Options')
Value: 0,0
Walidacja pola
Pola formularza (komponenty Ext.form. *), Które mają skojarzone wyrażenia regularne lub vtypes do walidacji, wyzwalają walidację z pewnym opóźnieniem (patrz validationDelay
właściwość, która jest domyślnie ustawiona na 250 ms), po wprowadzeniu tekstu przez użytkownika lub natychmiast po utracie pola focus - lub rozmywa (zobacz validateOnDelay
właściwość). Aby wyzwolić walidację pola po wydaniu polecenia typu Selenium w celu wprowadzenia tekstu w polu, należy wykonać jedną z następujących czynności:
Wyzwalanie opóźnionej walidacji
ExtJS odpala licznik czasu opóźnienia walidacji, gdy pole otrzymuje zdarzenia keyup. Aby uruchomić ten licznik czasu, po prostu wydaj fałszywe zdarzenie klucza (nie ma znaczenia, którego klucza używasz, ponieważ ExtJS go ignoruje), a następnie krótką pauzę dłuższą niż validationDelay:
Command: keyUp
Target: someTextArea
Value: x
Command: pause
Target: 500
Wyzwalanie natychmiastowej weryfikacji
Możesz wstrzyknąć zdarzenie rozmycia w pole, aby uruchomić natychmiastową weryfikację:
Command: runScript
Target: someComponent.nameTextField.fireEvent("blur")
Sprawdzanie wyników walidacji
Po sprawdzeniu poprawności możesz sprawdzić obecność lub brak pola błędu:
Command: verifyElementNotPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Command: verifyElementPresent
Target: //*[@id="nameTextField"]/../*[@class="x-form-invalid-msg" and not(contains(@style, "display: none"))]
Zwróć uwagę, że sprawdzenie "display: none" jest konieczne, ponieważ po wyświetleniu pola błędu, a następnie trzeba je ukryć, ExtJS po prostu ukryje pole błędu zamiast całkowicie usunąć je z drzewa DOM.
Wskazówki dotyczące poszczególnych elementów
Kliknięcie Ext.form.Button
opcja 1
Polecenie: kliknij Cel: przycisk css =: zawiera ('Zapisz')
Zaznacza przycisk według jego podpisu
Opcja 2
Polecenie: kliknij przycisk Cel: css = # opcje zapisywania
Wybiera przycisk według jego identyfikatora
Wybieranie wartości z Ext.form.ComboBox
Command: runScript
Target: with (Ext.getCmp('genderComboBox')) { setValue('female'); fireEvent('select'); }
Najpierw ustawia wartość, a następnie jawnie uruchamia wybrane zdarzenie w przypadku obecności obserwatorów.