This blog is about automating the rich face calendar component using Selenium WebDriver. This is quite a useful component and is used where ever date needs to be filled in. Sample calendar component is shown below:
, shown above.
4) After we reach the correct month, the only task left is to calculate which day index to select. Day index starts at zero in the sample calendar shown above.
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
interface Xpaths
{
/*
* This inteface contains all the xpath's that are used in the program
*/
String calendarPopUpButtonxPath = "//*[@id='j_id354:j_id355PopupButton']";
String monthIncrementerxPath = "//*[@id='j_id354:j_id355Header']/table/tbody/tr/td[4]/div";
String monthDecrementerxPath = "//*[@id='j_id354:j_id355Header']/table/tbody/tr/td[2]/div";
String dayxPathPart1 = "//*[@id='j_id354:j_id355DayCell";
String dayxPathPart2 = "']";
String dayZeroxPath = "//*[@id='j_id354:j_id355DayCell0']";
String applyButtonxPath = "//*[@id='j_id354:j_id355Footer']/table/tbody/tr/td[6]/div";
}
interface Months
{
int JANUARY = 1,
FEBRUARY = 2,
MARCH = 3,
APRIL = 4,
MAY = 5,
JUNE = 6,
JULY = 7,
AUGUST = 8,
SEPTEMBER = 9,
OCTOBER = 10,
NOVEMBER = 11,
DECEMBER = 12;
int MAX_DAY_IN_A_MONTH = 31;
}
public class AutomateJsfCalendar implements Xpaths,Months
{
/**Months
* @param args
*/
static int targetDay = 0,
targetMonth = 0,
targetYear = 0;
static int currentDay = 0,
currentMonth = 0,
currentYear = 0;
static int jumpMonthsBy = 0,
index = 0;
static boolean increment = true;
public static void main(String[] args)
{
WebDriver driver = new FirefoxDriver();
driver.navigate().to("http://livedemo.exadel.com/richfaces-demo/richfaces/calendar.jsf");
driver.manage().timeouts().implicitlyWait(15L, TimeUnit.SECONDS);
driver.manage().window().maximize();
WebElement element = driver.findElement(By.xpath(calendarPopUpButtonxPath));
element.click();
//At this point, jsf calendar component is displayed.
//Today's date is 30/03/2013. Let us say we want to set the date as 15/07/2013
String dateToSet = "15/07/2013";
GetTargetDateMonthAndYear(dateToSet);
GetCurrentDateMonthAndYear();
CalculateHowManyMonthsToJump();
for(int i=0;i<jumpMonthsBy;i++)
{
if(increment)
element = driver.findElement(By.xpath(monthIncrementerxPath));
else
element = driver.findElement(By.xpath(monthDecrementerxPath));
element.click();
try
{
//sleep will let you see the automation happening.
Thread.sleep(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
CalculateCorrectDayIndex(driver);
String completePath = dayxPathPart1 + index + dayxPathPart2;
element = driver.findElement(By.xpath(completePath));
element.click();
element = driver.findElement(By.xpath(applyButtonxPath));
element.click();
//driver.quit();
}//end of main..
/*
*This method will bisect the target date and upadates targetDay, targetMonth & targetYear variables.
*/
static void GetTargetDateMonthAndYear(String dateString)
{
int firstIndex = dateString.indexOf("/");
int lastIndex = dateString.lastIndexOf("/");
String month = dateString.substring(0, firstIndex);
targetDay = Integer.parseInt(month);
String day = dateString.substring(firstIndex+1, lastIndex);
targetMonth = Integer.parseInt(day);
String year = dateString.substring(lastIndex+1, dateString.length());
}
/*
* This method will fetch current date and updates currentDay, currentMonth & currentYear variables.
*/
static void GetCurrentDateMonthAndYear()
{
Calendar cal = Calendar.getInstance();
currentDay = cal.get(Calendar.DAY_OF_MONTH);
currentMonth = cal.get(Calendar.MONTH)+1;//+1 because month values starts from 0. January = 0.
currentYear = cal.get(Calendar.YEAR);
}
/*
* This method decides how many time this ">" element on the calendar component needs to be clicked to reach target month.
*/
static void CalculateHowManyMonthsToJump()
{
if((targetMonth - currentMonth) > 0 )
{
jumpMonthsBy = (targetMonth - currentMonth);
}
else
{
jumpMonthsBy = (currentMonth - targetMonth);
increment = false;
}
}
/*
* This calculates the current index that holds the targetDay value that we need to click in the calendar control.
*/
static void CalculateCorrectDayIndex(WebDriver driver)
{
int tempMonth = targetMonth - 1;
if(tempMonth == 0)
{
//if target month is January, control will come inside.
tempMonth = DECEMBER;
}
WebElement element = driver.findElement(By.xpath(dayZeroxPath));
String str = element.getText();
int dayValueAtZeroIndex = Integer.parseInt(str);
if(dayValueAtZeroIndex == 1)
{
index = targetDay - 1;
}
else
{
switch(tempMonth)
{
case JANUARY:
case MARCH:
case MAY:
case JULY:
case AUGUST:
case OCTOBER:
case DECEMBER:
{
index = ((MAX_DAY_IN_A_MONTH - dayValueAtZeroIndex) + targetDay);
break;
}
case FEBRUARY:
{
/*
* Separate case is needed for feb because Feb contains only 28(MAX_DAY_IN_A_MONTH - 3) days.
*/
index = (((MAX_DAY_IN_A_MONTH - 3) - dayValueAtZeroIndex) + targetDay);
break;
}
default:
{
//Control will come here for months that consists of 30(MAX_DAY_IN_A_MONTH - 1) days.
index = (((MAX_DAY_IN_A_MONTH - 1) - dayValueAtZeroIndex) + targetDay);
break;
}
}
}
}
}//end of class.
1) Interface that only contain variables.
2) How the class implements multiple interfaces using the <implements> keyword.
3) How to use switch statements.
4) Modular programming by implementing separate method for different tasks.
Comments are welcome.
Thanks :)