היי חברים, בפוסט הזה אני רוצה להציג בפניכם את היכולת המדהימה של שימוש ב-Lambda Expression  עם ה-ExplicitlyWait שמגיע עם Selenium WebDriver בכדי להרחיב את ארגז הכלים שלנו לסוגי המתנות שונים.

תראו, זה לא סוד כי אחד מהדברים המעצבנים ביותר שיש לנו ב-Selenium הוא כל עניין הסינכרוניזציה בין במערכת הבודקת (Selenium) לבין המערכת הנבדקת (אותה אפליקציית Web), להבדיל מכלי אוטומציה אחרים, כמו Cypress או Playwright שם נושא ההמתנות כבר מטופל באופן אוטומטי, ב-Selenium אנו נצטרך להתאמץ קצת יותר בשביל להגיע לאותן תוצאות המתנה.

 

בגדול, Selenium WebDriver מגיע עם כמה סוגי המתנות:

PageLoadTimeout

ImplicitlyWait

ExplicitlyWait

FluentWait

על חלק מההמתנות הללו הרחבנו בפוסט אחר בבלוג שלנו: המתנה חכמה (מוזמנים לקרוא)

 

אז כאמור, בפוסט הזה אני רוצה להציג לכם שיטה מתקדמת, נקייה ואלגנטית להרחיב את יכולות ה-Wait שלנו, ע"י כתיבה של קוד קצר עם Lambda Expression

נתחיל בדוגמא פשוטה, נגיד ואנו מעוניינים להמתין לאלמנט עד שהוא יוצג על המסך (שימו לב, אלמנט מוצג, לא קיים). בשביל זה יש לנו מימוש מובנה ב-ExplicitlyWait שזוהי מתודת ה-visibilityOf. הקוד שלנו להמתנת האלמנט יכול למשל להיראות כך:

 

private WebDriverWait wait;

@FindBy(id = "example")
private WebElement example;

public void verifyExampleDisplayed() {
    wait = new WebDriverWait(driver, Duration.ofSeconds(5));
    wait.until(ExpectedConditions.visibilityOf(this.example));
    assertTrue(this.example.isDisplayed());
}

עשיתי כאן שימוש ב-Page Objects (אלמנט ה-example) וכפי שאנו רואים בקוד הנ"ל, אנו מפעילים את מתודת ה-visibilityOf של מחלקת ה-ExpectedConditions שקיימת לנו כבר ב-Selenium.

  • ניתן היה לוותר על ה-Assert מכיוון שעצם ההמתנה הייתה זורקת Eשגיאה במידה ותנאי לא היה מתקיים תוך x זמן
  • איתחול ה-wait אינו אמור לשבת תחת מתודת ה-verifyExampleDisplayed , הכנסתי אותו לכאן למען הדוגמא

 

ה-Lambda Expression הוא למעשה הגדרה של פונקציות ללא מזהה (אנונימיות), היתרון הבולט של פונקציות אלו הוא תחביר מקוצר בהשוואה להגדרת פונקציה רגילה וכן יתרונות נוספים שאינני מתכוון לכסות כאן בפוסט. ישנם המון מדריכים על פונקציות Lambda באינטרנט ואני מזמין אתכם לקרוא ולחקור.

איך היינו משנים את הקוד הנ"ל עם שימוש ב-Lambda Expression ? את מתודת ה-verifyExampleDisplayed היינו מגדירים כך:

public void verifyExampleDisplayed() {
    wait = new WebDriverWait(driver, Duration.ofSeconds(5));
    wait.until((d) -> this.example.isDisplayed());
    assertTrue(this.example.isDisplayed());
}

ה-d במקרה הזה הוא בסה"כ שם של משתנה, לצורך הדוגמא, הייתי יכול לקרוא לו גם kuku , העניין הוא שהמשתנה הזה מייצג לי אובייקט של ה-WebDriver (על כן קראתי לו d שהוא קיצור של driver), למעשה היינו יכולים להפעיל עליו אח"כ כל מתודה שאנו מפעילים על ה-driver , כמו למשל:

wait.until((d) -> d.getTitle());

אז אנחנו שולחים לפונקציה האנונימית אובייקט של ה-driver ומה אנו מצפים בתמורה ? שהוא יפעיל את מתודת ה-isDisplayed על אלמנט ה-example, את כל זה אנחנו מכיניסים לתוך קריטריון ההמתנה (until) שלנו.

יופי, למה היינו צריכים את זה ? מה בסופו של דבר קיצרנו פה בקוד ? למען האמת בדוגמא הזו, אין פה ממש קיצור דרך ופשוט החלפנו פעולה אחת באחרת. אבל (וזה אבל גדול מאוד), עצם זה שאנו יודעים להשתמש ב-Lambda Expression , אנו למעשה לא מוגבלים כלל במימושים המובנים של Selenium.

לדוגמא, נגיד שאנו מעוניינים להמתין למשהו מורכב יותר, משהו חכם יותר מאשר להצגת אלמנט כפי שראינו מקודם, בו ניקח את המקרה הבא:

  1. כנס לאתר של גוגל
  2. חפש באתר "עתיד האוטומציה"
  3. המתן לתוצאות החיפוש
  4. בחר את התוצאה החמישית מלמעלה ולחץ עליה…

בואו נתמקד בסעיף 3 , איך היינו מבצעים המתנה לכל תוצאות החיפוש ? או אפילו יותר מורכב מזה, איך היינו ממתינים לחמשת תוצאות החיפוש הראשונות ? מממ… קצת מאתגר הא ?

אז זהו, שבעזרת Lambda Expression, אפשר לממש פעולה כזו די בקלות, כך:

@FindBy(id = "example")
private List<WebElement> results;

public void clickOnFifthResult() {
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until((d) -> this.results.size() > 5);
    this.results.get(4).click();
    // Continue with business flow...
}
  • שימו לב כי תפסנו כאן ב-Page Objects רשימה של אלמנטים
  • קריטריון ההמתנה שלנו כאן הוא עד שגודל הרשימה של תוצאות החיפוש יהיה מעל ל-5 תוצאות

 

פשוט, קל, אלגנטי !

גם את החלק של ההמתנות המורכבות הזה אנחנו מכסים במלואו בקורס האוטומציה למתקדמים שלנו: Automation++ , לפרטים נוספים, הקישו כאן

בהצלחה,

סאיד גאבר

 

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