Ok, you asked for leads so here're some thoughts and wild guesses (as long as you didn't give us neither url nor html).
- sendkeys() doesn't work because the input field most probably has an event handler attached that opens datepicker widget. So, your first try to set value through JS is OK. I use slightly different way (sorry, python code here):
driver.execute_script("arguments[0].value = arguments[1];", webelement, value)
- But this mightn't work because you're entering a value to the visible field and an actual field (supposed to be filled by the datepicker widget) used by the page (a form or JS code) is hidden and holds no value. Then, try to find that field and enter a value to it by JS method.
- In my current project I couldn't find that hidden field. I've decided to implement full user-like interaction with the datepicker widget. The scenario: click on the date field (datepicker widget opens), click on year or month selector buttons, then click on a day wanted. This way widget sets relevant data in a relevant fields (whatever and wherever they are) and closes.
Why I said fields (plural)? My recent thought was: May be setting the visible date field is right but there's some other field that must be set (like, say, date_was_set = "true").
Hope, this was helpful.
Edit. As for the 3rd paragraph. Here is my somewhat edited example (python, again).
The datepicker looks like this
As you can see it has buttons to adjust month and year combined.
from selenium.webdriver.support import expected_conditions as EC
class SetValCalendarStrategy(object):
def __init__(self, driver, calendar_param):
self.driver = driver
# this object holds parameters to find the calendar itself and its components
# pairs:
# sel_type - selector type ('xpath', 'id', 'name' etc.)
# sel_value - selector value to find ("//tr/td" etc)
self.param = calendar_param
def __call__(self, field, value, timeout):
"""
:param <webelement> field - input field
:param <datetime> value - value (date) to set
"""
# initiate datepicker with click on date input field
field.click()
# wait for a widget to show
cal = WebDriverWait(self.driver, timeout, 0.3).until(
EC.visibility_of_element_located(
(self.param.sel_type, self.param.sel_value)))
# decrease month/year button
prev_button = cal.find_element(
self.param.prev_month.sel_type,
self.param.prev_month.sel_value)
# increase button
next_button = cal.find_element(
self.param.next_month.sel_type,
self.param.next_month.sel_value)
today = datetime.now()
# calculate difference in months between today and the target date
month_diff = value.month + (value.year - today.year) * 12 - today.month
# select month/date
if month_diff < 0:
button = prev_button
else:
button = next_button
for i in range(abs(month_diff)):
button.click()
# template looks like this. It selects only days from target month (bold font)
# "//div[contains(@class, 'datePickerDay') and not(contains(@class, 'datePickerDayIsFiller')) and text()='{}']"
# insert day (21) into template. then it becomes
# "//div[contains(@class, 'datePickerDay') and not(contains(@class, 'datePickerDayIsFiller')) and text()='21']"
day_picker_sel_value =
self.param.day_picker.sel_template.format(value.day)
day = cal.find_element(
self.param.day_picker.sel_type,
day_picker_sel_value)
day.click()