7

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>
BruceyBandit
  • 3,978
  • 19
  • 72
  • 144
  • [Please do not bump your questions by posting a new question as a plea for attention](http://stackoverflow.com/questions/35241704/selecting-dates-from-a-datepicker-selenium-ide). Your bounty is more than enough for that. – AStopher Feb 06 '16 at 14:13
  • 1
    Why are you using `Selenium IDE` and not any selenium webdriver language bindings? Would you be okay with a, say, Python-Selenium based answer? – alecxe Feb 06 '16 at 15:57
  • @alecxe It's because our company mainly uses selenium ide. I'm actually a manual tester but want to learn some automation so I can run tests much quicker. If python-Selenium will help with selenium ide then yes go for it. Virtually I just need to know the commands on how to do it. I believe I need to do a storeeval and loop through the days until I can find the next available date but just can't seem to figure out how to do it. – BruceyBandit Feb 06 '16 at 16:22
  • @BruceyBandit okay, I think the code is ready to be reviewed and tested. Hope it would help to solve the problem. Let me know if you need help understanding what is going on in the code. Thanks. – alecxe Feb 06 '16 at 17:10
  • @BruceyBandit can you get support from back end team to get list of possible available dates by departure and arrival points? Reason I ask this is because we faced similar problems. That time, we used to get list of available dates from database and pass them through url and test. Eg: In this url, you can see dep point, arrival point, departure date, arrival date, number of adults http://www.jet2.com/cheap-flights/leeds-bradford/larnaca/2016-04-27/2016-05-04?adults=2. – Abdul Hameed Feb 06 '16 at 18:38
  • @AbdulHameed Hi Abdul. actually you will need to do the same thing on that page, find the first flight that's available. If you can do that for just the first calendar then you've cracked it and then I can look to see what you've done and learn from it to try and implement for the arrival dates. If you try manually, move to next month to Apr, you'll see available dates. – BruceyBandit Feb 06 '16 at 20:19
  • @AbdulHameed Oh I understand now. You used deeplinks to retrieve it. The thing is, we don not know the dates for any flight unless we manually search. That's why we need the script to do it for us automatically, or else we have to breakpoint the script, select the dates manually before running the script again afterwards. I know it's not easy, hence why I put 400 points on it. – BruceyBandit Feb 06 '16 at 20:33

3 Answers3

5

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)

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • Selenium in python does actually look really cool., I will learn this in my free time at home with your answer and documents. However, I now know why we use selenium ide, because it's quicker to just record our manual tests. The calender is the only glitch in terms of needing to do something fancy in the background but with just IDE, we just record our manual tests as we go through. Upvote answer as its very good but it will have to be IDE only. Won't have time to type python scripts whilst performing manual tests in the workplace. – BruceyBandit Feb 06 '16 at 17:17
  • @alecxe thanks for the explanation, is there a way to use your code and do the following? check a website and if a time in a specific month is open take that time as an appointment, if there is not any time available in that specific month check again in 15 minutes, and keep doing that till the time is available and booking has been made? after the booking is made finish the loop and report it to the user. – Alex Apr 05 '21 at 23:25
1

It is quite challenging to do this via Selenium IDE. Refer link here and see how gotoIF works. Download user extension js from here and add to your selenium IDE. If you can use Selenium Webdriver then it will be easy for you to achieve.

My below examples are to do via Selenium IDE. I have given example only to select outbound flight. In both cases, I first send the url with today's date as departure and arrival date. I then use gotoIf to select first available date for outbound.

Example 1:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://www.jet2.com/" />
<title>21jet2_01</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">21jet2_01</td></tr>
</thead><tbody>
<tr>
    <td>open</td>
    <td>/cheap-flights/leeds-bradford/larnaca/2016-02-07/2016-02-07?adults=2</td>
    <td></td>
</tr>
<tr>
    <td>storeElementPresent</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td>x</td>
</tr>
<tr>
    <td>gotoIf</td>
    <td>${x} == true</td>
    <td>select</td>
</tr>
<tr>
    <td>label</td>
    <td>clickNextMonth</td>
    <td></td>
</tr>
<tr>
    <td>clickAndWait</td>
    <td>xpath=//div[@class='monthview outbound ']/div/div[2]/a[@class='changepage nextmonth icon icon-arrow-next']</td>
    <td></td>
</tr>
<tr>
    <td>storeElementPresent</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td>y</td>
</tr>
<tr>
    <td>gotoIf</td>
    <td>${y} == false</td>
    <td>clickNextMonth</td>
</tr>
<tr>
    <td>label</td>
    <td>select</td>
    <td></td>
</tr>
<tr>
    <td>click</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td></td>
</tr>
</tbody></table>
</body>
</html>

Example 2:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://www.jet2.com/" />
<title>21jet2_01</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">21jet2_01</td></tr>
</thead><tbody>
<tr>
    <td>open</td>
    <td>/cheap-flights/belfast/alicante/2016-02-07/2016-02-07?adults=2</td>
    <td></td>
</tr>
<tr>
    <td>storeElementPresent</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td>x</td>
</tr>
<tr>
    <td>gotoIf</td>
    <td>${x} == true</td>
    <td>select</td>
</tr>
<tr>
    <td>label</td>
    <td>clickNextMonth</td>
    <td></td>
</tr>
<tr>
    <td>clickAndWait</td>
    <td>xpath=//div[@class='monthview outbound ']/div/div[2]/a[@class='changepage nextmonth icon icon-arrow-next']</td>
    <td></td>
</tr>
<tr>
    <td>storeElementPresent</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td>y</td>
</tr>
<tr>
    <td>gotoIf</td>
    <td>${y} == false</td>
    <td>clickNextMonth</td>
</tr>
<tr>
    <td>label</td>
    <td>select</td>
    <td></td>
</tr>
<tr>
    <td>click</td>
    <td>xpath=//div[@class='monthview outbound ']/div[2]/table/tbody/tr/td[starts-with(@class, &quot;LS1FlightDay flights&quot;)]/a/div/span[@class='fare']</td>
    <td></td>
</tr>
</tbody></table>
</body>
</html>
Abdul Hameed
  • 1,135
  • 1
  • 13
  • 24
0

Here is the Java version.

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class DatePicketJet2 {
    public static WebDriver browser;

    public static void main(String args[]) throws InterruptedException {

        browser = new FirefoxDriver();
        String url = "http://www.jet2.com/";

        browser.get(url);
        browser.manage().window().maximize();

        browser.findElement(By.id("departureAirportList")).click();  
        WebElement departureCountry = browser.findElement(By.id("destinations-uk"));
        WebElement departureCityLocator = departureCountry.findElement(By.tagName("ul"));
        List<WebElement> departureCities = departureCityLocator.findElements(By.tagName("li"));
        /*
        for (WebElement we : departureCities) {
            System.out.println(we.getText());
        }
        */
        departureCities.get(1).click();

        browser.findElement(By.id("destinationAirportList")).click();  

        WebElement destinationCountry = browser.findElement(By.id("destinations-country"));
        WebElement destinationCityLocator = destinationCountry.findElement(By.tagName("ul"));
        List<WebElement> destinationCities = destinationCityLocator.findElements(By.tagName("li"));
        /*
        for (WebElement we : destinationCities) {
            System.out.println(we.getText());
        }
        */
        destinationCities.get(1).click();

        browser.findElement(By.id("departure-date-selector")).click();

        WebElement departureMonth = browser.findElement(By.tagName("tbody"));
        //System.out.println(departureMonth.getText());
        List<WebElement> departureDate = departureMonth.findElements(By.tagName("a"));
        for (WebElement we : departureDate) {
            System.out.println("~" + we.getText());
            we.click();
            break;
        }

        browser.findElement(By.id("return-date-selector")).click();
        Thread.sleep(1000);
        WebElement returnMonth = browser.findElement(By.tagName("tbody"));
        System.out.println("<>" + returnMonth.isEnabled());
        System.out.println(returnMonth.getText());
        List<WebElement> returnDate = returnMonth.findElements(By.tagName("a"));
        for (WebElement we1 : returnDate) {
            System.out.println("~" + we1.getText());
            we1.click();
            break;
        }
        Thread.sleep(1000);
        browser.close();
    }
}

Look out for the <tbody> and find all visible dates using tag by name as "a" you will get all the dates which are viable or showing in green color.

Later refine your logic based on your requirement.

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
Jagdeep
  • 139
  • 3
  • 12
  • Hi Jagdeep, this answer will b helpful for those doing Java. I will upvote it. However I will need just the basic command, target and values to place in IDE. I stated the reason why in the comment in the answer before yours on why that is. Do you know how to do it just with IDE? – BruceyBandit Feb 06 '16 at 18:13
  • You need programming to get to know on the available dates. IDE is just for recording, you need to play around with code otherwise it will be difficult to get the dates which are in green. Hope your understand this. IDE is limited to give you format of what the test will look like, it will help you write code faster. I am not sure even the google guys use this way as you are asking. Please consider it as a tool for better and faster coding on automation but just not only rely on IDE. HTH – Jagdeep Feb 06 '16 at 18:34
  • It can be done though because a collegue of mine has done it. He didn't have the file with him but he stated we use storeEval, whileloops and echo in order to do it. – BruceyBandit Feb 06 '16 at 19:43