2013-05-30 11 views
10

Mam aplikację, która używa KnockoutJS i próbuję napisać kilka testów, które testują formularz. Jeśli nie znasz KnockoutJS, opowiadanie tego jest takie, że zapewnia powiązania z mojego widoku z moim modelem danych. Oznacza to, że po wpisaniu wartości w polu wejściowym mój obiekt bazowy jest automatycznie aktualizowany o tę wartość pól wejściowych. Odbywa się to domyślnie poprzez zmianę zdarzenia.WebDriver: Zmień zdarzenie nie odpalam

Problem polega na tym, że gdy mój test WebDriver wpisuje się w polu, zdarzenie change nie jest uruchamiane, więc mój bazowy model danych nie ma odpowiednich wartości. Powoduje to niepowodzenie sprawdzania poprawności formularza, gdy nie powinien.

Zrobiłem wszystko, co mogłem znaleźć w Internecie, aby to zadziałało. Mam:

  1. wysłał kartę klucza
  2. kliknięciu dala od pola formularza
  3. wysłać kod JavaScript do ognia ostrości i rozmycia zdarzenia (walidacja występuje na rozmycie)
  4. kliknięciu pola formularza przed wpisaniem
  5. zestaw czeka tylko okrywać to był problem z synchronizacją
  6. zmieniły KnockoutJS zaktualizować pole wprowadzania na afterkeydown

Żadne z nich nie sprawdziło się u mnie. Potrzebuję jakiejś pomocy.

Ponadto zweryfikowałem, że nie jest to problem z bąbelkami zdarzeń, ponieważ usunąłem wszystkie inne zdarzenia jawnie, pozostawiając tylko zdarzenie zmiany KnockoutJS.

Rozwiązanie, którego szukam, to takie, które działa dla wszystkich sterowników przeglądarki (... przynajmniej głównych, np. IE, FF, Chrome, Safari) i nie wymaga korzystania z jQuery.

Każda pomoc zostanie bardzo doceniona.

Oto kod względne Używam wpisać wartości w polu:

// find element 
WebElement input = this.element.findElement(By.className("controls")) 
           .findElement(By.tagName("input")); 

// to set focus? 
input.click(); 

// erase any existing value (because clear does not send any events 
for (int i = 0; i < input.getAttribute("value").length(); i++) { 
    input.sendKeys(Keys.BACK_SPACE); 
} 

// type in value 
input.sendKeys(text); 

// to fire change & blur? (doesnt fire change) 
//input.sendKeys(Keys.TAB); 

// to fire change & blur? (doesnt fire change) 
driver.findElement(By.tagName("body")).click(); 
+0

Więc jeśli jestem zrozumienie, aktualizuje pola 'input' z każdym naciśnięciu klawisza? – Brian

+0

Proszę mi wybaczyć, że zadałem potencjalnie głupie pytanie, ale czy dana strona działa poprawnie, kiedy ręcznie wchodzisz z nią w przeglądarkę? np. jeśli przeglądasz stronę w przeglądarce, wpisujesz pole tekstowe i tabulator z pola tekstowego, czy model jest aktualizowany? – RodneyTrotter

+1

@ Brian pole wprowadzania jest aktualizowane przez użytkownika. bazowy model danych jest aktualizowany do wartości w polu wejściowym, gdy zdarzenie onchange jest uruchamiane (przynajmniej powinno). A jeśli zmienię wartość bazową w modelu danych, pole wejściowe zostanie automatycznie zaktualizowane do nowej wartości. Wszystko to zapewnia KnockoutJS. – loesak

Odpowiedz

4

Sądzę, że dowiedziałem się o moim problemie. W pełni przyznam, że to był PEBKAC. Zapomniałem, że WebDriver ma problemy, jeśli okno przeglądarki nie znajduje się w aktywnym ognisku na komputerze (co wciąż jest dla mnie dziwne). Kiedy debugowałem problem, korzystałem z edytora, aby przejść przez ten kod. Po uruchomieniu kodu normalnie i bez usuwania fokusu z przeglądarki zdarzenia są uruchamiane zgodnie z oczekiwaniami przy użyciu wszystkich trzech rozwiązań (tabulacja, kliknięcie i javascript).

Mam przykładowy projekt pokazujący wszystkie trzy metody, jednak jestem głównym noobem z git i github i mam problemy z dostarczeniem projektu. Kiedy to stwierdzę, podzielę się z wami projektem.

EDIT: Otrzymałem przykładowy kod na GitHub (https://github.com/loesak/knockout.webdriver.change.event.test). Możesz uruchomić projekt jako aplikację webową na serwerze i uruchomić test ręcznie lub możesz uruchomić testy przez maven (mvn clean install). Nie włożyłem wiele wysiłku w sprawne działanie tej funkcji, więc zakładam, że masz zainstalowaną przeglądarkę Firefox i port 8080 jest otwarty.

EDIT: Fixed podano numer portu

+0

Gratulujemy rozwiązania problemu +1. – Brian

3

Więc znaleźli sposób na obejście tego problemu teraz, ale zdecydowanie mogę uwierzyć, że to jest poprawne rozwiązanie. To łamie moją zasadę dotyczącą nieużywania jQuery, jednak czuję, że to jest w porządku dla mnie, ponieważ KnockoutJS wymaga załadowania jQuery. Prawdopodobnie istnieje prosty sposób, aby to zrobić. Testowałem to z FireFox, Safari i PhantomJS. Zakładam, że będzie działać równie dobrze w Chrome. Nie daję obietnic dla Internet Explorera.

Jestem NOT zamierzam oznaczyć tę odpowiedź jako poprawną odpowiedź. Prawidłowe rozwiązanie powinno polegać na przeglądaniu przeglądarek WebDriver odpowiednich zdarzeń. Tylko wtedy, gdy uważam, że nie jest to możliwe przez WebDriver, zaznaczę to jako poprawną odpowiedź.

// find element in question 
WebElement input = this.element.findElement(By.className("controls")) 
           .findElement(By.tagName("input")); 

// click it to fire focus event 
input.click(); 

// erase any existing value 
for (int i = 0; i < input.getAttribute("value").length(); i++) { 
    input.sendKeys(Keys.BACK_SPACE); 
} 

// enter in desired text 
input.sendKeys(text); 

// fire on change event (WebDriver SHOULD DO THIS) 
((JavascriptExecutor) driver).executeScript(
     "$(arguments[0]).change(); return true;" 
    , input); 

// click away to fire blur event 
driver.findElement(By.tagName("body")).click(); 
+0

Jeśli możesz podać odtwarzalny scenariusz i ** udowodnić ** jest to problem z WebDriver, a następnie zgłoś błąd. – Arran

+0

, więc stworzyłem projekt do odtworzenia tego i w ten sposób odkryłem problem. krótko mówiąc, jest to błędny błąd. Połączyłem się z projektem demonstracyjnym, ale moja głupia noobność uniemożliwia mi sprawdzenie w projekcie. – loesak

Powiązane problemy