2011-07-18 32 views
22

Tôi đang viết thông số cho bộ điều khiển trong dự án Rails 3 sử dụng RSpec và Capybara, và tôi muốn chọn ngày hiện tại từ một hộp chọn. Tôi cố gắng:Làm thế nào để chọn ngày từ một hộp chọn bằng cách sử dụng Capybara trong Rails 3?

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

nhưng spec thất bại và tôi nhận được lỗi:

Failure/Lỗi: chọn Date.today,: từ => 'Ngày tháng năm sinh' NoMethodError: phương pháp xác định 'to_xpath' cho Mon, ngày 18 tháng 7 năm 2011: Ngày

Cách khắc phục?

P.S. Trong tệp xem, tôi sử dụng thẻ simple_form_for và hộp chọn được tạo theo mã:

f.input :date_of_birth 

Trả lời

21

Bạn cần chỉ định giá trị chính xác như trong menu chọn trong html. Vì vậy, nếu lựa chọn của bạn có các giá trị như "2011/01/01" thì bạn cần phải viết:

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

Mã của bạn không thành công vì bạn vượt qua một đối tượng ngày.

+0

Nó không hoạt động. Tôi gặp lỗi: Lỗi/lỗi: chọn '2011/07/18',: từ => 'Ngày sinh' Capybara :: ElementNotFound: không thể chọn tùy chọn, không có tùy chọn với văn bản '2011/07/18' trong hộp chọn 'Ngày sinh' Nhân tiện, Rails tạo 3 hộp chọn cho mỗi phần ngày. –

+0

Sau đó, bạn cần phải chọn 3 tùy chọn từ 3 hộp chọn và sử dụng các giá trị giống như bạn thấy trên trang. – solnic

+0

Cảm ơn rất nhiều! Bây giờ nó hoạt động! –

2

Nhờ Dylan cho trỏ nó ra, nhưng trong trường hợp bất cứ ai đang tìm kiếm các phiên bản dưa chuột, bạn có thể sử dụng này:

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

Để biết thêm thông tin, xem select_date.

+1

Đây là liên kết đến phương pháp dưa chuột. Câu hỏi đặt ra là hỏi về việc sử dụng capybara với rspec. –

+0

Tệ của tôi, nhưng tôi nghĩ tôi sẽ để nó ở đó với một bản chỉnh sửa. – Jaryl

24

Đã xảy ra sự cố tương tự. Tôi googled tại rất nhiều và giải quyết nó theo cách này:

  1. Wrote ngày chọn macro vào /spec/request_macros.rb Phương pháp select_by_id là cần thiết đối với tôi, vì tháng phụ thuộc vào dịch

    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. thêm họ /spec/spec_helper.rb tôi

    config.include RequestMacros, :type => :request 
    

Bây giờ trong các thử nghiệm hội nhập của tôi trong đặc tả/yêu cầu tôi có thể sử dụng

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

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

+0

Giải pháp và triển khai tuyệt vời. Cảm ơn! –

7

Một thích ứng nhẹ của câu trả lời Markus của:

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

Có vẻ như trang này đã được che phủ đầy đủ, nhưng hãy xem Capybara's docs để tắt câu trả lời. Bạn có thể chọn theo tên, id hoặc văn bản nhãn.

1

Với mã Formtastic sau làm cho Rails ngày mặc định chọn:

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

Trong spec của bạn, phá vỡ các ngày vào các cuộc gọi riêng cho mỗi chọn thẻ cá nhân:

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

tôi không thích rằng mã này rất ý thức về HTML, nhưng nó hoạt động với các phiên bản của đá quý tại thời điểm này.

Gems:

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

với tín dụng cho Markus Hartmair cho một giải pháp tuyệt vời, tôi thích sử dụng nhãn làm bộ chọn vì khả năng đọc được cải thiện. Vì vậy, phiên bản của tôi về mô-đun helper của ông là:

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 

gọi nó như thế này:

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

Tôi phải sử dụng 'find (: xpath," .// label [contains (., '# {Field}')] ") [: for] [0 ..- 4]' và 'Date :: MONTHNAMES [ date.month] ' – ybart

1

Trong trường hợp đặc biệt của tôi, tôi thêm khả năng nhiều ngày chọn trường để trang với accepts_nested_attributes_for chức năng. Điều này có nghĩa, tôi không chắc chắn những gì đầy đủ id hoặc name của các trường sẽ có.

Đây là giải pháp tôi đã đưa ra trong trường hợp nó giúp bất cứ ai khác Googling này:

Tôi gói ngày chọn trường trong một div container với một lớp:

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

Sau đó, trong tôi tính năng 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 

Dưới đây là một phương pháp helper tôi đã viết cho nó:

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 

Sau đó, sử dụng các helper:

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

Tôi tìm thấy một giải pháp sạch cho rspec và Capybara để kiểm tra sử dụng ngày tháng và thời gian chọn phương pháp, nơi trong HTML của bạn, bạn sử dụng một datetime chọn hoặc ngày chọn. Điều này làm việc với Rails 4, RSpec 3.1 và Capybara 2.4.4.

Say ở dạng HTML của bạn, bạn có sau đây:

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

các DateTime Chọn Xem helper sẽ tạo ra 5 lựa chọn các lĩnh vực với id như id="modelname_start_date_1i", nơi id được nối với 1i, 2i, 3i, 4i, 5i. Theo mặc định Năm, Tháng, Ngày, Giờ, Phút. Nếu bạn thay đổi thứ tự của các trường, hãy đảm bảo thay đổi trình trợ giúp tính năng bên dưới.

1) Tạo một Helper Tính năng cho ngày tháng và thời gian giúp đỡ

đặc tả/support/giúp đỡ/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 

Lưu ý rằng cho ngày tôi sử dụng %-d cung cấp cho bạn một tổ chức phi giá trị số có sẵn (ví dụ 4) thay vì %d có giá trị số không có đệm (ví dụ 04). Kiểm tra the date formats with strftime

2) Sau đó, bạn cần đưa các phương thức ngày và giờ của bạn vào spec/support/helpers.rb để bạn có thể sử dụng chúng trong bất kỳ tệp thông số nào.

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

3) Trong tệp Spec, bạn có thể gọi người trợ giúp. Ví dụ:

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

Sau đây làm việc cho tôi, sử dụng một date_field:

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

cho Rails 4, trong trường hợp có ai đó bị cho câu hỏi này mà không bị giới hạn trong Rails 3.

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

Tất nhiên bạn có thể trích xuất phần này thành người trợ giúp và làm cho nó động.

Các vấn đề liên quan