@@ -8,12 +8,13 @@ module SelectDatesAndTimes
8
8
# Select a Rails date. Options hash must include from: +label+
9
9
def select_date ( date , options )
10
10
date = Date . parse ( date )
11
- if ::Rails ::VERSION ::MAJOR >= 7
12
- # Rails 7 generates date fields using input type="date". Capybara support's them
11
+ base_dom_id = get_base_dom_from_options ( options )
12
+
13
+ # Rails 7 use HTML5 input type="date" by default. If input is not present fallback to plain select boxes alternative.
14
+ # It's safe to use has_css? without waiting/retry. We already know field's label is visible
15
+ if html5_input_field_present? ( base_dom_id )
13
16
fill_in options [ :from ] , with : date
14
17
else
15
- base_dom_id = get_base_dom_id_from_label_tag ( options [ :from ] )
16
-
17
18
find ( :xpath , ".//select[@id='#{ base_dom_id } _1i']" ) . select ( date . year . to_s )
18
19
find ( :xpath , ".//select[@id='#{ base_dom_id } _2i']" ) . select ( I18n . l ( date , format : '%B' ) )
19
20
find ( :xpath , ".//select[@id='#{ base_dom_id } _3i']" ) . select ( date . day . to_s )
@@ -23,30 +24,43 @@ def select_date(date, options)
23
24
# Select a Rails time. Options hash must include from: +label+
24
25
def select_time ( time , options )
25
26
time = Time . zone . parse ( time )
26
- if ::Rails ::VERSION ::MAJOR >= 7
27
- # Rails 7 generates date fields using input type="time". Capybara support's them
27
+ base_dom_id = get_base_dom_from_options ( options )
28
+
29
+ # Rails 7 use HTML5 input type="time" by default. If input is not present fallback to plain select boxes alternative.
30
+ # It's safe to use has_css? without waiting/retry. We already know field's label is visible
31
+ if html5_input_field_present? ( base_dom_id )
28
32
fill_in options [ :from ] , with : time
29
33
else
30
- base_dom_id = get_base_dom_id_from_label_tag ( options [ :from ] )
31
-
32
34
find ( :xpath , ".//select[@id='#{ base_dom_id } _4i']" ) . select ( time . hour . to_s . rjust ( 2 , '0' ) )
33
35
find ( :xpath , ".//select[@id='#{ base_dom_id } _5i']" ) . select ( time . min . to_s . rjust ( 2 , '0' ) )
34
36
end
35
37
end
36
38
37
39
# Select a Rails datetime. Options hash must include from: +label+
38
40
def select_datetime ( datetime , options )
39
- if ::Rails ::VERSION ::MAJOR >= 7
40
- # Rails 7 generates datetime fields using input type="datetime-local". Capybara support's them
41
+ base_dom_id = get_base_dom_id_from_label_tag ( options [ :from ] )
42
+
43
+ # Rails 7 use HTML5 input type="datetime-local" by default. If input is not present fallback to plain select boxes alternative.
44
+ # It's safe to use has_css? without waiting/retry. We already know field's label is visible
45
+ if html5_input_field_present? ( base_dom_id )
41
46
fill_in options [ :from ] , with : DateTime . parse ( datetime )
42
47
else
43
- select_date ( datetime , options )
44
- select_time ( datetime , options )
48
+ extended_options = options . merge ( base_dom_id : base_dom_id )
49
+ select_date ( datetime , extended_options )
50
+ select_time ( datetime , extended_options )
45
51
end
46
52
end
47
53
48
54
private
49
55
56
+ def html5_input_field_present? ( base_dom_id )
57
+ ::Rails ::VERSION ::MAJOR >= 7 && page . has_css? ( "##{ base_dom_id } " , wait : 0 )
58
+ end
59
+
60
+ def get_base_dom_from_options ( options )
61
+ options [ :base_dom_id ] || get_base_dom_id_from_label_tag ( options [ :from ] )
62
+ end
63
+
50
64
# @example "event_starts_at_"
51
65
def get_base_dom_id_from_label_tag ( field )
52
66
find ( :xpath , ".//label[contains(., '#{ field } ')]" ) [ 'for' ] . gsub ( /(_[1-5]i)$/ , '' )
0 commit comments