2012-11-02 13 views
7

Używam Rails 3.2.8 zrails3-jquery-autocomplete: jak testować z RSpec i Capybara?

  • gem 'jQuery szyn', '2.1.2'
  • gem 'rails3-jQuery autouzupełniania', '1.0.9'
  • gem 'rspec barierki', '2.11.4'
  • gem 'Kapibara', '1.1.3'
  • gem 'kapibary-WebKit', '0.12.1'

I niedawno konwertowane wybierz rozwijaną listę do autouzupełniania (nas ing rails3-jquery-autocomplete) i próbuję zaktualizować specyfikacje żądań, aby wypełnić autouzupełnianie.

Moje podejście było stworzenie pomocnika, jak pokazano na this gist:

def fill_autocomplete(field, options = {}) 
    fill_in field, :with => options[:with] 

    selector = "ul.ui-autocomplete a:contains('#{options[:select]}')" 

    page.should have_selector selector 
    page.execute_script "$(\"#{selector}\").mouseenter().click()" 
end 

Gdybym sprawdzić, z Webkit, test nie powiedzie się z tej wiadomości:

expected css "ul.ui-autocomplete a:contains('Firstname Lastname')" to return something. 

Gdybym test z selen , gdy oglądam test w Firefoksie, robię , a nie, pojawia się rozwijana lista wyboru. Dodawanie sleep 3, aby czekać na rozwijanie nie pomaga.

Widzę here, że istnieje powiązany, ale nieco stary problem z kapibara-webkit, coś o tym, kiedy pole jest wypełnione, jest natychmiast rozmyte, co oczywiście uniemożliwiłoby wyświetlenie listy wyboru autouzupełniania. Ale to nie wydaje się jibe z innymi, którzy mają to do pracy.

Czy jest obecnie możliwe przetestowanie formularza zawierającego pole rails3-jquery-autocomplete z RSpec i Capybara? W jaki sposób? Jeśli nie, czy istnieje sposób ręcznego wypełnienia odpowiedniego, ukrytego pola id, aby móc przetestować, czy formularz tworzy poprawne dane?

Odpowiedz

9

W końcu otrzymałem testy autouzupełniania działające przynajmniej ze sterownikiem Selenium.

Rozwiązaniem jest skoncentrowanie się na polu i wydawanie zdarzenia kluczowego.

Najpierw potwierdziłem to testowaniem ręcznym w przeglądarce. Jeśli użyję myszy (nie CTRL + V), aby wkleić wyszukiwany termin do pola autouzupełniania, nic się nie dzieje - nie jest wyświetlana rozwijana lista wyboru. Jest to najwyraźniej odpowiednik tego, co dzieje się, gdy Capybara wysyła polecenie fill_in. Jednak po tym, jak termin znajduje się w polu, gdy fokus nadal znajduje się na polu, jeśli dotknę dowolnego klawisza, np. Klawisz Shift, pojawi się lista wyboru. Najwyraźniej lista wyboru pojawia się tylko po naciśnięciu klawisza.

Wariant 1

Jednym z rozwiązań jest rozszerzenie funkcji z pierwotnego pytania w następujący sposób:

def fill_autocomplete(field, options = {}) 
    fill_in field, :with => options[:with] 

    page.execute_script %Q{ $('##{field}').trigger("focus") } 
    page.execute_script %Q{ $('##{field}').trigger("keydown") } 
    selector = "ul.ui-autocomplete a:contains('#{options[:select]}')" 

    page.should have_selector selector 
    page.execute_script "$(\"#{selector}\").mouseenter().click()" 
end 

a następnie połączyć je w następujący sposób:

fill_autocomplete "to_contact_name", with: "Jone", select: "Bob Jones" 

Wariant 2

W podobny sposób, uzyskano z Steak test w głównym rails3-jquery-autouzupełniania gem wykorzystuje standardową FILL_IN, a następnie ten choose_autocomplete_result:

def choose_autocomplete_result(item_text, input_selector="input[data-autocomplete]") 
    page.execute_script %Q{ $('#{input_selector}').trigger("focus") } 
    page.execute_script %Q{ $('#{input_selector}').trigger("keydown") } 
    # Set up a selector, wait for it to appear on the page, then use it. 
    item_selector = "ul.ui-autocomplete li.ui-menu-item a:contains('#{item_text}')" 
    page.should have_selector item_selector 
    page.execute_script %Q{ $("#{item_selector}").trigger("mouseenter").trigger("click"); } 
end 

który nazywany jest tak jak:

fill_in "to_contact_name", :with => "Jone" 
choose_autocomplete_result "Bob Jones", "#to_contact_name" 

Przyjąłem drugie podejście do moich testów. Wydaje się całkiem niezawodny w przypadku Selenium, ale nie działa z webkitem, co jest zbyt złe, ponieważ testy Selenium są dość powolne w porównaniu. Rozwiązanie, które działa pod webkit byłoby mile widziane!

+1

Tak, to nie działa z Webkit. Testuję to na capybara + poltergeist (webkit env), który rozbił się na sprawdzeniu poprawności have_selector. kiedy debuguję go, wykonując screencast, stwierdziłem, że element autouzupełniania został wygenerowany, ale obiekt strony nie może go rozpoznać – raykin

+2

Twoje rozwiązanie 1 opcji nie działa z powodu faktu, że ': zawiera' nie jest prawidłowymi selektorami CSS W3C (to jest tylko jQuery). Naprawiłem to za pomocą rozwiązania wymienionego w http: // stackoverflow.com/questions/6355586/testing-jquery-autocomplete-ui-with-cucumber pod moim imieniem –

0

Zamiast używać page.execute_script, po wprowadzeniu wypełniłem dane wejściowe pustym miejscem, aby zdarzenie się uruchomiło.

fill_in("query", :with => "ma") 
fill_in("query", :with => "") 
# autocomplete suggestions will come up 
all('.autocomplete div').first.should have_content("mango") 
# other assertions 
3

Ja też wpadłem na ten sam ból. Po spędzeniu kilku godzin na tym, mam jednego dobrego pomocnika, który działa zarówno z selenem i polstergeist plus bez użycia sleep(). Poniższy kod został przetestowany z Kapibara 2.1.0:

def fill_autocomplete(field, options = {}) 
    fill_in field, with: options[:with] 

    page.execute_script %Q{ $('##{field}').trigger('focus') } 
    page.execute_script %Q{ $('##{field}').trigger('keydown') } 
    selector = %Q{ul.ui-autocomplete li.ui-menu-item a:contains("#{options[:select]}")} 

    page.should have_selector('ul.ui-autocomplete li.ui-menu-item a') 
    page.execute_script %Q{ $('#{selector}').trigger('mouseenter').click() } 
    end 

Zasadniczo, mówię Capybara wypełnić pola wejściowego następnie użyć JS wywołać zdarzenie keydown aktywować autouzupełniania. Jednak zamiast sleep(), korzystam z page.should have_selector('ul.ui-autocomplete li.ui-menu-item a'), które czekają aż pojawi się lista rozwijana. Następnie używam JS, aby wywołać zdarzenie mouseenter, a następnie kliknij. Żałuję, że nie ma lepszego sposobu niż robienie rzeczy z JS eval, ale jest to najbardziej niezawodne rozwiązanie, które mogłem wymyślić.

+1

Keydown nie uruchamia kodu autouzupełniania przy pomocy Poltergeist. Zweryfikowałem to, dodając na ekranie fałszywe okno wprowadzania danych i dołączając do niego odbiornik o kluczowym znaczeniu, który powoduje, że obiekt testowy jest widoczny lub niewidoczny. Następnie robię zrzut ekranu przed i po teście. Tak więc wiem, że zdarzenie keydown jest wyzwalane, ale z jakiegokolwiek powodu NIE wyzwala kodu autouzupełniania, który działa tak dobrze w przeglądarce. Czy masz jakiś pomysł? Spędziłem prawie 48 godzin pracy nad tym i po prostu nie mogę się przedostać. – AKWF

2

Jeśli ktoś potrzebuje kod do inspiracji (zajęło mi to trochę czasu, nawet po przeczytaniu tego wątku), to działa:

 context "with 5 items results" do 
     before do 
      5.times { FactoryGirl.create(:item, title: "chinese " + random_string(5)) } 
      page.execute_script("$('input#search_param').val('chinese')") 
      page.execute_script("$('input#search_param').trigger('focus')") 
      page.execute_script("$('input#search_param').trigger('keydown')") 
     end 
     specify { page.evaluate_script("$('input#search_param').val()").should == 'chinese' } 
     specify { page.should have_css "#autocomplete-menu li", count: 5 } 
     end 

Dzięki Mark Berry dla inspiracji.

1

Inną opcją jest kapibara send_keys metoda:

find('#my_object_id').send_keys 'bob'

wolę tę opcję na wstrzyknięcie JavaScript ognia keyDown wydarzenia/focus/mouseenter.

Powiązane problemy