How To Automate Calendar Using Selenium WebDriver For Testing?

How To Automate Calendar Using Selenium WebDriver For Testing?

Quite often while buying a movie ticket online or filling up a form, you’d come across calendars to pick dates and even time. These calendars make the whole process of picking dates much easier and interactive and play a crucial role in enhancing user experience. It would be surprising to find websites, especially in the travel and hospitality domain, where they don’t make use of the date picker calendar so that their customers can schedule their travel. Since there are different types of calendar controls and their behaviour can vary across different web browsers, it becomes important to exhaustively automate calendar using Selenium WebDriver.

The most popular date picker controls are jQuery calendar (or jQuery date picker) and Kendo calendar (or Kendo date picker). Even if you have not used calendar controls for your project, it is important to have know-how about these standard controls and mechanisms to automate calendar using Selenium WebDriver, here’s a document to help you know What Is Selenium?

In this Selenium WebDriver tutorial for testing, I will take a deep dive to automate calendar using Selenium WebDriver for popular calendar controls. You can skip to any sub-section depending on your understanding about calendar controls. Below are the sub-topics covered this Selenium testing tutorial:

Types Of Calendar Controls

A calendar control (date picker control) allows the user to select a date easily. Usually, it appears as an input field in an HTML form. Since the date selected by the user might be needed later, it is important to maintain the format. This is also why HTML forms are more widely used than entering date in a text-box.

There are two popular types of Calendar controls you’d need to automate calendar using Selenium WebDriver:

  • jQuery Calendar — The jQuery calendar is a part of the open-source project at JS Foundation (previously called jQuery Foundation). There are a number of other elements like user interface interactions, widgets, effects, etc. that are also built on top of jQuery JavaScript Library.

  • Kendo Calendar — Kendo Calendar is developed by Telerik.com. It is not an open-source project. Using Kendo UI, developers can build JavaScript apps faster.

Kendo and jQuery Calendars work on all major web browsers. But there are a few exceptions- Kendo on IE works on IE7 (and above) whereas jQuery works on IE8 (and above). Both these controls are responsive and have mobile browser compatibility.

Now perform live interactive jQuery testing of your jQuery Mobile websites on LambdaTest.

How To Automate Calendar In Selenium WebDriver For Automation Testing?

The challenge in Selenium test automation of calendar controls is that the presentation of information can vary from calendar to calendar. In some calendar controls, the months & years are shown in a drop-down whereas in few of them, the months & years can be changed using navigation controls i.e. previous and next buttons.

Some date picker controls also have time alongside date & time. This makes automated browser testing of calendar controls challenging as the test implementation will need to be tweaked as per the appearance and style of the control.

This section of Selenium testing tutorial focuses on the implementation to automate calendar using Selenium WebDriver:

This Playwright browser testing tutorial will guide you through the setup of the Playwright framework, which will enable you to write end-to-end tests for your future projects.

Handling ‘JQuery Calendar’ in an IFRAME

There are many scenarios where you would want to place the Calendar control inside an iFrame. In such cases, before performing any operation on the date picker, you have to first switch to that iFrame.

Once inside the iFrame, you should perform the following operations:

Step 1: Click on the Calendar Control to open the same.

Step 2: Find the Year drop-down control and select the required year from that drop-down.

Step 3: Find the Month drop-down control and select the required month from that drop-down.

Step 4: Once year and month is selected, locate the corresponding date by navigating through the Date table.

I’ll use jQuery’s date picker demo URL as the test URL to demonstrate how to automate calendar using Selenium WebDriver when the calendar is inside the iFrame. In this Selenium testing tutorial I’ll be using Python’s unittest framework to automate calendar using Selenium WebDriver

Shown below is the complete Selenium test automation implementation to automate calendar using Selenium WebDriver inside an iFrame.

FileName — 1_Selenium_Calendar_iFrame_Test.py

#Selenium testing tutorial to automate calendar using Selenium WebDriver inside an iFrame.
import unittest
import time
from selenium import webdriver
from selenium.webdriver.support.select import Select

# The Date Range picker is from https://jqueryui.com/datepicker/#date-range

expected_from_date_str = '01/20/2020'
expected_to_date_str = '02/26/2020'

expected_fr_date = '20'
expected_to_date = '26'

test_url = 'https://jqueryui.com/datepicker/#date-range'

class CalendarControlTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()

    def test_calendar_control_range_(self):
        driver = self.driver
        driver.get(test_url)
        time.sleep(5)

        frame = driver.find_element_by_xpath("//*[@id='content']/iframe")
        driver.switch_to.frame(frame)

        ################################# Steps for the From Date ############################
        from_dp = driver.find_element_by_xpath("//input[@id='from']")
        from_dp.click()
        time.sleep(5)

        from_month = driver.find_element_by_xpath("//div/select[@class='ui-datepicker-month']")
        selected_from_month = Select(from_month)
        selected_from_month.select_by_visible_text("Jan")
        time.sleep(5)

        # from_day = driver.find_element_by_xpath("//table/tbody/tr/td/a[text()='20']")
        from_day = driver.find_element_by_xpath("//td[not(contains(@class,'ui-datepicker-month'))]/a[text()='" + expected_fr_date + "']")
        from_day.click()
        time.sleep(10)

        ################################# Steps for the To Date ############################
        # The same steps like the ones in From Month are repeated except that now the operations
        # are performed on a different web element.

        to_dp = driver.find_element_by_xpath("//input[@id='to']")
        to_dp.click()
        time.sleep(5)

        to_month = driver.find_element_by_xpath("//div/select[@class='ui-datepicker-month']")
        selected_to_month=Select(to_month)
        selected_to_month.select_by_visible_text("Feb")
        time.sleep(5)

        # day_to=driver.find_element_by_xpath("//table/tbody/tr/td/a[text()='26']")
        to_day = driver.find_element_by_xpath("//td[not(contains(@class,'ui-datepicker-month'))]/a[text()='" + expected_to_date + "']")
        to_day.click()
        time.sleep(10)

        ################################# Verify whether the values are as expected ############################
        selected_from_date_str = from_dp.get_attribute('value')
        self.assertEqual(selected_from_date_str, expected_from_date_str)

        selected_to_date_str = to_dp.get_attribute('value')
        self.assertEqual(selected_to_date_str, expected_to_date_str)

        print("Unit Test of jQuery Calendar passed")

    def tearDown(self):
        self.driver.close()
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

It’s crucial to debug websites for Safari before pushing them live. In this article, we look at how to debug websites using developer tools for safari.

Code WalkThrough

In the above example for this Selenium testing tutorial, the calendar is not a multi-date calendar i.e. every month will show a maximum of 31 days. There is no repetition of date values from different months.

The Inspect Tool of the web browser i.e. Chrome is used to get the XPath of the iFrame.

Step 1 — The iFrame is identified using the XPath locator. We then switch to iFrame that contains the Calendar event.

def test_calendar_control_range_(self):
    driver = self.driver
    driver.get(test_url)
    time.sleep(5)

    frame = driver.find_element_by_xpath("//*[@id='content']/iframe")
    driver.switch_to.frame(frame)

As this date picker provides date range functionality, the steps implemented for ‘from’ are also executed for ‘to’ in the date picker. The only difference is that the locators used for ‘from’ and ‘to’ are different.

Step 2 — The ‘from’ picker is located using its XPath. Once it is located, a Click operation is performed to open the Calendar.

The Select() operation in Python is used to select the target month i.e. Jan in our example.

from_dp = driver.find_element_by_xpath("//input[@id='from']")
from_dp.click()
time.sleep(5)

from_month = driver.find_element_by_xpath("//div/select[@class='ui-datepicker-month']")
selected_from_month = Select(from_month)
selected_from_month.select_by_visible_text("Jan")
time.sleep(5)

Step 3 — As we are already present in the target month, the final step is to select the target date i.e. 20th in the example. We have used dynamic XPath along with contains() method to exclude ‘similar dates’ for the next month. Though such a scenario will not come in this Selenium testing tutorial example, the implementation is a more foolproof mechanism to automate calendar using Selenium WebDriver.

# from_day = driver.find_element_by_xpath("//table/tbody/tr/td/a[text()='20']")
from_day = driver.find_element_by_xpath("//td[not(contains(@class,'ui-datepicker-month'))]/a[text()='" + expected_fr_date + "']")
from_day.click()
time.sleep(10)

The same steps are repeated for the ‘to’ element of the date picker. Shown below in this Selenium testing tutorial is the output snapshot that demonstrates handling of JQuery Calendar Control in an IFRAME.

Looking to enhance your web testing capabilities? Look no further than our top-of-the-line platform for testing web applications. With our advanced tools for manual and automated cross-browser testing, you can seamlessly test your web application across over 3000 browsers online.

Handling ‘JQuery Calendar’ With Dates From Multiple Months

As the title suggests, the JQuery Calendar used in this case can have dates of multiple months displayed in it i.e. When March is displayed in the Calendar, along with 31 days of March, there is a possibility that days of April are also displayed. If you have to select 1st January, incorrect implementation may lead to selection of 1st April as it is also displayed in the Calendar.

To demonstrate how to automate calendar using Selenium WebDriver when the calendar is displaying dates from multiple months, we use jQuery’s date picker with ‘multiple months’ demo URL as the test URL. Below are the test cases requirements to Selenium testing tutorial to automate calendar using Selenium WebDriver:

  1. Navigate to https://jqueryui.com/resources/demos/datepicker/other-months.html

  2. Locate the datepicker element and perform a click on the same

  3. Click on the ‘next’ button in the Calendar control till the expected year & month are found.

  4. Locate the entry in the calendar matching the ‘date’ and select the same to complete the test i.e. 04/01/2020

Below is the complete implementation on how to automate calendar using Selenium WebDriver when multiple months are displayed in the calendar.

FileName — 2_Selenium_Calendar_Multiple_Dates_Test.py

import unittest
import time
from selenium import webdriver
from selenium.webdriver.support.select import Select

# jQuery to select multiple dates

target_year = "2020"
target_month ="April"
target_date = "1"
space = " "

expected_month_year_val = '04/01/2020'

test_url = 'http://jqueryui.com/resources/demos/datepicker/other-months.html'

class CalendarControlTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()

    def test_calendar_control_range_(self):
        driver = self.driver
        driver.get(test_url)
        time.sleep(5)

        datepicker_val = driver.find_element_by_id('datepicker')
        datepicker_val.click()

        target_month_year_string = target_month + space + target_year

        elem_selected_year = driver.find_element_by_class_name("ui-datepicker-year")
        selected_year_string = elem_selected_year.get_attribute("innerHTML")

        elem_selected_month = driver.find_element_by_class_name("ui-datepicker-month")
        selected_month_string = elem_selected_month.get_attribute("innerHTML")

        # Concatenate selected month and year strings
        selected_month_year_string = selected_month_string + selected_year_string

        previous_button_xpath = "//*[@id='ui-datepicker-div']/div/a[1]"
        next_button_xpath = "//*[@id='ui-datepicker-div']/div/a[2]"

        # Navigate through the calendar to go to the required year
        # and than the required month

        while (selected_month_year_string != target_month_year_string):
            if (((int(target_year)) < int(selected_year_string))):
                # Click the next button
                previous_click = driver.find_element_by_xpath(previous_button_xpath)
                previous_click.click()
            else:    
                next_click = driver.find_element_by_xpath(next_button_xpath)
                next_click.click()

            elem_selected_year = driver.find_element_by_class_name("ui-datepicker-year")
            selected_year_string = elem_selected_year.get_attribute("innerHTML")

            elem_selected_month = driver.find_element_by_class_name("ui-datepicker-month")
            selected_month_string = elem_selected_month.get_attribute("innerHTML")

            # Compute the final day-month-year string
            selected_month_year_string = selected_month_string + space + selected_year_string

        elem_date = driver.find_element_by_xpath("//td[not(contains(@class,'ui-datepicker-other-month'))]/a[text()='" + target_date + "']")
        elem_date.click()

        time.sleep(10)

        # Check the selected month, date, and year from the Calendar
        selected_month_year_val = datepicker_val.get_attribute('value')
        print(selected_month_year_val)

        self.assertEqual(selected_month_year_val, expected_month_year_val)

        print("Unit Test of jQuery Calendar passed")

    def tearDown(self):
        self.driver.close()
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

It’s crucial to debug websites for Safari before pushing them live. In this article, we look at how to debug websites using dev tools in safari.

Code WalkThrough

To get started with the implementation of this Selenium test automation example, we first create the Chrome WebDriver instance.

Step 1 — Once the WebDriver instance is created, the test URL is opened.

class CalendarControlTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()

    def test_calendar_control_range_(self):
        driver = self.driver
        driver.get(test_url)
        time.sleep(5)

Step 2 — Locate the datepicker element using its XPath and perform a click to open the Calendar control.

datepicker_val = driver.find_element_by_id(‘datepicker’)
datepicker_val.click()

Step 3 — As the year & date selected can be from the future, next button on the date picker has to be clicked till the expected value has reached.

The datepicker-year and datepicker-month elements are located using class name locator. As these are label controls, the text content of these elements are read using innerHTML property.

elem_selected_year = driver.find_element_by_class_name("ui-datepicker-year")
selected_year_string = elem_selected_year.get_attribute("innerHTML")

elem_selected_month = driver.find_element_by_class_name("ui-datepicker-month")
selected_month_string = elem_selected_month.get_attribute("innerHTML")

# Concatenate selected month and year strings
selected_month_year_string = selected_month_string + selected_year_string

previous_button_xpath = "//*[@id='ui-datepicker-div']/div/a[1]"
next_button_xpath = "//*[@id='ui-datepicker-div']/div/a[2]"

Step 4 — To select the target date from the calendar, the next or previous button on the calendar control is clicked till there is a match of the selected year & month with the expected year & month.

# Navigate through the calendar to go to the required year
# and than the required month

while (selected_month_year_string != target_month_year_string):
        if (((int(target_year)) < int(selected_year_string))):
            # Click the next button
            previous_click = driver.find_element_by_xpath(previous_button_xpath)
            previous_click.click()
        else:    
            next_click = driver.find_element_by_xpath(next_button_xpath)
            next_click.click()

        elem_selected_year = driver.find_element_by_class_name("ui-datepicker-year")
        selected_year_string = elem_selected_year.get_attribute("innerHTML")

        elem_selected_month = driver.find_element_by_class_name("ui-datepicker-month")
        selected_month_string = elem_selected_month.get_attribute("innerHTML")

        selected_month_year_string = selected_month_string + space + selected_year_string

Step 5 — Now that the required year and month have been identified, dynamic XPath along with contains() method is used to select the required ‘date’ from the date picker control.

Assert is raised if there is no match between the selected date from the Calendar and the expected date.

elem_date = driver.find_element_by_xpath("//td[not(contains(@class,'ui-datepicker-other-month'))]/a[text()='" + target_date + "']")
elem_date.click()

time.sleep(10)

# Check the selected month, date, and year from the Calendar
selected_month_year_val = datepicker_val.get_attribute('value')
print(selected_month_year_val)

self.assertEqual(selected_month_year_val, expected_month_year_val)

Shown below is the output snapshot of the Selenium test automation example that demonstrated how to automate calendar using Selenium WebDriver when multiple months are present in the control.

Handling Kendo Calendar in Selenium test automation

Kendo Calendar is a popular date time picker used for websites/web applications. The only downside of using Kendo Calendar is that it would not work in old versions of Internet Explorer (IE). If your web application requires uniformity in the behavior of calendar controls across different browsers and operating systems, you should use the jQuery Calendar as you would encounter far less cross browser compatibility testing issues with jQuery Calendar.

This section of Selenium testing tutorial demonstrates how to automate calendar using Selenium WebDriver with Kendo Calendar. Below are the test case requirements:

  1. Navigate to https://demos.telerik.com/kendo-ui/datetimepicker/index

  2. Locate the datepicker element and perform a click on the same

  3. Click on the ‘next’ button in the Calendar control till the expected year & month are found.

  4. Locate the entry in the calendar matching the ‘date’ and select the same to complete the test i.e. 02/24/2024

Below is the complete implementation on how to automate calendar using Selenium WebDriver when Kendo Calendar is used.

FileName — 3_KendoUI_Selenium_Calendar_Test.py

# Selenium testing tutorial to automate calendar using Selenium WebDriver
import unittest
import time
from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

target_year = "2024"
target_month ="February"
target_date = "20"
space = " "

test_url = 'https://demos.telerik.com/kendo-ui/datetimepicker/index'

class CalendarControlTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()

    def test_calendar_control_range_(self):
        driver = self.driver
        driver.get(test_url)
        time.sleep(5)

        target_month_year_string = target_month + space + target_year

        elem_datepicker = driver.find_element_by_css_selector(".k-icon.k-i-calendar")
        elem_datepicker.click()

        time.sleep(5)

        WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "k-content")))
        elem_table = driver.find_element_by_class_name("k-content")

        # Locators for the Previous and Next Buttons
        elem_previous_button_class_name = "k-nav-prev"
        elem_next_button_class_name = "k-nav-next"

        # Locator for Month and Year Selected label
        elem_month_year_class_name = "k-nav-fast"

        elem_selected_year = driver.find_element_by_class_name(elem_month_year_class_name)
        selected_month_year_string = elem_selected_year.get_attribute("innerHTML")

        while (selected_month_year_string != target_month_year_string):
                next_click = driver.find_element_by_class_name(elem_next_button_class_name)
                next_click.click()
                time.sleep(2)

                elem_selected_year = driver.find_element_by_class_name(elem_month_year_class_name)
                selected_month_year_string = elem_selected_year.get_attribute("innerHTML")
                # print(selected_month_year_string)

        # Added a sleep to check the output
        time.sleep(5)

        for row in elem_table.find_elements_by_xpath("//tr"):
            for cell in row.find_elements_by_xpath("td"):
                if (cell.text == target_date):
                    req_date = driver.find_element_by_link_text(cell.text)
                    req_date.click()
                    break

        time.sleep(5)

        # Since we are here and all the necessary fields are selected, the test has passed.
        print("Unit Test of jQuery Calendar passed")

    def tearDown(self):
        self.driver.close()
        self.driver.quit()

if __name__ == "__main__":
    unittest.main()

Code WalkThrough

Chrome WebDriver instance is created and the URL under test is opened on the browser. Once this basic step is complete, subsequent steps to locate the element and selecting the expected date is performed.

Step 1 — The Date Picker is located using CSS Selector. Once the same is located, click operation is performed to open the Kendo Calendar.

An explicit wait of 10 seconds is added till the presence of the element with class-name of k-content. It is the Kendo Calendar on which subsequent operations will be performed.

elem_datepicker = driver.find_element_by_css_selector(".k-icon.k-i-calendar")
elem_datepicker.click()

time.sleep(5)

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "k-content")))
elem_table = driver.find_element_by_class_name("k-content")

Step 2 — For demonstration, we select the date which is in the future. The next button on the Kendo Calendar has to be clicked till the required year & month are found.

The content of the label that displays the month & year on the Kendo Calendar is accessed using the innerHTML property.

# Locators for the Previous and Next Buttons to automate calendar using Selenium WebDriver
        elem_previous_button_class_name = "k-nav-prev"
        elem_next_button_class_name = "k-nav-next"

        # Locator for Month and Year Selected label
        elem_month_year_class_name = "k-nav-fast"

        elem_selected_year = driver.find_element_by_class_name(elem_month_year_class_name)
        selected_month_year_string = elem_selected_year.get_attribute("innerHTML")

Step 3 — To select the target year & month from the calendar, the next button is pressed till the expected year & month are found.

while (selected_month_year_string != target_month_year_string):
next_click = driver.find_element_by_class_name(elem_next_button_class_name)
next_click.click()
time.sleep(2)

elem_selected_year = driver.find_element_by_class_name(elem_month_year_class_name)
selected_month_year_string = elem_selected_year.get_attribute("innerHTML")

Step 4 — We traverse through the table that contains the calendar entries and perform a search for the requested date. The content in each cell i.e. is compared against the requested date.

Inspect web elements to help developers and testers to debug UI flaws or make modifications in HTML or CSS files. Learn how to inspect element on MacBook.

Once the search is successful, a link in the corresponding cell is clicked to select the date to automate calendar using Selenium WebDriver.

for row in elem_table.find_elements_by_xpath("//tr"):
    for cell in row.find_elements_by_xpath("td"):
       if (cell.text == target_date):
          req_date = driver.find_element_by_link_text(cell.text)
          req_date.click()
          break

Shown below is the execution snapshot and browser snapshot:

Browser Compatibility Issues With Calendars

As your users access your web application using different browsers, OS and devices, a lot of device or browser compatibility issues are bound to come. This is primarily due to the fact that every browser has their own browser engine and it might not support some elements.

The major focus of Selenium test automation to automate calendar using Selenium WebDriver is ensuring consistent user-experience across different combinations used to access your web page/web app.

Five new input types were added in HTML 5 using which web developers can add calendar controls to their website using native HTML. There is no reliance on any JavaScript or jQuery library. The only downside is different experiences across various as each one has its own mechanism to render the Calendar (date time picker) control to automate calendar using Selenium WebDriver.

As seen in the screenshot from Can I Use, Calendar control input type does not have good cross browser support. Date & Time input types are not supported on any version of Internet Explorer (IE). There are issues with Calendar controls on Safari 3.1 — Safari 12.1, as well as Safari 13. The same is also applicable for a few versions of the Firefox browser.

A reliable way to handle cross-browser compatible issues with input types like Calendar controls is by making use of the jQuery Calendar. It provides uniformity in widget interface across all the browsers and even works with unsupported browsers like IE and Safari. You can also have a look at our detailed blog on Handling cross browser compatibility issues with different input types.

Using Online Selenium Grid For Exhaustive Verification Of ‘Calendar Controls’

Rather than approaching this problem by implementing a non-scalable approach of housing different combinations of browsers, operating systems, and devices; it is better to perform Selenium test automation on the cloud. Lambdatest’s cross browser testing platform helps you to improve test coverage and better scalability.

The existing implementation to automate calendar using Selenium WebDriver requires minimal changes as execution occurs on an online Selenium Grid instead of a local machine. As tests can be executed in parallel, you can expect faster turn-around time leading to better productivity.

Below are the steps you’d need to use your Selenium test automation script on LambdaTest’s online Selenium Grid:

  1. First you’ll need to make sure you have an account on LambdaTest. Make a note of the user-name and access-key which are required for accessing the remote Selenium Grid on LambdaTest.

  2. Select the appropriate plan depending on the test requirements

  3. Create browser capabilities using Desired Capabilities Generator on LambdaTest.

  4. Modify the existing implementation to accommodate changes for execution on remote Selenium Grid.

You can refer to one of our earlier Selenium testing tutorials on LambdaTest to get started with cross browser testing.

Looking to streamline your browser testing process? Look no further than our state-of-the-art platform for conducting browser tests. With our comprehensive tools for manual and automated cross browser testing, you can seamlessly test your web application across a vast range of browsers.

It’s a Wrap!

In this Selenium testing tutorial, we had a look at the most popular Calendar controls and how to perform Selenium test automation on these Calendar controls. Input types like date time pickers, color pickers, etc. are increasingly being used in web development.

There is no thumb rule to automate calendar using Selenium WebDriver as there are different types of Calendar Controls and their behavior might vary from one browser to another. This is where Selenium test automation on the cloud can be instrumental as it lets you verify the test code on numerous combinations of browsers, operating systems, and devices.

Do let us know what are some of the challenges that you have faced while trying to automate calendar using Selenium WebDriver in the comment section down below. Do share this article with your peers by retweeting us or by sharing this article on LinkedIn. Happy Testing!!!