0

I've to select a user specified date and the snippet for picker is below.

enter image description here

sendkeys() functionality isn't working so I tried the below code.

JavascriptExecutor check = (JavascriptExecutor)driver; check.executeScript("document.getElementById('hotel-checkin').setAttribute('value','10 Jan 2018')");

On entering the value, the date picker stays alive wherein the script fails to click the search button which is actually overlapped by date picker.

Any leads would be of great help. Thanks in advance!

Umesh Kumar
  • 127
  • 1
  • 1
  • 9
  • Have you tried blurring the input element after setting the value? Alternatively can you set the text of the field to pick the date and then blur it? – Dillanm Mar 15 '18 at 14:00
  • Did you try the _powerful_ and _proven_ **Java** `click()` ? – undetected Selenium Mar 15 '18 at 14:14
  • Can you elaborate on "isn't working?" Are you sure your locator is correct? Are you getting an error message of any kind? I have yet to find a control that accepts keyboard input that won't also work with sendKeys. – Bill Hileman Mar 15 '18 at 14:25
  • @DebanjanB I tried the below code and there are no errors but the driver isn't entering/typing the values into the field. 'driver.findElement(By.id("hotel-checkin")).click(); driver.findElement(By.id("hotel-checkin")).sendKeys("20/Jan/2018");' – Umesh Kumar Mar 16 '18 at 07:00
  • You have two related problems here: enter a value and hide DatePicker widget to be able to click to submit button. I guess @DebanjanB suggested to solve the second problem: try clicking outside the date field to hide DatePicker widget – Alexey Dolgopolov Mar 16 '18 at 08:09
  • About entering a value try reading some related questions: https://stackoverflow.com/questions/30468289/date-picker-selenium-webdriver-java?rq=1, https://stackoverflow.com/questions/21422548/how-to-select-the-date-picker-in-selenium-webdriver?rq=1 and so on. – Alexey Dolgopolov Mar 16 '18 at 08:14

1 Answers1

0

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).

  1. 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)
  2. 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.
  3. 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 datepicker widget 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()