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
22
demandé sur Aleksandr Shvalev 2011-07-18 11:24:46

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.

21
répondu solnic 2011-07-18 14:09:18

avait le même problème. J'ai googlé au lot et résolu de cette façon:

  1. 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
    
  2. 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 :)

24
répondu Markus Hartmair 2012-02-22 15:59:36
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"
9
répondu Les Nightingill 2013-05-27 02:09:33

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
7
répondu Kris 2012-05-08 09:51:46

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
7
répondu Aurelien Schlumberger 2014-12-02 07:41:36

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.

2
répondu Jaryl 2012-02-10 06:51:12

é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
1
répondu scarver2 2013-05-07 21:42:38

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')
1
répondu Elliot Larson 2014-09-16 18:38:13

La suite travaillé pour moi, à l'aide d'un date_field:

fill_in "Date", with: DateTime.now.strftime('%m/%d/%Y')
0
répondu npostolovski 2015-10-27 06:23:45

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.

0
répondu Mugur 'Bud' Chirica 2018-03-09 10:14:30

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.

-1
répondu dooleyo 2013-02-04 17:56:16