Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium IDE: How to select next available date from datepicker

I want my selenium IDE test case to run like the steps below in order to select a date automatically:

  • Click departure date to open datepicker
  • Starting with day currently selected, loop through dates until reaching the next available date (If required move onto the next month or year to find the next available date)
  • Select the available date from the datepicker

Can somebody show me as I'm new to selenium on how to do this for the above example? All my script can do at the moment is open the calendar.

Below is the html I managed to receive that matches with the screenshot above:

//Months drop down
    <select class="ui-datepicker-month" data-handler="selectMonth" data-event="change">
    <option value="2" selected="selected">Mar
    </option><option value="3">Apr</option>
    <option value="4">May</option>
    <option value="5">Jun</option>
    <option value="6">Jul</option>
    <option value="7">Aug</option>
    <option value="8">Sep</option>
    <option value="9">Oct</option>
    </select>
//Years drop down
    <select class="ui-datepicker-year" data-handler="selectYear" data-event="change">
    <option value="2016" selected="selected">2016</option>
    </select>
    <table class="ui-datepicker-calendar">
//days labels
    <thead>
    <tr>
    <th scope="col"><span title="Monday">Mo</span></th>
    <th scope="col"><span title="Tuesday">Tu</span></th>
    <th scope="col"><span title="Wednesday">We</span></th>
    <th scope="col"><span title="Thursday">Th</span></th>
    <th scope="col"><span title="Friday">Fr</span></th>
    <th scope="col" class="ui-datepicker-week-end"><span title="Saturday">Sa</span></th>
    <th scope="col" class="ui-datepicker-week-end"><span title="Sunday">Su</span></th>
    </tr>
    </thead>
    <tbody>
//dates
    <tr>
    <td class=" ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled">&nbsp;</td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">1</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">2</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">3</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">4</span></td>
    <td class=" ui-datepicker-week-end ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">5</span></td>
    <td class=" ui-datepicker-week-end ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">6</span></td></tr>
    <tr>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">7</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">8</span></td>
    ...same process till last week of dates (bottom row of calendar in screenshot)
    <tr>
    <td class=" ui-datepicker-days-cell-over  ui-datepicker-current-day" title="Click to see flights on this date" data-handler="selectDay" data-event="click" data-month="2" data-year="2016"><a class="ui-state-default ui-state-active" href="#">28</a></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">29</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">30</span></td>
    <td class=" ui-datepicker-unselectable ui-state-disabled " title="No available flights on this date"><span class="ui-state-default">31</span></td>
    <td class=" ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled">&nbsp;</td><td class=" ui-datepicker-week-end ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled">&nbsp;</td>
    <td class=" ui-datepicker-week-end ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled">&nbsp;</td>
    </tr>
    </tbody>
    </table>
like image 383
BruceyBandit Avatar asked Dec 04 '11 17:12

BruceyBandit


People also ask

How will you select a date from a Datepicker in a webpage using Selenium for automated testing explain with a proper code?

Steps to select Date from Datepicker with Selenium and Java For Chrome, right-click and inspect the given element to find its XPath. To find XPath of a UI element in Firefox, right-click on the desired element, go to “Inspect Element” to open the inspector which will help identify the XPath of the desired element.

How do you automate a calendar in Selenium?

Step 1 - Initiate WebDriver and set the application's URL where a Calendar is implemented. Define the xpath with the Calendar control's id (in this example it is - travel_date) from the html source to find the element and later use that object to initiate the click action.


1 Answers

Automating such a task in a Selenium IDE would be quite challenging since there is a non-trivial logic involved in getting the next available date, you should consider switching to Selenium WebDriver picking one of the selenium language bindings available.

Here is a working code made using Python language Selenium bindings. The idea is to:

  • instantiate a WebDriver (using Firefox() in this example but there are other choices too)
  • maximize the browser window
  • navigate to the URL (http://www.jet2.com)
  • wait until the page is loaded explicitly (docs)
  • fill out the departure and destination fields
  • click the "Depart" field to trigger the calendar to be shown
  • in the calendar, locate the current date - it has the ui-datepicker-current-day class
  • check if there is an available date in this month using the "by XPath" location technique and following axis. If yes, print it out and click.
  • if we have not found the next available date in this month, initialize and "endless" loop and click the "Next" month button checking if we have an available date present. Print it out and click if found and exit the loop. Otherwise, click the "Next" button.
  • if we don't have the "Next" button - then we are at the end of a year, select the next year in the year dropdown, continue the loop
  • close the driver when done

The Code:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


FROM = "Leeds Bradford"
TO = "Budapest BUD"

driver = webdriver.Firefox()  # or, webdriver.Chrome(), or webdriver.PhantomJS() or etc.
driver.maximize_window()
driver.get("http://www.jet2.com")

wait = WebDriverWait(driver, 10)
actions = ActionChains(driver)

# wait for the page to load
wait.until(EC.presence_of_element_located((By.ID, "departure-airport-input")))

# fill out the form
driver.find_element_by_id("departure-airport-input").send_keys(FROM)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#ui-id-1 .ui-menu-item"))).click()

driver.find_element_by_id("destination-airport-input").send_keys(TO)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#ui-id-2 .ui-menu-item"))).click()

# select date
datepicker = driver.find_element_by_id("departure-date-selector")
actions.move_to_element(datepicker).click().perform()

# find the calendar, month and year picker and the current date
calendar = driver.find_element_by_id("departureDateContainer")
month_picker = Select(calendar.find_element_by_class_name("ui-datepicker-month"))
year_picker = Select(calendar.find_element_by_class_name("ui-datepicker-year"))
current_date = calendar.find_element_by_class_name("ui-datepicker-current-day")

# printing out current date
month = month_picker.first_selected_option.text
year = year_picker.first_selected_option.text
print("Current date: {day} {month} {year}".format(day=current_date.text, month=month, year=year))

try:
    # see if we have an available date in this month
    next_available_date = current_date.find_element_by_xpath("following::td[@data-handler='selectDay' and ancestor::div/@id='departureDateContainer']")
    print("Found an available date: {day} {month} {year}".format(day=next_available_date.text, month=month, year=year))
    next_available_date.click()
except NoSuchElementException:
    # looping over until the next available date found
    while True:
        # click next, if not found, select the next year
        try:
            calendar.find_element_by_class_name("ui-datepicker-next").click()
        except NoSuchElementException:
            # select next year
            year = Select(calendar.find_element_by_class_name("ui-datepicker-year"))
            year.select_by_visible_text(str(int(year.first_selected_option.text) + 1))

        # reporting current processed month and year
        month = Select(calendar.find_element_by_class_name("ui-datepicker-month")).first_selected_option.text
        year = Select(calendar.find_element_by_class_name("ui-datepicker-year")).first_selected_option.text
        print("Processing {month} {year}".format(month=month, year=year))

        try:
            next_available_date = calendar.find_element_by_xpath(".//td[@data-handler='selectDay']")
            print("Found an available date: {day} {month} {year}".format(day=next_available_date.text, month=month, year=year))
            next_available_date.click()
            break
        except NoSuchElementException:
            continue

driver.close()

Test results:

  • Leeds Bradford -> Antalya AYT (next available date in April):

    Current date: 28 Mar 2016
    Processing Apr 2016
    Found an available date: 4 Apr 2016
    
  • Leeds Bradford - > Budapest BUD (next available date in the same month as current date):

    Current date: 12 Feb 2016
    Found an available date: 15 Feb 2016
    
  • ? (next available date in the next year)

like image 74
alecxe Avatar answered Oct 18 '22 10:10

alecxe