如何在Rails 3中使用Capybara从选择框中选择日期?

我正在使用RSpec和Capybara为Rails 3项目中的控制器编写规范,我想从选择框中选择当前日期。 我试过了:

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

但规格失败了,我得到错误:

失败/错误:选择Date.today,:from =>’出生日期’NoMethodError:未定义的方法`to_xpath’for Mon,2011年7月18日:日期

怎么解决?

PS在视图文件中我使用simple_form_for标记,选择框由代码生成:

 f.input :date_of_birth 

您需要在html的选择菜单中指定确切的值。 因此,如果您的选择具有类似“2011/01/01”的值,那么您需要写:

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

您的代码失败,因为您传递了日期对象。

有同样的问题。 我用谷歌搜索并以这种方式解决了它:

  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 

现在在我可以使用的spec / requests中的集成测试中

 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 🙂

由于Markus 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" 

略微改编马库斯的答案:

 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 

我为rspec和capybara找到了一个干净的解决方案来测试使用日期和时间选择方法,在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"}) %> 

DateTime Select View帮助器将创建5个带有id的选择字段,例如id="modelname_start_date_1i" ,其中id附加有1i,2i,3i,4i,5i。 默认情况下,年,月,日,小时,分钟。 如果更改字段的顺序,请确保更改下面的function助手。

1)为日期和时间助手创建function助手

规格/支持/助理/ 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那一天,它给出了非填充数值(即4),而不是具有零填充数值的%d (即04)。 使用strftime检查日期格式

2)然后,您需要在spec / support / helpers.rb中包含日期和时间助手方法,以便在任何规范文件中使用它们。

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

3)在您的Spec文件中,您可以调用您的助手。 例如:

 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 

感谢Dylan指出它,但如果有人在寻找黄瓜版本,你可以使用这个:

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

有关更多信息,请参阅select_date 。

鉴于以下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,但它确实适用于此时的gems版本。

gem:

  • Capybara 2.1.0
  • Formtastic 2.2.1
  • Rails 3.2.13
  • RSpec 2.13.0

在我的特定情况下,我正在使用accepts_nested_attributes_forfunction向页面添加可能的多个日期选择字段。 这意味着,我不确定字段的完整idname是什么。

这是我提出的解决方案,以防它帮助其他人谷歌搜索:

我将日期选择字段包装在带有类的容器div中:

 
<%= f.date_select :date_of_birth %>

然后在我的function规范中:

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

以下是使用date_field为我工作的:

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

对于Rails 4 ,如果有人得到这个问题而不仅限于Rails 3。

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

您当然可以将其提取到帮助程序并使其动态化。

看起来这个已被充分覆盖,但请参阅Capybara的文档以获得正式答案。 您可以按名称,ID或标签文本进行选择。