# frozen_string_literal: true module Cucumber module Rails module Capybara # This module defines methods for selecting dates and times module SelectDatesAndTimes # Select a Rails date. Options hash must include from: +label+ def select_date(date, options) date = Date.parse(date) base_dom_id = get_base_dom_from_options(options) # Rails 7 use HTML5 input type="date" by default. If input is not present fallback to plain select boxes alternative. # It's safe to use has_css? without waiting/retry. We already know field's label is visible if html5_input_field_present?(base_dom_id) fill_in options[:from], with: date else find(:xpath, ".//select[@id='#{base_dom_id}_1i']").select(date.year.to_s) find(:xpath, ".//select[@id='#{base_dom_id}_2i']").select(I18n.l(date, format: '%B')) find(:xpath, ".//select[@id='#{base_dom_id}_3i']").select(date.day.to_s) end end # Select a Rails time. Options hash must include from: +label+ def select_time(time, options) time = Time.zone.parse(time) base_dom_id = get_base_dom_from_options(options) # Rails 7 use HTML5 input type="time" by default. If input is not present fallback to plain select boxes alternative. # It's safe to use has_css? without waiting/retry. We already know field's label is visible if html5_input_field_present?(base_dom_id) fill_in options[:from], with: time else find(:xpath, ".//select[@id='#{base_dom_id}_4i']").select(time.hour.to_s.rjust(2, '0')) find(:xpath, ".//select[@id='#{base_dom_id}_5i']").select(time.min.to_s.rjust(2, '0')) end end # Select a Rails datetime. Options hash must include from: +label+ def select_datetime(datetime, options) base_dom_id = get_base_dom_id_from_label_tag(options[:from]) # Rails 7 use HTML5 input type="datetime-local" by default. If input is not present fallback to plain select boxes alternative. # It's safe to use has_css? without waiting/retry. We already know field's label is visible if html5_input_field_present?(base_dom_id) fill_in options[:from], with: DateTime.parse(datetime) else extended_options = options.merge(base_dom_id: base_dom_id) select_date(datetime, extended_options) select_time(datetime, extended_options) end end private def html5_input_field_present?(base_dom_id) ::Rails::VERSION::MAJOR >= 7 && page.has_css?("##{base_dom_id}", wait: 0) end def get_base_dom_from_options(options) options[:base_dom_id] || get_base_dom_id_from_label_tag(options[:from]) end # @example "event_starts_at_" def get_base_dom_id_from_label_tag(field) find(:xpath, ".//label[contains(., '#{field}')]")['for'].gsub(/(_[1-5]i)$/, '') end end end end end World(::Cucumber::Rails::Capybara::SelectDatesAndTimes)