2011-07-18 59 views
22

我正在使用RSpec和Capybara編寫Rails 3項目中控制器的規範,並且我想從選擇框中選擇當前日期。我想:如何從選擇框中使用Capybara在Rails 3中選擇日期?

select Date.today, :from => 'Date of birth' 

但規格失敗,我得到錯誤:

故障/錯誤:選擇Date.today,:從 NoMethodError => '出生年月': 未定義的方法`to_xpath」對於2011年7月18日,星期一:日期

如何解決?

P.S.在查看文件我用simple_form_for標籤,並通過代碼生成的選擇框:

f.input :date_of_birth 

回答

21

你需要,因爲它是在HTML選擇菜單指定的精確值。所以,如果你選擇了值分別爲「2011/01/01」,那麼你需要寫:因爲你傳遞一個日期對象

select '2011/01/01', :from => 'Date of birth' 

你的代碼失敗。

+0

它不起作用。我得到錯誤: 失敗/錯誤:選擇'2011/07/18',:from =>'出生日期' 水豚:: ElementNotFound: 無法選擇選項,沒有選項與文本'2011/07/18'在選擇框'出生日期' 順便說一下,R​​ails爲每個日期部分生成3個選擇框。 –

+0

然後,您需要從3個選擇框中選擇3個選項,並使用與您在頁面上看到的相同的值。 – solnic

+0

非常感謝!現在它工作了! –

2

感謝迪倫指出來,但如果有人正在尋找黃瓜的版本,您可以使用此:

select_date("Date of birth", :with => "1/1/2011") 

欲瞭解更多信息,請參閱select_date

+1

這是一個黃瓜方法的鏈接。問題是詢問有關使用rspec的水豚。 –

+0

我的不好,但我想我會在那裏修改它。 – Jaryl

24

有同樣的問題。我在一派很多,解決了它這種方式:

  1. 寫日期選擇宏進/spec/request_macros.rb 的select_by_id方法是必要的我,因爲這個月是依賴於翻譯

    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. 將它們添加到我的/spec/spec_helper.rb

    config.include RequestMacros, :type => :request 
    

現在在規範我的集成測試/請求我可以使用

select_date attr[:birthday], :from => "user_birthday" 

感謝http://jasonneylon.wordpress.com/2011/02/16/selecting-from-a-dropdown-generically-with-capybara/https://gist.github.com/558786 :)

+0

偉大的解決方案和實施。謝謝! –

7

馬庫斯的回答略有適應:

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

它看起來像這個已被充分覆蓋,但看到Capybara's docs關閉官方答覆。您可以按名稱,標識或標籤文本進行選擇。

1

鑑於以下Formtastic代碼呈現Rails的默認日期選擇:

= f.input :born_on, end_year: Time.now.year, start_year: 60.years.ago.year 

在你規範,打破了日期爲單獨調用每個個體選擇標籤:

select '1956', from: 'person_born_on_1i' 
select 'July', from: 'person_born_on_2i' 
select '9', from: 'person_born_on_3i' 

我不喜歡這段代碼非常瞭解HTML,但它現在可以與寶石的版本一起工作。

寶石:

  • 水豚2.1.0
  • Formtastic 2.2.1
  • 的Rails 3.2.13
  • RSpec的2.13.0
9

以信譽馬庫斯Hartmair爲出色的解決方案,我更喜歡使用標籤作爲選擇器,因爲可讀性提高。所以,我的他的幫手模塊的版本是:

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 

調用它像這樣:

select_date "2012,Jan,1", :from => "From date" 
+0

我不得不使用'find(:xpath,「.// label [contains(。,'#{field}')]」)[:for] [0 ..- 4]'和Date :: MONTHNAMES [ date.month]' – ybart

1

在我的特定情況下,我加入潛在的多個日期選擇字段到頁面accepts_nested_attributes_for功能。這意味着,我不確定這些字段的完整idname將會是什麼。

這是我的情況下想出瞭解決方案可以幫助別人谷歌搜索此:

我包裝的日期選擇字段的div容器與類:

<div class='date-of-birth-container'> 
    <%= f.date_select :date_of_birth %> 
</div> 

然後在我功能規格:

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 

這裏有一個輔助方法,我寫它:

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 

然後使用助手:

select_date_within_css_selector(Date.new(1955, 1, 1), '.date-of-birth-container') 
7

我發現RSpec的和水豚一個乾淨的解決方案使用日期和時間選擇的方法,凡在你的HTML您使用日期時間選擇或選擇日期進行測試。這適用於Rails 4,RSpec 3.1和Capybara 2.4.4。

說,在你的HTML表格,您有以下:

<%= f.datetime_select(:start_date, {default: DateTime.now, prompt: {day: 'Choose day', month: "Choose month", year: "Choose year"}}, {class: "date-select"}) %> 

日期時間選擇視圖助手將創建5個選擇字段與IDS如id="modelname_start_date_1i",其中ID的後面附加1I,2I,3I, 4i,5i。默認情況下爲年,月,日,小時,分鐘。如果您更改字段的順序,請確保在下面更改功能助手。

1)創建日期和時間的助手

規格/支持/傭工功能助手/ 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 

注意,一天我用%-d,給你一個非-padded數值(即4),而不是%d,它有一個零填充數值(即04)。檢查the date formats with strftime

2)然後,您需要在規格/支持/ helpers.rb您的日期和時間的助手方法,所以你可以在任何spec文件中使用它們。

require 'support/helpers/date_time_select_helpers' 
RSpec.configure do |config| 
    config.include Features::DateTimeSelectHelpers, type: :feature 
end 

3)在你的規格文件中,你可以打電話給你的幫手。例如:

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 
0

以下爲我工作,使用DATE_FIELD:沒有限制到Rails

fill_in "Date", with: DateTime.now.strftime('%m/%d/%Y') 
0

對於導軌4,以防有人獲取到這個問題3.

select '2020', from: 'field_name_{}_1i' 
    select 'January', from: 'field_name_{}_2i' 
    select '1', from: 'field_name_{}_3i' 

你當然可以提取這個給幫手,並使其動態。

相關問題