2017-10-03 9 views
0

Une partie de mon test nécessite la sélection d'une université de ce champ de formulaire:Capybara entier action (id) par rapport à la chaîne (nom) confusion

<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> 

Voici le code html réelle:

<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> 

ici est l'erreur que je reçois:

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>' 

Lorsque le formulaire est soumis, ceci est un exemple de ce qu'il passe dans le cadre des paramètres

"university_id"=>"4" 

Dans le test ci-dessous je veux choisir une université, et je l'ai essayé toutes les combinaisons que je peux penser comme:

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

mais je ne peux pas sembler le faire fonctionner. Quelle est la bonne façon de faire cela? Merci!

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 

est ici les utilisateurs/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> 

est ici la forme partielle

<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 - Ce n'est pas votre problème actuel, mais vous devriez utiliser les assertions fournies par Capybara plutôt que 'assert_equal' et' assert'. Les assertions fournies par Capybara ont un comportement d'attente/de nouvelle tentative pour éviter les tests de détection. 'assert_current_path (sign_in_path)' au lieu de 'assert_equal ...' et 'assert_content (" confirmez votre email ")' au lieu de 'assert page.has_content? (...)' –

Répondre

1

Lorsque vous utilisez page.select - le paramètre principal est adapté à l'aide du ' option 'selector type - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L413 - et l'option :from est apparié en utilisant le type de sélecteur 'select' - https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L358. Cela signifie que l'option :from correspondra au nom, à l'identifiant, à l'espace réservé ou au texte d'étiquette associé d'un élément HTML <select>, et le paramètre principal correspond au texte de l'option sélectionnable. Vous ne montrez pas le code HTML réel de la page ou les détails de l'objet form que vous appelez « form.select » - mais si elle est un objet utilisateur, il pourrait être quelque chose comme

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

En cas de une seule sélection sur la page avec une option de « l'Université de Harvard », vous pouvez aussi faire juste

page.select "Harvard" 

les raisons vos tentatives ne fonctionnent pas est parce que -

# 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" 

tout cela assum L'élément visible sur la page est en fait un élément <select> et non un widget piloté par JS (que la classe de js-dependent-fields sur la div de wrapping aurait tendance à indiquer). Si le ou les éléments visibles sont un widget JS, tout ceci sort de la fenêtre puisque page.select ne fonctionne qu'avec les éléments HTML <select> et vous devrez afficher le code HTML actuel pour le widget de sélection visible sur votre page.

+0

Merci Thomas - la liste déroulante Université est cachée sauf si le personnel est sélectionné comme rôle. – mike9182

+0

@ mike9182 Si le code dans ma réponse ne sélectionne pas ce que vous voulez - montrer le code HTML réel de cette section de la page (pas l'erb) afin que nous puissions voir quel est l'identifiant réel attribué à l'élément - vous peut obtenir les pages entières html en faisant quelque chose comme 'puts page.html' avant d'essayer de sélectionner. Ajoutez également l'erreur exacte que vous obtenez à votre question. –

+0

Merci Thomas pour l'aide - Je viens d'ajouter le code HTML correspondant à la question et l'erreur exacte que je reçois en utilisant votre code. – mike9182