Подтвердить что ты не робот

Как выбрать дату из окна выбора с помощью Capybara в Rails 3?

Я пишу спецификацию для контроллера в проекте Rails 3 с использованием RSpec и Capybara, и я хочу выбрать текущую дату из окна выбора. Я пробовал:

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

но спецификация не работает, и я получаю ошибку:

Ошибка/ошибка: выберите Date.today,: from = > 'Дата рождения' NoMethodError: undefined метод `to_xpath 'для пн, 18 июля 2011: Дата

Как это исправить?

P.S. В файле вида я использую тэг simple_form_for, и поле выбора генерируется кодом:

f.input :date_of_birth
4b9b3361

Ответ 1

Вам нужно указать точное значение как в меню выбора в html. Поэтому, если ваш выбор имеет значения типа "2011/01/01", тогда вам нужно написать:

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

Ваш код выходит из строя, потому что вы передаете объект даты.

Ответ 2

Была та же проблема. Я googled на много и решил это следующим образом:

  • Написал макросы выбора даты в /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
    
  • Добавили их в мой /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:)

Ответ 3

с благодарностью 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"

Ответ 4

Небольшая адаптация ответа Маркуса:

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

Ответ 5

Я нашел чистое решение для 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="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, который дает вам неполное числовое значение (т.е. 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

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

Ответ 6

Спасибо Дилан за то, что он указал, но если кто-то ищет версию огурца, вы можете использовать это:

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

Для получения дополнительной информации см. select_date.

Ответ 7

Учитывая следующий код Formtastic, он отображает селектор даты по умолчанию Rails:

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

В вашей спецификации разбить дату на отдельные вызовы на каждый отдельный тег select:

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

Мне не нравится, что этот код настолько осведомлен о HTML, но в настоящее время он работает с версиями драгоценных камней.

Драгоценные камни:

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

Ответ 8

В моей конкретной ситуации я добавляю потенциально несколько полей выбора даты на страницу с помощью функции accepts_nested_attributes_for. Это означает, что я не уверен, какими будут полные id или name полей.

Здесь решение, которое я придумал, в случае, если это поможет кому-то еще в Google:

Я переношу поле выбора даты в контейнер 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')

Ответ 9

Похоже, что этот был достаточно охвачен, но см. Capybara docs для официального ответа. Вы можете выбрать по имени, идентификатору или меток.

Ответ 10

Следующее работало для меня, используя поле date_field:

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