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:
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"> </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"> </td><td class=" ui-datepicker-week-end ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled"> </td>
<td class=" ui-datepicker-week-end ui-datepicker-other-month ui-datepicker-unselectable ui-state-disabled"> </td>
</tr>
</tbody>
</table>
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:
Firefox()
in this example but there are other choices too) ui-datepicker-current-day
class following
axis. If yes, print it out and click. 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)
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, "LS1FlightDay flights")]/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, "LS1FlightDay flights")]/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, "LS1FlightDay flights")]/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, "LS1FlightDay flights")]/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, "LS1FlightDay flights")]/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, "LS1FlightDay flights")]/a/div/span[@class='fare']</td>
<td></td>
</tr>
</tbody></table>
</body>
</html>
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.
链接地址: http://www.djcxy.com/p/56634.html