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

Ale*_*lev 23 rspec ruby-on-rails date capybara ruby-on-rails-3

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

select Date.today, :from => 'Date of birth'
Run Code Online (Sandbox Code Playgroud)

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

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

怎么解决?

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

f.input :date_of_birth
Run Code Online (Sandbox Code Playgroud)

Mar*_*air 25

有同样的问题.我在google上搜索并以这种方式解决了它:

  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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将它们添加到我的/spec/spec_helper.rb中

    config.include RequestMacros, :type => :request
    
    Run Code Online (Sandbox Code Playgroud)

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

select_date attr[:birthday], :from => "user_birthday"
Run Code Online (Sandbox Code Playgroud)

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


sol*_*nic 22

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

select '2011/01/01', :from => 'Date of birth'
Run Code Online (Sandbox Code Playgroud)

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


Les*_*ill 9

鉴于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
Run Code Online (Sandbox Code Playgroud)

这样叫:

select_date "2012,Jan,1", :from => "From date"
Run Code Online (Sandbox Code Playgroud)


Aur*_*ger 9

我为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"}) %>
Run Code Online (Sandbox Code Playgroud)

DateTime Select View帮助器将创建5个带有id的选择字段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 
Run Code Online (Sandbox Code Playgroud)

请注意,对于我使用的%-d那一天,它给你一个非填充数值(即4),而不是%d具有零填充数值(即04).使用strftime检查日期格式

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

require 'support/helpers/date_time_select_helpers'
RSpec.configure do |config|
  config.include Features::DateTimeSelectHelpers, type: :feature
end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


Kri*_*ris 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
Run Code Online (Sandbox Code Playgroud)