באפליקציה שלנו אנו נתקלים בפקדים שונים , כאלו שפשוט לאטמט (To Automate) עם סלניום כמו כפתורי רדיו (Radio Buttons) , שדות טקסט וכו' , כאלו שקצת קשה יותר לאטמט כמו ComboBox וכאלו שעוד קשה יותר לאטמט כמו ה-DatePicker. אין זה אומר שזוהי משימה בלתי אפשרית, רק פשוט צריך להחיל איזושהי לוגיקה מסויימת על הפקד בשביל להתמודד עימו בהצלחה.

כיום קיימים שני סוגים עיקריים של Date Pickers איתם אנו נוהגים לעבוד, האחד מסוג jQuery , השני מסוג Kendo (של חברת Telerik).

דוגמא ל- jQuery Date-Picker

דוגמא ל- Kendo Date-Picker

 

בפוסט זה נראה כיצד ניתן לעבוד עם סלניום מול שני Date Pickers האלו

תחילה אנו צריכים להבין (וניתן לראות זאת בקלות בקוד ה-HTML) כי הפקדים הללו למעשה בנויים כטבלאות HTML , עם תגיות TR ו-TD:

 

עם הידיעה הזו נוכל פשוט להתחיל לפרסס את הטבלה על ידי חלוקה לאלמנטים המתבססים על פי העמודות \ השורות או במילים אחרות לפני תגיות ה-TR \ TD. אז כרגע אנחנו יודעים שני דברים על התוכנית שלנו:

1. כשמדברים על טבלאות , יש צורך להשתמש בלולאות

2.  מכיוון שאנו מדברים על תגיות – TR/TD נוכל להיעזר ב-Locator – tagName

את השורות והעמודות נכניס לרשימות (Lists) , כל אחת תזכה לרשימה משלה ועליהן נרוץ בשתי לולאות קאנוניות (כשהאחת תרוץ על השורות והשנייה על העמודות)

ב-Kendo Date Picker, הקוד יראה כך:

String DAY = "10";
driver.get("http://demos.telerik.com/kendo-ui/datetimepicker/index");	// Navigate to Telerik page	
driver.findElement(By.cssSelector("span[aria-controls='datetimepicker_dateview']")).click();  // Open Date-Picker
WebElement table = driver.findElement(By.className("k-content"));   
List<WebElement> tableRows = table.findElements(By.tagName("tr"));  // List of Rows
for (WebElement row : tableRows)     // Run on Rows
{
	List<WebElement> cells = row.findElements(By.tagName("td"));    // List of Columns
	for (WebElement cell : cells)   // Run on Columns
	{
		if (cell.getText().equals(DAY))
		{
			driver.findElement(By.linkText(DAY)).click();
		}
	}
}

 

ב-jQuery Date Picker, הקוד יראה כך:

String DAY = "10";
driver.get("http://jqueryui.com/resources/demos/datepicker/other-months.html");   // Navigate to jQuery page	
driver.findElement(By.id("datepicker")).click();   // Open Date-Picker
WebElement dateWidget = driver.findElement(By.id("ui-datepicker-div"));
 List columns = dateWidget.findElements(By.tagName("td"));   // List of Columns
for (WebElement cell:columns)    // Run on Columns (Cells)
{
	 if (cell.getText().equals(DAY))
	 {
	       cell.findElement(By.linkText(DAY)).click();
	       break; 
	 }
}

* שימו לב כי ניתן למעשה לרוץ רק על ה-TD (שמייצגים לי תאים בטבלה) ומשם לשלוף את הנתון הרלוונטי ולהקליק עליו

 

בואו עכשיו ונעביר הילוך, עד עתה ראינו כיצד ניתן לבחור תאריך לפי היום באותו חודש נוכחי שמופיע בפקד (החודש שאנו נמצאים בו כעת), אבל מה קורה כאשר נרצה לדפדף ולעבור בין חודשים או שנים קדימה ואחורה ?

במקרה כזה נרצה קודם לקרוא את האלמנטים המייצגים את חודש והשנה ב-Date Picker :

נגדיר את תאריך היעד שנרצה להגיע אליו לפי שלושה פרמטרים: expDate , expMonth , expYear

כעת נוכל להשוות בהתנייה את תאריך היעד לעומת מה שקראנו עם הסלניום – אלמנט החודש + השנה, במידה ונמצאו החודש והשנה (ההתניה מחזירה true) נבחר את היום לפי אותה שיטה שכבר ראינו בתחילת הפוסט.

במידה והחודש והשנה לא נמצאו אנו נתחיל "לשחק" עם כפתורי ה-Next ו-Previous למעבר בין חודשים בהתאמה ושוב נחזור על תהליך ההשוואה. כך התוכנית אמורה להיראות:

WebElement datePicker;
List<WebElement> noOfColumns;
List<String> monthList = Arrays.asList("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
int expMonth = 2016;
int expYear = 4;
String expDate = "18";
String calMonth = null;
String calYear = null;

driver.get("http://jqueryui.com/resources/demos/datepicker/other-months.html");
driver.findElement(By.id("datepicker")).click();

while (dateNotFound)
{
	calMonth = driver.findElement(By.className("ui-datepicker-month")).getText();
	calYear = driver.findElement(By.className("ui-datepicker-year")).getText();	
	if(monthList.indexOf(calMonth)+1 == expMonth && (expYear == Integer.parseInt(calYear)))
	{
		datePicker = driver.findElement(By.id("ui-datepicker-div")); 
		noOfColumns=datePicker.findElements(By.tagName("td"));
		 
		for (WebElement cell: noOfColumns)
		{
			 if (cell.getText().equals(expDate))
			 {
				 cell.findElement(By.linkText(expDate)).click();
				 break;
			 }
		}
	}
	else if(monthList.indexOf(calMonth)+1 < expMonth && (expYear == Integer.parseInt(calYear)) || expYear > Integer.parseInt(calYear))
	{
		driver.findElement(By.cssSelector("a[data-handler='next']")).click();											  
	}
	else if(monthList.indexOf(calMonth)+1 > expMonth && (expYear == Integer.parseInt(calYear)) || expYear < Integer.parseInt(calYear))
	{
		driver.findElement(By.cssSelector("a[data-handler='prev']")).click();
	}
}

 

השאר הערה\הודעה