2014-04-29 6 views
9

Wie kann ich einen Capybara-Integrationstest mit einem Formular unter Verwendung von jquery.selectize schreiben?Capybara-Integrationstests mit jquery.selectize

Ich möchte einen Benutzer testen, der ein paar Werte eingibt.

+2

Erklärungen für -1s sind immer willkommen. –

+1

Ja, es ist immer ärgerlich, wenn du keinen Kommentar für nicht wirklich offensichtlich hast. Downvote = \ Wahrscheinlich sollten wir etwas vorschlagen, das Reputation für das Ablehnen ohne Kommentar schmälert – ted

+0

Es gab [Diskussion darüber] (http: // meta .stackexchange.com/questions/135/ermutigende-Leute-zu-erklären-downvotes) –

Antwort

0

selectize nutzt alle wichtigen Ereignisse (keydown, keypress, keyup) eine große UI zur Verfügung zu stellen, aber scheint nicht eine einfache Möglichkeit, um Daten von Javascript zu setzen.

Eine Lösung besteht darin, die Bibliothek syn.js zu verwenden, um die richtigen Schlüsselereignisse auszulösen. Hier ist ein Helfer, die funktioniert:

def fill_in_selectize_area selector, options 
    # Syn appears to require an id, so assign a temporary one 
    @selectize_unique_id ||= 0 
    unique_id = "temp_selectize_id_#{@selectize_unique_id +=1}" 
    with = options.fetch(:with) 
    page.execute_script %Q{ 
    var selectize = $(#{selector.to_json})[0].selectize; 
    var type = #{with.to_json}.join(selectize.settings.delimiter) + '\t'; 
    selectize.$control_input.attr('id', #{unique_id.to_json}); 
    Syn.click({}, #{unique_id.to_json}).delay().type(type); 
    } 
    # make sure that it worked *and* that it's finished: 
    page.should have_content with.join('×') << '×' 
end 

# example use: 
fill_in_selectize_area '[name="blog[tags]"]', with: ['awesome subject', 'other tag'] 

Beachten Sie, dass die delay benötigt wird, weil am Eingang Fokussierung nicht sofortig ist.

+0

Schwierig, keine -1 zu dieser Antwort zu finden. Ich mag die Frage nicht, wenn du magst, aber wenn es eine gültige Frage ist, kann das nur eine gute Antwort sein, oder? –

1

Die API erlaubt es aber die Optionen müssen zuerst hinzugefügt werden, bevor der Wert eingestellt werden:

var selectize = $('.selector')[0].selectize 
selectize.addOptions([{text: 'Hello', value: 'Hello'}, {text: 'World', value: 'World'}]) 
selectize.setValue(['Hello', 'World']) 
+0

Ich fühle mich etwas ♥ –

+0

Nach weit und breit nach Antworten gesucht, war diese Route das Beste für mich. Der größte Nachteil dieses Ansatzes ist, dass er meine Ajax-Ladung umgeht. Aber um zu testen, dass Selectize funktioniert und dass Werte an das Formular übergeben werden, hat dies für mich funktioniert! –

+0

Ein Vorbehalt: Wenn Sie initialisieren, selektieren Sie mit 'valueField' und' labelField', muss Ihr 'addOptions'-Hash entsprechend Ihren eingehenden Daten modifiziert werden. –

5

Ich habe einen Helfer, die ich in Feature-Spezifikationen zu meinem Capybara mischen:

module PageSteps 
    def fill_in_selectized(key, *values) 
    values.flatten.each do |value| 
     page.execute_script(%{ 
     $('.#{key} .selectize-input input').val('#{value}'); 
     $('##{key}').selectize()[0].selectize.createItem(); 
     }) 
    end 
    end 
end 

und hier ist ein Beispiel dafür, wie es verwendet wird:

# Single value 
fill_in_selectized('candidate_offices', 'Santa Monica') 

# Multiple values 
fill_in_selectized('candidate_offices', ['San Francisco', 'Santa Monica']) 

der erste Parameter ein „Schlüssel“ und arbeitet in unserem appl Dank unserer Auszeichnung. Abhängig von Ihrem Markup müssen Sie möglicherweise etwas optimieren. Dies erfordert einen JavaScript fähigen Capybara Treiber (wir benutzen Poltergeist).

1

Dies ist mein Helfer, den ich mit meinen Feature-Spezifikationen mische. Es zwickt und erweitert Christian's answer.

  • Es richtet sich sowohl an select und text Eingangstypen
  • Es liest sich wie die regelmäßige Capybara fill_in Methode
  • Es kann jede Kennung akzeptieren, die für find_field arbeitet, um die Eingabe zu finden. Sie können also den Text des Labels, die ID des Elements oder den Namen des Elements verwenden, um das Element zu finden.

Die einzige Annahme dieser Code macht, ist, dass Ihre Texteingabe hat ein name Attribut (was natürlich die Rails Eingang Helfer automatisch hinzufügen)

def selectize(key, with:) 
    field = page.find_field(key, visible: false) 
    case field.tag_name 
    when "select" 
    page.execute_script(%{ 
     $("select[name='#{field["name"]}']") 
     .selectize()[0].selectize.setValue(#{Array(with)}); 
    }) 
    else 
    Array(with).each do |value| 
     page.execute_script(%{ 
     $("input[name='#{field["name"]}']") 
      .next() 
      .find(".selectize-input input").val('#{value}') 
      .end() 
      .prev() 
      .selectize()[0].selectize.createItem(); 
     }) 
    end 
    end 
end 

Beispiel Nutzung:

selectize "Single-choice field", with: "Only option" 
selectize "Multi-choice field", with: ["Option A", "Option B"] 
5

Die meisten Antworten hier ändern Dinge unter der Decke und sind nicht das gleiche wie die Interaktion des Benutzers. Hier ist eine Version, die nahe an dem ist, was der Benutzer tut.

# waits for the text to show up in autocomplete and then selects it 
def selectize_select(selectize_class, text) 
    find("#{selectize_class} .selectize-input input").native.send_keys(text) #fill the input text 
    find(:xpath, "//div[@data-selectable and contains(., '#{text}')]").click #wait for the input and then click on it 
    # convert css selector to xpath selector using Nokogiri::CSS.xpath_for 
end