באפליקציה שלנו אנו נתקלים בפקדים שונים , כאלו שפשוט לאטמט (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(); } }