Comment sélectionner la date à partir d'une boîte de sélection en utilisant Capybara dans Rails 3?
j'écris une spécification pour un contrôleur dans le projet Rails 3 en utilisant RSpec et Capybara, et je veux sélectionner la date actuelle à partir d'une boîte de sélection. J'ai essayé:
select Date.today, :from => 'Date of birth'
mais la spec échoue et j'obtiens l'erreur:
echec / erreur: sélectionnez la Date.aujourd'hui,: à partir de = > "Date de naissance" NoMethodError: méthode non définie "to_xpath" pour Lun, 18 Jul 2011:Date
comment le réparer?
<!-J'utilise la balise simple_form_for et la boîte de sélection est générée par code:f.input :date_of_birth
11 réponses
vous devez spécifier la valeur exacte telle qu'elle est dans le menu sélectionner en html. Donc si votre select a des valeurs comme "2011/01/01" alors vous devez écrire:
select '2011/01/01', :from => 'Date of birth'
votre code échoue parce que vous passez un objet date.
avait le même problème. J'ai googlé au lot et résolu de cette façon:
date écrite sélectionnez macros dans / spec / request_macros.rb Le select_by_id méthode est nécessaire pour moi, car le mois dépend de la traduction
module RequestMacros def select_by_id(id, options = {}) field = options[:from] option_xpath = "//*[@id='#{field}']/option[#{id}]" option_text = find(:xpath, option_xpath).text select option_text, :from => field end def select_date(date, options = {}) field = options[:from] select date.year.to_s, :from => "#{field}_1i" select_by_id date.month, :from => "#{field}_2i" select date.day.to_s, :from => "#{field}_3i" end end
Ajouté à mon /spec / spec_helper.rb
config.include RequestMacros, :type => :request
Maintenant, dans mes tests d'intégration dans spec/demandes je peux utilisez
select_date attr[:birthday], :from => "user_birthday"
Grâce à http://jasonneylon.wordpress.com/2011/02/16/selecting-from-a-dropdown-generically-with-capybara/ et https://gist.github.com/558786 :)
module SelectDateHelper
def select_date(date, options = {})
field = options[:from]
base_id = find(:xpath, ".//label[contains(.,'#{field}')]")[:for]
year, month, day = date.split(',')
select year, :from => "#{base_id}_1i"
select month, :from => "#{base_id}_2i"
select day, :from => "#{base_id}_3i"
end
end
l'appeler comme ceci:
select_date "2012,Jan,1", :from => "From date"
une légère adaptation de la réponse DE Markus:
def select_date(date, options = {})
raise ArgumentError, 'from is a required option' if options[:from].blank?
field = options[:from].to_s
select date.year.to_s, :from => "#{field}_1i"
select Date::MONTHNAMES[date.month], :from => "#{field}_2i"
select date.day.to_s, :from => "#{field}_3i"
end
j'ai trouvé une solution propre pour rspec et capybara pour tester en utilisant les méthodes date et time select, où dans votre HTML vous utilisez une datetime select ou date select. Cela fonctionne avec les Rails 4, RSpec 3.1 et Capybara 2.4.4.
dites dans votre forme HTML que vous avez ce qui suit:
<%= f.datetime_select(:start_date, {default: DateTime.now, prompt: {day: 'Choose day', month: "Choose month", year: "Choose year"}}, {class: "date-select"}) %>
L'Assistant DateTime Select View créera 5 champs select avec des ID comme id="modelname_start_date_1i"
, où l'id est joint avec 1i, 2i, 3i, 4i, 5i. Par défaut Année, Mois, Jour, Heure, Minute. Si vous modifier l'ordre des champs, assurez-vous de changer la fonction helper ci-dessous.
1) Créez un Helper de fonctionnalité pour les helpers de dates et d'heures
spec/support/helpers / date_time_select_helpers.rb
module Features
module DateTimeSelectHelpers
def select_date_and_time(date, options = {})
field = options[:from]
select date.strftime('%Y'), :from => "#{field}_1i" #year
select date.strftime('%B'), :from => "#{field}_2i" #month
select date.strftime('%-d'), :from => "#{field}_3i" #day
select date.strftime('%H'), :from => "#{field}_4i" #hour
select date.strftime('%M'), :from => "#{field}_5i" #minute
end
def select_date(date, options = {})
field = options[:from]
select date.strftime('%Y'), :from => "#{field}_1i" #year
select date.strftime('%B'), :from => "#{field}_2i" #month
select date.strftime('%-d'), :from => "#{field}_3i" #day
end
end
end
notez que pour le jour que j'utilise %-d
cela vous donne une valeur numérique non-matelassée (c.-à-d. 4) au lieu de %d
qui a une valeur numérique zéro-rembourrée (c.-à-d. 04). Vérifier les formats de date avec strftime
2) Vous alors besoin d'inclure votre date et l'heure aides méthodes spec/support / helpers.rb vous pouvez donc les utiliser dans n'importe quel fichier spec.
require 'support/helpers/date_time_select_helpers'
RSpec.configure do |config|
config.include Features::DateTimeSelectHelpers, type: :feature
end
3) Dans votre fichier Spec, vous pouvez appeler votre aide. Par exemple:
feature 'New Post' do
scenario 'Add a post' do
visit new_post_path
fill_in "post[name]", with: "My post"
select_date_and_time(2.days.from_now, from:"post_start_date")
click_button "Submit"
expect(page).to have_content "Your post was successfully saved"
end
end
merci à Dylan de le souligner, mais au cas où quelqu'un cherche la version du concombre, vous pouvez utiliser ceci:
select_date("Date of birth", :with => "1/1/2011")
Pour plus d'informations, voir select_date.
étant donné que le code Formtastic suivant rend le sélecteur de date par défaut des Rails:
= f.input :born_on, end_year: Time.now.year, start_year: 60.years.ago.year
dans votre spécification, fractionnez la date en appels distincts à chaque individu choisissez l'étiquette:
select '1956', from: 'person_born_on_1i'
select 'July', from: 'person_born_on_2i'
select '9', from: 'person_born_on_3i'
Je n'aime pas que ce code soit si conscient du HTML, mais il fonctionne avec les versions de gemmes en ce moment.
pierres précieuses:
- Capybara 2.1.0
- Formtastic 2.2.1
- Rails 3.2.13
- RSpec 2.13.0
dans ma situation particulière, j'ajoute potentiellement plusieurs champs Date select à la page avec accepts_nested_attributes_for
fonctionnalité. Cela signifie, Je ne suis pas sûr ce que le plein id
ou name
les champs sont en passe de l'être.
Voici la solution que j'ai trouvée au cas où cela aiderait quelqu'un D'autre à googler ceci:
j'enroule le champ date select dans un conteneur div avec une classe:
<div class='date-of-birth-container'>
<%= f.date_select :date_of_birth %>
</div>
dans ma fonction spec:
within '.date-of-birth-container' do
find("option[value='1']", text: 'January').select_option
find("option[value='1']", text: '1').select_option
find("option[value='1955']").select_option
end
voici un helper la méthode que j'ai écrit pour elle:
def select_date_within_css_selector(date, css_selector)
month_name = Date::MONTHNAMES.fetch(date.month)
within css_selector do
find("option[value='#{date.month}']", text: month_name).select_option
find("option[value='#{date.day}']", text: date.day.to_s).select_option
find("option[value='#{date.year}']").select_option
end
end
Ensuite, en utilisant le helper:
select_date_within_css_selector(Date.new(1955, 1, 1), '.date-of-birth-container')
La suite travaillé pour moi, à l'aide d'un date_field:
fill_in "Date", with: DateTime.now.strftime('%m/%d/%Y')
Rails 4, dans le cas où quelqu'un arrive à cette question sans être limité à Rails 3.
select '2020', from: 'field_name_{}_1i'
select 'January', from: 'field_name_{}_2i'
select '1', from: 'field_name_{}_3i'
Vous pouvez bien sûr extraire ceci à un helper et le rendre dynamique.
il semble que celui-ci ait été suffisamment couvert, mais voir Capybara de docs pour une réponse officielle. Vous pouvez choisir par nom, id, ou texte d'étiquette.