2017-10-03 4 views
0

Teil meines Tests erfordert aus diesem Formularfeld eine Universität Auswahl:Capybara Aktion integer (id) vs. String (Name) Verwirrung

<div class="js-dependent-fields" data-select-id="user_role" data-option-value="staff"> 
    <div class="form-group"> 
    <%= form.label :university %> 
    <%= form.select :university_id, options_for_select(University.all.map{ |uni| [uni.name, uni.id] }), {prompt: 'Select Your University'}, { class: "form-control" } %> 
    </div> 
</div> 

Hier ist die eigentliche HTML ist:

<div class="js-dependent-fields" data-select-id="user_role" data-option-value="staff"> 
    <div class="form-group"> 
    <label for="user_university">University</label> 
    <select class="form-control" name="user[university_id]" id="user_university_id"><option value="">Select Your University</option> 
<option value="1">Harvard</option></select> 
    </div> 

Hier I ist der Fehler bin immer:

test_signup_valid_user           ERROR (0.05s) 
Capybara::ElementNotFound:   Capybara::ElementNotFound: Unable to find visible option "Harvard University" 
      test/integration/boarding_flow_test.rb:63:in `block in <class:BoardingFlowTest>' 

Wenn das Formular abgeschickt wird, ist dies ein Beispiel dafür, was es geht als Teil der Parameter

"university_id"=>"4" 

Im folgenden Test ich eine Universität auswählen möchten, und ich habe jede Kombination habe ich versucht, von wie denken kann:

page.select "3", from: "university_id" 
page.select "Harvard University", from: "University" 

aber ich kann nicht scheinen, damit es funktioniert. Was ist der richtige Weg, dies zu tun? Vielen Dank!

test 'signup valid user' do 
    visit sign_up_path 

    fill_in "First name", with: "John" 
    fill_in "Last name", with: "Doe" 
    fill_in "Email", with: "[email protected]" 
    fill_in "Password", with: "foobar" 
    page.select "Staff", from: "Role" 
    page.select "3", from: "university_id" 

    click_on "Signup" 

    assert_equal sign_in_path, current_path 
    assert page.has_content?("confirm your email") 
    end 

Hier Benutzer/new.html.erb

<div class="row"> 
    <div class="col-sm-8 col-md-4 col-sm-offset-2 col-md-offset-4"> 
    <div class="login-panel panel panel-default"> 
     <div class="panel-heading"> 
     <h3 class="panel-title">Signup</h3> 
     </div> 
     <div class="panel-body"> 
     <%= form_for @user do |form| %> 
      <fieldset> 
      <%= render partial: '/users/form', object: form %> 

      <%= form.submit t(".submit"), class: "btn btn-md btn-success btn-block" %> 
      <hr> 
      <h5 class="text-center">Already have an account?</h5> 
      <%= link_to t(".login"), sign_in_path, class: "btn btn-md btn-info btn-block" %> 
      </fieldset> 
     <% end %> 
     </div> 
    </div> 
    </div> 
</div> 

Hier ist die Form teilweise

<div class="form-group"> 
    <%= form.label :first_name %> 
    <%= form.text_field :first_name, class: "form-control" %> 
</div> 

<div class="form-group"> 
    <%= form.label :last_name %> 
    <%= form.text_field :last_name, class: "form-control" %> 
</div> 

<div class="form-group"> 
    <%= form.label :email %> 
    <%= form.text_field :email, type: 'email', class: "form-control" %> 
</div> 

<div class="form-group"> 
    <%= form.label :password %> 
    <%= form.password_field :password, class: "form-control" %> 
</div> 

<div class="form-group"> 
    <%= form.label :role %> 
    <%= form.select :role, options_for_select(User.roles.keys.map{ |role| [User.human_attribute_name("role.#{role}"), role] }), {}, { class: "form-control" } %> 
</div> 

<div class="js-dependent-fields" data-select-id="user_role" data-option-value="staff"> 
    <div class="form-group"> 
    <%= form.label :university %> 
    <%= form.select :university_id, options_for_select(University.all.map{ |uni| [uni.name, uni.id] }), {prompt: 'Select Your University'}, { class: "form-control" } %> 
    </div> 
</div> 
+0

FYI - Dies ist nicht Ihr aktuelles Problem, aber Sie sollten die Behauptungen von Capybara anstelle von 'assert_equal' und' assert' verwenden. Die Capybara-bereitgestellten Assertionen haben ein Warte-/Wiederholungsverhalten, um flockige Tests zu verhindern. 'assert_current_path (sign_in_path)' anstelle von 'assert_equal ...' und 'assert_content (" bestätige deine E-Mail ")' anstelle von 'assert page.has_content? (...)' –

Antwort

1

Wenn page.select mit - der Hauptparameter angepasst ist mit dem ' Option 'Wähltyp - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L413 - und die :from Option ist Übereinstimmung mit dem Auswahltyp "Select" - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L358. Dies bedeutet, dass die Option :from den Namen, die ID, den Platzhalter oder den zugehörigen Beschriftungstext eines HTML-Elements <select> entspricht und der Hauptparameter dem Text der auswählbaren Option entspricht. Sie zeigen nicht den tatsächlichen HTML-Code der Seite oder die Details des form Objekts, das Sie ‚form.select‘ zum Aufruf - aber wenn es ein Benutzer-Objekt ist es könnte so etwas wie

page.select("Harvard", from: 'user_university_id') # assuming the id of the actual select is 'user_university_id' 

werden, wenn es nur ein wählen auf der Seite mit der Möglichkeit der „Harvard University“, können Sie auch tun, nur

page.select "Harvard" 

die Gründe Ihre Versuche nicht, weil nicht funktioniert -

# Doesn't work because "3" isn't the readable text of the option and 
# 'university_id' is not the id of the select element 
page.select "3", from: "university_id" 

# Doesn't work because "University" is not the label text associated 
# with the select. This is because your partials label line would need to be 
# form.label :university_id, "University" 
# to link the label with the university_id select element. Additionally 
# "Harvard University" isn't actually the text shown in your HTML - it's just "Harvard" 
page.select "Harvard University", from: "University" 

das alles assum Das sichtbare Element auf der Seite ist eigentlich ein <select> Element und kein JS-gesteuertes Widget (welches die Klasse von js-dependent-fields auf dem Wrapping div anzeigen würde, könnte dies bedeuten). Wenn die sichtbaren Elemente ein JS-Widget sind, dann geht das alles aus dem Fenster, da page.select nur mit HTML <select> Elementen funktioniert und Sie den tatsächlichen HTML-Code für das sichtbare Auswahl-Widget auf Ihrer Seite anzeigen müssen.

+0

Danke Thomas - das University-Dropdown ist ausgeblendet es sei denn, die Mitarbeiter sind als Rolle ausgewählt. – mike9182

+0

@ mike9182 Wenn der Code in meiner Antwort nicht auswählen, was Sie wollen - zeigen Sie das tatsächliche HTML von diesem Abschnitt der Seite (nicht das Erb), so dass wir sehen können, was die tatsächliche ID dem Element zugewiesen ist - Sie kann die ganze Seite html durch etwas tun wie 'puts page.html' vor dem Versuch zu wählen. Fügen Sie auch den genauen Fehler hinzu, den Sie zu Ihrer Frage erhalten. –

+0

Danke Thomas für die Hilfe - Ich habe nur die relevante HTML zu der Frage hinzugefügt und den genauen Fehler, den ich mit Ihrem Code erhalte. – mike9182