Datepicker control, as the name suggests, is an interface to select one or multiple dates. When clicked on datepicker control, it provides a calendar that enables user to select the date/s. Datepicker control is very very common and widely used in almost every website. It is very tricky and needs to be handled very carefully. In this blog, let’s see how to set a date in datepicker control using Selenium and java as programming language.
For this demonstration, I am using a form from the website http://demoqa.com.
There is a date control on the form for capturing “Date of Birth”. After clicking in the text box for “Date of Birth” control, the actual date control pops up, where user has to select the date. -------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------As we can see in the code snippet below, the web element variable declared for the “Date of Birth” control is “dob”. When a user clicks the “Date of Birth” control, it takes a few moments for the calendar control to popup. Hence, after clicking on the control through Selenium code, it is necessary to use WebDriverWait object, so that the calendar control is loaded and is available for clicking. Else, it gives “element not interactable” error.
------------------------------------------------------------------------------------------------------------------------------------------------
WebElement dob = driver.findElement(By.xpath("//div[@id='dateOfBirth']//input"));
dob.sendKeys(Keys.SPACE);
WebDriverWait w = new WebDriverWait(driver, Duration.ofSeconds(10));
w.until(ExpectedConditions.visibilityOf(dob));
((JavascriptExecutor)driver).executeScript("arguments[0].click();", dob);
-------------------------------------------------------------------------------------------------------------------------------------------------
A function setDate() is written which accepts month, date and year as parameters and populates the calendar control accordingly.
The parameters for setDate() function are generated by using Random() function. Lets understand the logic step-by-step.
int month, date, year;
String min = "", max = "";
List<WebElement> lstYears = driver.findElements
(By.xpath("//select[@class='react-datepicker__year-select']/option"));
WebElement webEl = driver.findElement
(By.xpath("//select[@class='react-datepicker__year-select']/option[1]"));
min = webEl.getText();
webEl = driver.findElement
(By.xpath("//select[@class='react-datepicker__year-select']/option[" + lstYears.size() + "]"));
max = webEl.getText();
System.out.println("min: " + min + ", max: " + max);
Random rn = new Random();
year = rn.nextInt(Integer.parseInt(min), Integer.parseInt(max));
month = rn.nextInt(1,12);
date = 1;
if(Year.isLeap(year)) {
if (month==2) {
date = rn.nextInt(1,29);
}
else {
date = rn.nextInt(1,28);
}
}
//31 - 1, 3, 5, 7,8 , 10, 12
//30 - 4, 6, 9, 11
if(month!=2) {
if(month == 4 || month == 6 || month == 9 || month == 11) {
date = rn.nextInt(1,30);
}
else{
date = rn.nextInt(1,30);
}
}
System.out.println(month + "-" + date + "-" + year);
setDate(month,date,year);
First the range of the dropdown control is searched and a year is selected from that range, i.e. min (1900) to max (2100) . Then a month is selected from 1 t 12. There are following possibilities : 1. Year selected is a leap year and the month selected is 2 (February), then the date should be in the range of 1 and 29. 2. Year selected is not a leap year and the month selected is 2 (February), then the date should be in the range of 1 and 28. 3. Year selected is a leap or not a leap year and the month selected is other than 2 (February), then the date should be in the range of 1 and 30 or 1 to 31 depending on the month selected. (Please note that, there is a readymade function Year.isLeap(year) available.) This is how the random numbers for year, month and date are selected and passed to the function setDate(). -------------------------------------------------------------------------------------------------------------------------------------------------
Now let’s see the function setDate().
public static WebDriver driver;
private static void setDate(int month, int date, int year) {
WebElement selYear = driver.findElement (By.xpath("//*[@class='react-datepicker__year-select']"));
selYear.click();
String y = Integer.toString(year);
selYear.sendKeys(y);
selYear.click();
WebElement selMonth = driver.findElement
(By.xpath("//*[@class='react-datepicker__month-select']"));
selMonth.click();
String m = Month.of(month).toString();
selMonth.sendKeys(m);
selMonth.click();
String d = Integer.toString(date);
String xp = "//*[@class='react-datepicker__week']//*[text()='" + d + "']";
WebElement selDate = driver.findElement(By.xpath(xp));
selDate.click();
}
------------------------------------------------------------------------------------------------------------------------------------------------- After clicking in the Date of Birth text box, calendar control pops up. Thereafter, setDate() function selects the date based on the input parameters. Following is the explanation of the setDate() function code. For setting the year: 1. Find the element for “year” which is a dropdown control. Find the xpath using the “class” attribute. 2. Convert year value to string. 3. Pass this string to the dropdown element and set it. For setting the month: 1. Find the element for “month” which is a dropdown control. Find the xpath using the “class” attribute. 2. The dropdown contains months in “string” format. i.e. not numbers, but names of months. Therefore, convert the month from integer value to month name. E.g. 3->March, 9->September…etc. There is function “Month.of(month).toString()” which converts the integer value to Month Name. 3. Pass this string value to the dropdown element and set it. For setting the date: 1. There is no dropdown element, but a “div” tag. 2. Using the date parameter, create the xpath dynamically as given in the code sample below for this particular example. You can note that a date for the month is represented under a “div” tag inside another “div” tag for a week or month. e.g. The xpath for the date “12” is as follows : “//*[@class='react-datepicker__week']//*[text()='12']”
In this way, we learnt how to navigate through calendar control through selenium.