מדריך עזר לסקריפטים Robo

במסמך הזה מפורט מידע על סקריפטים של Robo, כולל המבנה, היכולות, השימוש, ההקלטה והפעולות. סקריפטים של רובוטים הם בדיקות שמבצעות אוטומציה של משימות בקרת איכות (QA) ידניות לאפליקציות לנייד, ומאפשרות אסטרטגיות של אינטגרציה רציפה (CI) ובדיקות לפני השקה. סקריפט של Robo הוא קובץ JSON שמתאר רצף של פעולות בממשק המשתמש (UI) ופעולות אחרות.

אפשר ליצור סקריפט של Robo בדרכים הבאות:

  • שימוש בתכונה של הקלטת סקריפט של Robo. (Android בלבד)

  • יוצרים את סקריפט ה-Robo באופן ידני. (Android ו-iOS+)

  • מתעדים את סקריפט ה-Robo ולאחר מכן עורכים אותו באופן ידני. (Android בלבד)

מידע נוסף על שימוש בסקריפטים של Robo זמין במאמר הרצת סקריפט של Robo.

מבוא

סקריפט Robo מסופק לבדיקה של Robo לצד נתוני קלט אחרים, כמו חבילת האפליקציה ל-Android (APK) של האפליקציה שנבדקת.

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

[
  {
    "crawlStage": "crawl",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "user123",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/username"
          }
        ]
      },
      {
        "eventType": "VIEW_TEXT_CHANGED",
        "replacementText": "12345",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/password"
          }
        ]
      },
      {
        "eventType": "VIEW_CLICKED",
        "elementDescriptors": [
          {
            "resourceId": "my.app.package:id/login"
          }
        ]
      }
    ]
  }
]

אם יש קובץ עם סקריפט Robo יחיד, והתנאי להפעלה שלו הוא app_under_test_shown כברירת מחדל, כמו בדוגמה שלמעלה, אפשר לציין את סקריפט ה-Robo בקובץ באמצעות פורמט פשוט יותר – פשוט רצף של הפעולות שלו:

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "user123",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/username"
      }
    ]
  },
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "12345",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/password"
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/login"
      }
    ]
  }
]

תמיכה ב-iOS+ בסקריפטים של Robo

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

הפעולות הבאות נתמכות ב-iOS ואילך:

  • טענת נכוֹנוּת (assertion)
  • קליק
  • לחיצה ארוכה
  • החלקה
  • התעלמות מכל הרכיבים
  • המתן
  • צילום מסך
  • סיום הסריקה

המאפיינים המזהים הבאים בתיאור הרכיבים נתמכים ב-iOS ואילך:

  • שם הכיתה
  • שם המחלקה של האב
  • תיאור התוכן (וביטוי רגולרי)
  • טקסט (וביטוי רגולרי (regex))

תנאי ההפעלה הבאים בתיאור ההקשר נתמכים ב-iOS ואילך:

  • הצגת האפליקציה שנמצאת בבדיקה
  • האלמנט קיים
  • בוצעה פעולה בסקריפט שאינה של Robo

מבנה

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

מאפיין תיאור
id מספר שלם שעוזר לעקוב אחרי סקריפט ה-Robo הזה בפלט של הסריקה. ל-Robo יש סקריפטים מובנים של Robo עם id משלהם. למרות שאותו id בסקריפטים שונים של Robo לא משפיע על ההתנהגות שלהם, יכול להיות מאתגר להבדיל בין פעולות לבין סקריפטים של Robo בתוצאות הסריקה. מומלץ להקצות id ייחודי של 1000 ומעלה לסקריפטים של Robo כדי למנוע התנגשויות.
description דומה ל-id אבל תיאורי יותר.
crawlStage השלב שבו סקריפט ה-Robo הזה מיושם על ידי Robo של סריקה. כברירת מחדל, זהו שלב הסריקה הראשי.
priority העדיפות של סקריפט ה-Robo הזה בהשוואה לסקריפטים אחרים של Robo. כברירת מחדל, כל הסקריפטים של Robo מקבלים את רמת העדיפות 1.
maxNumberOfRuns קובע כמה פעמים במהלך סריקה Robo יכול להריץ את הסקריפט הזה. כברירת מחדל, Robo יכול להריץ סקריפט של Robo פעם אחת.
contextDescriptor תיאור ההקשר או התנאי שמפעילים את סקריפט ה-Robo הזה. אם השורה הזו לא תופיע, התנאי להפעלה של סקריפט ה-Robo הזה יהיה תמיד מתקיים. במילים אחרות, סקריפט ה-Robo יהיה ללא תנאי.
actions כל הפעולות של סקריפט ה-Robo הזה.

קובץ אחד מכיל אוסף של סקריפט אחד או יותר של Robo.

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

[
  {
    "id": 1000,
    "description": "My first Robo script",
    "actions": [
      {
        "eventType": "DISABLE_KEYBOARD"
      }
    ]
  },
  {
    "id": 1001,
    "description": "My second Robo script",
    "actions": [
      {
        "eventType": "PRESSED_BACK"
      }
    ]
  }
]

תיאור הקשר

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

מאפיין תיאור
"condition": "always" תמיד מפעיל סקריפט של Robo.
"condition": "element_present" הפונקציה בודקת אם במסך מופיע ווידג'ט של ממשק משתמש שתואם ל-elementDescriptors או לטקסט שצוין ב-visionText.
"condition": "element_disabled" הפונקציה בודקת אם ווידג'ט של ממשק משתמש שתואם ל-elementDescriptors נמצא במסך, ואם אי אפשר לבצע איתו אינטראקציה.
"condition": "element_checked" הבדיקה בודקת אם ווידג'ט של ממשק משתמש שתואם ל-elementDescriptors נמצא במסך ומסומן.
"condition": "app_under_test_shown" הבדיקה מוודאת שהאפליקציה שנבדקת פועלת בחזית.
"condition": "default_launcher_shown" הבדיקה נועדה לוודא שמסך הבית של המכשיר מוצג, כלומר שאין אפליקציות שפועלות בחזית המסך.
"condition": "non_roboscript_action_performed" הבדיקה בודקת שהפעולות nonRoboscriptActionCount האחרונות שבוצעו ברצף על ידי בדיקת ה-Robo לא הן פעולות של סקריפט Robo.
negateCondition אם הערך מוגדר כ-true, הוא מבטל את הערך של condition. לדוגמה, אפשר להשתמש במאפיין הזה כדי לבדוק אם ווידג'ט של ממשק משתמש לא נמצא במסך, או שהאפליקציה שנבדקת לא פועלת בחזית.
elementDescriptors תיאור רכיב אחד או יותר שמזהה ווידג'ט של ממשק משתמש במסך. הוא משמש בשילוב עם התנאים element_present,‏ element_disabled ו-element_checked. הערך הזה לא יכול להתקיים בו-זמנית עם הערך visionText. למידע נוסף, ראו תיאורי רכיבים.
visionText הטקסט במסך מזוהה באמצעות ממשק ה-API של זיהוי התווים האופטי (OCR). visionText משמש בשילוב עם התנאי element_present. הערך הזה לא יכול להיות זהה לערך של elementDescriptors.
nonRoboscriptActionCount מספר הפעולות הרצופות בסקריפט שאינן של Robo שבוצעו לפני כן. הוא משמש בשילוב עם התנאי non_roboscript_action_performed כדי להפעיל סקריפט של Robo אחרי כל פעולת Robo מסוג nonRoboscriptActionCount. כברירת מחדל, הערך הוא 1.

דוגמה לסקריפט של Robo שמופעל על ידי ווידג'ט של ממשק משתמש עם מזהה המשאב "my.app.package:id/page_header" שמופיע במסך:

{
  "id": 1000,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/page_header"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Settings"
        }
      ]
    }
  ]
}

לפניכם דוגמה לסקריפט של Robo שמופעל על ידי "Privacy Policy" שזוהה באמצעות זיהוי תווים אופטי (OCR):

{
  "id": 1000,
  "description": "Vision text Robo script",
  "contextDescriptor": {
    "condition": "element_present",
    "visionText": "Privacy Policy"
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "visionText": "Privacy Policy"
    }
  ]
}

דוגמה לסקריפט של Robo שמחכה 5 שניות אחרי כל פעולת Robo שאינה סקריפט:

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "DELAYED_MESSAGE_POSTED",
      "delayTime" : 5000
    }]
}

פעולות

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

מאפיין תיאור
eventType מציין את סוג הפעולה, למשל: לחיצה, עריכת טקסט וכו'. חובה לכל פעולה.
elementDescriptors תיאורים שמזהים ווידג'ט של ממשק משתמש. נדרש לכל הפעולות שיש להן ווידג'ט יעד של ממשק משתמש, כמו לחיצה על לחצן מסוים.
optional אם הערך מוגדר כ-true, הפעולה הזו מושמטת אם אי אפשר לבצע אותה. לדוגמה, הפעולה הזו מועברת אם היא לא מצליחה למצוא את הווידג'ט של ממשק המשתמש היעד במסך, בלי לגרום לכשל בסקריפט של Robo שמכיל אותה. ערך ברירת המחדל הוא false.
replacementText הטקסט להזנה בווידג'ט של ממשק המשתמש היעד. חובה לפעולות לעריכת טקסט.
swipeDirection מציין את כיוון ההחלקה. חובה ביחס לפעולות החלקה.
delayTime מציין את משך ההמתנה, באלפיות שנייה. חובה לפעולות המתנה.
pointTapXCoordinate וגם pointTapYCoordinate הקואורדינטות X ו-Y של הנקודה שנלחצה, בפיסקלים. בלעדי ל-pointTapXPercent ול-pointTapYPercent. חובה ביחס לפעולות של הקשה על נקודה.
pointTapXPercent וגם pointTapYPercent הקואורדינטות X ו-Y באחוזים של הנקודה שנלחצה. בלעדית ל-pointTapXCoordinate ול-pointTapYCoordinate. חובה ביחס לפעולות של הקשה על נקודה.

דוגמה ל-script של Robo עם שתי פעולות ללא ווידג'טים של ממשק משתמש יעד, כלומר הפעולות האלה לא פועלות על ווידג'ט ספציפי של ממשק משתמש:

[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  },
  {
    "eventType": "PRESSED_BACK"
  }
]

מתארי רכיבים

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

מאפיין תיאור
className
ancestorClassName שם המחלקה של האב בהיררכיית ממשק המשתמש של הרכיב. ישות אב היא כל אחד מצמתי ההורה בהיררכיית ממשק המשתמש של הרכיב, כולל הרכיב עצמו.
resourceId
resourceIdRegex ביטוי רגולרי ב-Java שיתאים ל-resourceId.
contentDescription
contentDescriptionRegex ביטוי רגולרי ב-Java שיתאים ל-contentDescription.
text (שמופיע במסך)
textRegex ביטוי רגולרי ב-Java שיתאים ל-text.
groupViewChildPosition,‏ recyclerViewChildPosition או adapterViewChildPosition מייצג את מיקום הצאצא של ווידג'ט בממשק המשתמש, בהתאם לסוג הווידג'ט ההורה שלו.

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

לדוגמה, בדרך כלל אפשר להבדיל בין פריטים ברשימה רק באמצעות מיקומי הצאצאים השונים בתוך הווידג'ט ההורה. כלומר, בדרך כלל לא מספיק להשתמש רק בתיאור רכיב אחד כדי לזהות ווידג'ט של ממשק משתמש. לכן, המאפיין elementDescriptors של פעולה מכיל רצף של מתארי רכיבים שממוינים כך שהראשון תואם לווידג'ט של ממשק המשתמש היעד, השני תואם לווידג'ט ההורה של הווידג'ט של ממשק המשתמש היעד וכן הלאה. המערכת מתאימה את ווידג'ט ממשק המשתמש היעד של הפעולה כשכל מתארי האלמנטים שלו תואמים להיררכיית המשנה של ווידג'ט ממשק המשתמש התואם.

בדוגמה הבאה מוצג סקריפט של Robo עם שינוי טקסט ופעולות לחיצה. בשני המקרים צריך לזהות את ווידג'ט ממשק המשתמש של היעד באמצעות מתארי האלמנטים שסופקו:

[
  {
    "eventType": "VIEW_TEXT_CHANGED",
    "replacementText": "John",
    "elementDescriptors": [
      {
        "className": "android.support.v7.widget.AppCompatEditText",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/first_name"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0
      },
      {
        "className": "android.support.design.widget.TextInputLayout",
        "groupViewChildPosition": 1
      }
    ]
  },
  {
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "className": "android.support.design.widget.FloatingActionButton",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/done"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 1,
        "resourceId": "com.google.samples.apps.topeka:id/content"
      },
      {
        "className": "android.widget.FrameLayout",
        "groupViewChildPosition": 0,
        "resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
      }
    ]
  }
]

אפשרויות ביצוע

אפשר להוסיף קידומת לרשימת הפעולות בסקריפט Robo באמצעות אובייקט JSON שמציין את אפשרויות הביצוע של סקריפט ה-Robo. כותרת התצורה הזו מתחילה במילות המפתח roboscript, ואחריה ייצוג JSON של אפשרויות הביצוע הרצויות.

סקריפטים של Robo תומכים באפשרויות ההפעלה הבאות:

  • executionMode – אפשרויות ביצוע שחלות כשסקריפט Robo פועל:
    • strict – אם הערך מוגדר כ-true, סקריפט ה-Robo לא משתמש בהתאמה חלקית, דילוג על הפעולה הנוכחית והשעיה. כלומר, סקריפט ה-Robo מופעל כבדיקה רגילה של כלי המדידה, והוא נכשל ברגע שלא ניתן לבצע אחת מהפעולות שלו. כברירת מחדל, הערך הוא false.
    • dismiss_popups – אם ההגדרה היא true, בדיקת Robo תסגור תיבת דו-שיח בלתי צפויה במהלך ביצוע סקריפט ה-Robo, גם במצב strict. לאפשרות הזו אין השפעה כשלא נמצאים במצב strict. כברירת מחדל, הערך הוא false.
    • notify – אם הערך מוגדר כ-false, לא יוצגו התראות במסך של סקריפט ה-Robo בתחילת הביצוע ובסופו. כברירת מחדל, הערך הוא true.
  • postscript – אפשרויות ביצוע שחלות אחרי השלמת סקריפט Robo:
    • terminate – אם הערך מוגדר כ-true, בדיקת Robo תפסיק לסרוק אחרי שהסקריפט של Robo יושלם. כברירת מחדל, הערך הוא false.

דוגמה ל-script של Robo שמופעל במצב strict בלי התראות במסך, וממתין שלוש שניות ואז הסריקה נעצרת:

"roboscript": {
  "executionMode": {
    "strict": true,
    "notify": false
  },
  "postscript": {
    "terminate": true
  }
}
[
  {
    "eventType": "DELAYED_MESSAGE_POSTED",
    "delayTime": 3000
  }
]

פרמטרים של תבניות

פרמטר תבנית הוא placeholder בסקריפט של Robo שמוחליף את הערך בפועל כשבדיקת Robo טוענת את סקריפט ה-Robo הזה להרצה. הפרמטרים של התבנית מתחילים בקו תחתון כפול ואחריו סימן אחוז, ומסתיימים בסימן אחוז ואחריו קו תחתון כפול.

סקריפטים של Robo תומכים בפרמטרים הבאים של תבניות:

  • __%APP_PACKAGE_NAME%__ – שם החבילה של האפליקציה שנבדקת.

דוגמה לסקריפט של Robo שגורם להפסקת התהליך של האפליקציה שנבדקת:

[
  {
    "eventType": "ADB_SHELL_COMMAND",
    "command": "am force-stop __%APP_PACKAGE_NAME%__"
  }
]

תגובות

סקריפט של Robo יכול להכיל שורות תגובה, שהן שורות שמתחילות ב-# או ב-//.

דוגמה לסקריפט של Robo עם כמה הערות:

# Confirm a user account.
[
  {
    // Click the DONE button.
    "eventType": "VIEW_CLICKED",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
]

יכולות

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

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

אם ההתאמה החלקית תצליח, הפעולה המתאימה בסקריפט של Robo תושלם כרגיל. השיטה הזו תומכת בתרחישים שבהם מבנה האפליקציה משתנה, למשל בין גרסאות של האפליקציה, כשרכיבי המסך מסודרים מחדש.

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

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

השעיה אם לא ניתן להתאים את הפעולות הנוכחיות או הפעולות הבאות של סקריפט Robo באופן מלא או חלקי, סקריפט Robo יושעה באופן זמני ובדיקה של Robo תבחר פעולה לביצוע באמצעות השיטות האחרות שלה. אחרי שהפעולה הזו תושלם, בדיקת ה-Robo תמשיך את ביצוע הסקריפט של Robo.

הסקריפט של Robo יישאר מושעה כל עוד לא ניתן להתאים את הפעולות הנוכחיות או הפעולות הבאות בסקריפט של Robo. לכן, סקריפטים של Robo לא חייבים להיות פתיח לבדיקת Robo, ואפשר לשלב פעולות של סקריפט Robo עם פעולות רגילות של בדיקת Robo. הטכניקה הזו תומכת בתרחישים שבהם התנהגות האפליקציה לא יציבה, או כשהשינויים בין גרסאות האפליקציה גדולים מספיק כדי שבדיקה של Robo תצטרך "למלא את הפערים" באמצעות הפעולות הסטנדרטיות שלה.

עדיפויות

אם סקריפט של Robo מגיע ל-maxNumberOfRuns שלו, אי אפשר להפעיל אותו יותר בסריקה מסוימת. אם יש יותר מסקריפט Robo אחד שאפשר להפעיל לפי ההקשר הנוכחי, המערכת נותנת עדיפות לסקריפט Robo שמתאים לפי הסדר הבא:

  1. יש לו מאפיין contextDescriptor.
  2. יש לו את הערך הגבוה ביותר של priority (כברירת מחדל, לכל הסקריפטים של Robo יש את אותו priority של 1).
  3. מופיע מוקדם ככל האפשר ברשימה של סקריפטים של Robo, אם העדיפויות של סקריפטים של Robo זהות.

בדוגמה הבאה מוצג קובץ עם שלושה סקריפטים של Robo שמבצעים את אותה פעולה ומופעל עליהם אותו תנאי – האפליקציה שנבדקת נמצאת בחזית:

[
  {
    "id": 1000,
    "description": "Robo script 1",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  }
]

כשהאפליקציה שנבדקת נמצאת בחזית, Robo מפעיל את הפעולות הבאות, לפי הסדר:

  1. "Robo script 2" כי יש לו את העדיפות הגבוהה ביותר.
  2. "Robo script 1" כי הוא מופיע מוקדם יותר בין שאר סקריפטים רלוונטיים של Robo עם אותה עדיפות.
  3. "Robo script 3" כסקריפט האחרון הרלוונטי של Robo.

הפעלות חוזרות

כברירת מחדל, Robo מפעיל סקריפט של Robo לכל היותר פעם אחת במהלך סריקה. אפשר לשנות את זה באמצעות המאפיין maxNumberOfRuns.

דוגמה לסקריפט של Robo שמעביר את האפליקציה שנבדקת לרקע עד 10 פעמים:

{
  "id": 1000,
  "maxNumberOfRuns": 10,
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  },
  "actions": [
    {
      "eventType": "GO_HOME"
    }
  ]
}

שלב הסריקה

אפשר להשתמש בסקריפטים של Robo בשלבים שונים של סריקה נתונה של Robo:

שלב הסריקה תיאור
pre_crawl לפני ש-Robo מופעל ומתחיל לסרוק את האפליקציה שנבדקת.
post_crawl אחרי ש-Robo מסיים לסרוק את האפליקציה שנבדקת. משך הסקריפט של post_crawl לא יכול לחרוג מ-15 שניות, אחרת הסריקה עלולה להסתיים עקב זמן קצוב לתפוגה.
crawl שלב הסריקה הראשי, שבו Robo סורק את האפליקציה שנבדקת.
close_screen כש-Robo מנסה לחזור אחורה (backtrack) ממסך נתון, אחרי שכל הפעולות האפשריות במסך הזה נבדקות. כברירת מחדל, Robo presses back, וזה לא רצוי בתרחישים מסוימים.

אם לא צוין המאפיין crawlStage בסקריפט של Robo, ההנחה היא שהוא crawl.

לפניכם דוגמה לסקריפט של Robo שמנקה את נתוני המשתמשים באפליקציה שנבדקת לפני ש-Robo מתחיל לסרוק אותה:

{
  "id": 1000,
  "crawlStage": "pre_crawl",
  "actions": [
    {
      "eventType": "ADB_SHELL_COMMAND",
      "command": "pm clear __%APP_PACKAGE_NAME%__"
    }
  ]
}

דוגמה לסקריפט של Robo שמורה ל-Robo ללחוץ על "Cancel" בכל פעם שהוא מנסה לחזור אחורה (backtrack) מתיבת דו-שיח לאישור:

{
  "id": 1000,
  "crawlStage": "close_screen",
  "maxNumberOfRuns": 999,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/confirmation_dialog"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Cancel"
        }
      ]
    }
  ]
}

פעולות מותנות

סקריפט של Robo יכול להכיל פעולות מותנות. לפעולות מותנות יש שלושה מאפיינים נוספים שמתארים את האופן שבו Robo מבצע אותן:

מאפיין תיאור
priority העדיפות של הפעולה המותנית הזו בהשוואה לפעולות מותנות אחרות בסקריפט Robo שמכיל אותה. כברירת מחדל, לכל הפעולות המותנות יש עדיפות 1.
maxNumberOfRuns מספר הפעמים שבהן ניתן לבצע את הפעולה המותנית הזו במהלך הרצה אחת של סקריפט ה-Robo שמכיל אותה. כברירת מחדל, אפשר לבצע את כל הפעולות המותנות לכל היותר פעם אחת בהפעלה אחת של סקריפט ה-Robo שמכיל אותן.
contextDescriptor ההקשר או התנאי שמפעילים את הפעולה המותנית הזו. יש לו את אותו המבנה והוא מציע יכולות דומות לפונקציית contextDescriptor של סקריפט ה-Robo.

כשסקריפט של Robo מופעל, הוא מבצע את הפעולות הלא מותנות שלו אחת אחרי השנייה לפי סדר ההופעה. אם סקריפט של Robo מכיל פעולות מותנות, המערכת מביאה אותן בחשבון בכל פעם לפני שבוחרת פעולה לא מותנית לביצוע. אם פעולה מותנית מופעלת ונבחרת על סמך העדיפות שלה ומספר ההפעלות שנותרו, סקריפט Robo מבצע את הפעולה המותנית הזו. אחרת, סקריפט ה-Robo מבצע את הפעולה הבאה ללא תנאי. כדי שסקריפט של Robo יהיה תקף, הוא צריך לכלול לפחות פעולה אחת ללא תנאי.

בדוגמה הבאה מוצג סקריפט Robo ללא תנאי עם פעולה מותנית שסוגרת תיבת דו-שיח קופצת אם היא מופיעה בשלב כלשהו במהלך ביצוע הסקריפט:

{
  "id": 1000,
  "actions": [
    {
      "description": "Dismiss popup",
      "maxNumberOfRuns": 100,
      "contextDescriptor": {
        "condition": "default_launcher_shown",
        "negateCondition": true
      },
      "eventType": "GO_HOME"
    },
    {
      "description": "Screen off",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 26"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    }
}

התעלמות מפעולות

סקריפט של Robo יכול להכיל הוראות ל-Robo להתעלם מווידג'טים ספציפיים בממשק המשתמש או מכל הווידג'טים בממשק המשתמש במסך מסוים. ההנחיות האלה מיוצגות כביטול ההתייחסות ל'פעולות' עם eventType ELEMENT_IGNORED ו-ALL_ELEMENTS_IGNORED בהתאמה.

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

סקריפט של Robo יכול להכיל שילוב של פעולות של התעלמות, פעולות מותנות ופעולות לא מותנות. בניגוד לפעולות אחרות בסקריפט של Robo, פעולות של התעלמות חלות כל עוד הערך של המאפיין contextDescriptor בסקריפט של Robo שמכיל אותן תואם למסך במהלך סריקה של Robo, ללא קשר לערכים של המאפיינים priority ו-maxNumberOfRuns.

דוגמה לקובץ עם שני סקריפטים של Robo: סקריפט ה-Robo הראשון גורם ל-Robo להתעלם מכל ווידג'טים של ממשק משתמש במסך שמכיל ווידג'ט של ממשק משתמש עם מזהה המשאב "my.app.package:id/ignored_screen". הסקריפט השני של Robo גורם ל-Robo להתעלם מווידג'טים של ממשק משתמש שמזהי המשאבים שלהם תואמים לביטוי הרגולרי של Java‏ ".*:id/done" במסך שמכיל ווידג'ט של ממשק משתמש עם מזהה משאב "my.app.package:id/main_screen":

[
  {
    "id": 1000,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/ignored_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ALL_ELEMENTS_IGNORED"
      }
    ]
  },
  {
    "id": 1001,
    "contextDescriptor": {
      "condition": "element_present",
      "elementDescriptors": [
        {
          "resourceId": "my.app.package:id/main_screen"
        }
      ]
    },
    "actions": [
      {
        "eventType": "ELEMENT_IGNORED",
        "elementDescriptors": [
          {
            "resourceIdRegex": ".*:id/done"
          }
        ]
      }
    ]
  }
]

תמיכה ב-RecyclerView וב-AdapterView

הצאצאים של ווידג'טים מסוג RecyclerView ו-AdapterView נטענים באופן דינמי, ויכול להיות שהם יוצגו אחרי כמה החלקות מהמסך הנוכחי. מכיוון שגודל המסך ומספר החלקות הנדרשות כדי להגיע לצאצא הזה משתנים בהתאם לגורמים שונים של פורמט המכשיר, מומלץ להסתמך על מיקום הנתונים של הצאצא, שהוא מיקום מוחלט. גישה פחות חזקה היא להסתמך על מספר החלקות שנדרשות כדי להציג את הצאצא הזה במסך, ואז להשתמש במיקום שלו במסך.

לכן, סקריפט Robo מתעד את מיקומי הנתונים המוחלטים של הצאצאים של RecyclerView, שהם מטרות של פעולות של סקריפט Robo, בתור recyclerViewChildPosition. סקריפט Robo גם מתעד את המיקומים המוחלטים של צאצאי AdapterView שהם מטרות של פעולות של סקריפט Robo בתור adapterViewChildPosition.

הפעולות על הצאצאים של RecyclerView ו-AdapterView מתבצעות לפי השלבים הבאים:

  1. בדיקת Robo מבטיחה שהצאצא התואם יוצג במסך באמצעות פעולת מיקום ב-RecyclerView או ב-AdapterView שמכיל אותו.

  2. בדיקת ה-Robo מבצעת את הפעולה שתועדה ישירות ברכיב הצאצא, כי הוא כבר מוצג במסך.

דוגמה לפעולה של קליק על צאצא של AdapterView‏ (android.widget.GridView):

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "com.google.samples.apps.topeka.widget.AvatarView",
      "adapterViewChildPosition": 5,
      "resourceId": "com.google.samples.apps.topeka:id/avatar",
      "contentDescription": "Avatar 6"
    },
    {
      "className": "android.widget.GridView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/avatars"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 1
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

הדוגמה הבאה היא פעולת לחיצה על צאצא של RecyclerView‏ (android.support.v7.widget.RecyclerView):

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "className": "android.support.v7.widget.AppCompatTextView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_title"
    },
    {
      "className": "android.widget.FrameLayout",
      "recyclerViewChildPosition": 8,
      "resourceId": "com.google.samples.apps.topeka:id/category_item"
    },
    {
      "className": "android.support.v7.widget.RecyclerView",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/categories"
    },
    {
      "className": "android.widget.FrameLayout",
      "groupViewChildPosition": 1,
      "resourceId": "com.google.samples.apps.topeka:id/category_container"
    },
    {
      "className": "android.widget.LinearLayout",
      "groupViewChildPosition": 0
    }
  ]
}

איך מקליטים סקריפט Robo ב-Android Studio ומריצים אותו ב-Test Lab

אפשר ליצור סקריפט Robo ב-Android Studio, שמציל את הסקריפט כקובץ JSON. לאחר מכן אפשר להעלות את קובץ ה-JSON לאפליקציה ב-Firebase Test Lab ולהריץ את הבדיקה בהתאם.

כשמריצים בדיקת Robo עם סקריפט מצורף, הבדיקה מבצעת קודם את הפעולות שנקבעו מראש בסקריפט ואז בודקת את האפליקציה כרגיל.

כדי ליצור קובץ JSON של סקריפט Robo ב-Android Studio, פועלים לפי השלבים המפורטים במאמר הקלטה של סקריפט Robo באמצעות Test Lab ב-Android Studio.

פעולות של סקריפטים של Robo

המאפיין האופציונלי הנפוץ הבא חל על כל הפעולות:

  • description – עוזרת לעקוב אחרי ביצוע הפעולה הזו של סקריפט Robo בפלט של בדיקות Robo.

טענת נכוֹנוּת (assertion)

אם התנאי של ההצהרה נכון, סקריפט ה-Robo ממשיך לפעולה הבאה, שיכולה להיות הצהרה אחרת. אחרת, הפעלת הסקריפט של Robo תופסק בגלל טענת נכוֹנוּת (assertion) שנכשלה.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ASSERTION" --
contextDescriptor תיאור של ההקשר או התנאי שהוגדרו. יש לו את אותו מבנה והוא מציע יכולות דומות לפונקציית contextDescriptor של סקריפט ה-Robo.

הדוגמה הבאה היא טענת נכוֹנוּת (assertion) של סקריפט Robo, שבה בודקים שהאפליקציה שנבדקת נמצאת בחזית:

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "app_under_test_shown"
  }
}

הדוגמה הבאה היא טענת נכוֹנוּת (assertion) בסקריפט של Robo, שבודקת שווידג'ט של ממשק משתמש עם מזהה המשאב "com.google.samples.apps.topeka:id/done" נמצא במסך:

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "com.google.samples.apps.topeka:id/done"
      }
    ]
  }
}

זוהי דוגמה לאימרה (assertion) בסקריפט של Robo, שבה בודקים שלא זוהה "Settings" במסך באמצעות OCR:

{
  "eventType": "ASSERTION",
  "contextDescriptor": {
    "condition": "element_present",
    "negateCondition": true,
    "visionText": "Settings"
  }
}

קליק

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
eventType מציין את סוג הפעולה של סקריפט Robo.
"eventType": "VIEW_CLICKED" לוחצים על אלמנט היעד של האפליקציה שנבדקת.
"eventType": "SOFT_KEYBOARD_CLICK" לחיצה על אלמנט היעד של המקלדת הווירטואלית.
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" לוחץ על אלמנטים אקראיים במקלדת הווירטואלית עד maxNumberOfRuns פעמים.
"eventType": "LIST_ITEM_CLICKED" משמש את מכשיר ההקלטה של סקריפט Robo ב-Android Studio כדי ללחוץ על פריטים ברשימה.
elementDescriptors מזהה את ווידג'ט ממשק המשתמש שנלחץ עליו באמצעות היררכיית ממשק המשתמש של Android. הערך הזה לא יכול להתקיים בו-זמנית עם הערך visionText.
visionText זיהוי האלמנט שנלחץ עליו באמצעות OCR. הערך הזה לא יכול להיות זהה לערך של elementDescriptors.
matchIndex מציין את האינדקס של המופע של אלמנט היעד שתואם, כשאלמנט היעד מזוהה באמצעות visionText. אם הערך הוא 0, פעולת הסקריפט של Robo בוחרת את הרכיב הראשון שתואם, אם הערך הוא 1, פעולת הסקריפט של Robo בוחרת את הרכיב השני שתואם, וכן הלאה. הסדר נקבע משמאל לימין, מלמעלה למטה. ערך ברירת המחדל הוא 0 (התאמה ראשונה נבחרת).
maxNumberOfRuns קובע כמה פעמים ללחוץ על רכיב אקראי במקלדת הרכה, כש-eventType הוא SOFT_KEYBOARD_RANDOM_CLICK. ערך ברירת המחדל הוא 1.

בדוגמה הבאה מוצגת פעולה של סקריפט Robo שלוחצת על לחצן עם מזהה המשאב "com.google.samples.apps.topeka:id/done":

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

דוגמה לפעולה של סקריפט Robo שמבצעת קליק על המופע השני של המילה "Search" שזוהתה במסך באמצעות OCR:

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Search",
  "matchIndex": 1
}

דוגמה לפעולה בסקריפט של Robo שלוחצת על אלמנט של מקלדת וירטואלית עם תיאור תוכן "Emoji button":

{
  "eventType": "SOFT_KEYBOARD_CLICK",
  "elementDescriptors": [
    {
      "contentDescription": "Emoji button"
    }
  ]
}

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

{
  "eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
  "maxNumberOfRuns": 5
}

השבתת המקלדת הווירטואלית

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "DISABLE_KEYBOARD" --

דוגמה לפעולה בסקריפט של Robo להשבתת המקלדת הווירטואלית:

{
  "eventType": "DISABLE_KEYBOARD"
}

הרצת פקודת adb shell

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ADB_SHELL_COMMAND" --
command פקודת המעטפת של Android Debug Bridge‏ (adb) שרוצים להריץ.

המאפיין הבא הוא אופציונלי:

  • expectedOutputRegex – הפלט הצפוי של הפקודה כביטוי רגולרי של Java. אם הפלט לא תואם, הפעולה של סקריפט ה-Robo תיכשל. כברירת מחדל, זו מחרוזת ריקה, כלומר הפלט לא נבדק.

בדוגמה הבאה מוצגת פעולה של סקריפט Robo שמנקה את נתוני המשתמשים באפליקציה שנבדקת:

{
  "eventType": "ADB_SHELL_COMMAND",
  "command": "pm clear __%APP_PACKAGE_NAME%__"
}

מתן הרשאות

הפעולה הזו מתועדת על ידי מכשיר ההקלטה של סקריפט Robo ב-Android Studio, כדי לשמור על תאימות לאחור עם Espresso Test Recorder. בדיקת Robo מעניקה את כל ההרשאות לאפליקציה שנבדקת בתחילת כל סריקה, ולכן הפעולה הזו היא פעולה ללא תוצאה. אל תשתמשו בפעולה הזו בסקריפטים של Robo.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "PERMISSIONS_REQUEST" --

התעלמות מכל הרכיבים במסך

הפעולה הזו גורמת ל-Robo להתעלם מכל הרכיבים בכל מסך שמפעיל את סקריפט ה-Robo שמכיל אותו.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ALL_ELEMENTS_IGNORED" --

דוגמה לפעולה בסקריפט של Robo שגורמת ל-Robo להתעלם מכל הרכיבים במסך:

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

התעלמות מרכיב

הפעולה הזו גורמת ל-Robo להתעלם מאלמנט (או מאלמנטים) שתואמים ל-elementDescriptors שצוין.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ELEMENT_IGNORED" --
elementDescriptors מזהה את רכיבי הווידג'ט של ממשק המשתמש שנדחו באמצעות היררכיית ממשק המשתמש של Android.

המאפיין הבא הוא אופציונלי:

  • ignoreChildren – אם הערך מוגדר כ-true, Robo מתעלם גם מכל הצאצאים של הווידג'טים של ממשק המשתמש שנדחו. כברירת מחדל, הערך הוא false.

בדוגמה הבאה מוצגת פעולה של סקריפט Robo שמאפשרת ל-Robo להתעלם מכל הרכיבים שהתיאורים של התוכן שלהם מתחילים ב-"Avatar":

{
  "eventType": "ELEMENT_IGNORED",
  "elementDescriptors": [
    {
      "contentDescriptionRegex": "Avatar.*"
    }
  ]
}

טקסט קלט

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
eventType מציין את סוג הפעולה של סקריפט Robo.
"eventType": "VIEW_TEXT_CHANGED" מזין את הטקסט הנתון בווידג'ט של ממשק המשתמש היעד.
"eventType": "ENTER_TEXT" מזין את הטקסט הנתון בווידג'ט של ממשק המשתמש היעד, ולאחר מכן שולח אירוע KEYCODE_ENTER לווידג'ט של ממשק המשתמש הזה.
elementDescriptors מזהה את ווידג'ט ממשק המשתמש היעד באמצעות היררכיית ממשק המשתמש של Android.
replacementText הטקסט להזנה בווידג'ט של ממשק המשתמש היעד.

בדוגמה הבאה מוצגת פעולה של סקריפט Robo שמזינה את הערך "John" בווידג'ט של ממשק משתמש עם מזהה המשאב "com.google.samples.apps.topeka:id/first_name":

{
  "eventType": "VIEW_TEXT_CHANGED",
  "replacementText": "John",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

לחיצה ארוכה

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors מזהה את ווידג'ט ממשק המשתמש היעד באמצעות היררכיית ממשק המשתמש של Android. בלעדיים זה לזה עם visionText.
visionText זיהוי האלמנט שעליו לחצתם לחיצה ארוכה באמצעות OCR. הערך הזה לא יכול להיות זהה לערך של elementDescriptors.
matchIndex מציין את האינדקס של המופע של אלמנט היעד שתואם, כשאלמנט היעד מזוהה באמצעות visionText. אם הערך הוא 0, פעולת הסקריפט של Robo בוחרת את הרכיב הראשון שתואם, אם הערך הוא 1, פעולת הסקריפט של Robo בוחרת את הרכיב השני שתואם, וכן הלאה. הסדר נקבע משמאל לימין, מלמעלה למטה. ערך ברירת המחדל הוא 0 (התאמה ראשונה נבחרת).

המאפיין הבא הוא אופציונלי:

  • delayTime – קובעת את משך הלחיצה למטה של לחיצה ארוכה, באלפיות שנייה.

דוגמה לפעולה בסקריפט של Robo שמבצעת קליק של חמש שניות על ווידג'ט של ממשק משתמש עם תיאור התוכן "Avatar 8":

{
  "eventType": "VIEW_LONG_CLICKED",
  "elementDescriptors": [
    {
      "contentDescription": "Avatar 8"
    }
  ],
  "delayTime": 5000
}

ביצוע תנועה עם נקודה אחת

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ONE_POINT_GESTURE" --
coordinates שתי קואורדינטות לתנועה בנקודה אחת, בפורמט "(x1,y1)->(x2,y2)" כאחוזים או בפיקסלים.

המאפיין הבא הוא אופציונלי:

  • dragAndDrop – אם מגדירים את הערך true, תנועה עם אצבע אחת מבצעת פעולת גרירה ושחרור. כברירת מחדל, הערך הוא false.

הדוגמה הבאה היא פעולת מחווה של נקודה אחת בסקריפט של Robo שמבצעת החלקה למטה:

{
  "eventType": "ONE_POINT_GESTURE",
  "coordinates": "(50%,25%)->(50%,75%)"
}

מבצעים תנועה עם שתי אצבעות.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "TWO_POINT_GESTURE" --
coordinates ארבע קואורדינטות של מחווה של שתי נקודות, בפורמט "‎(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" כאחוזים או בפיקסלים.

דוגמה לפעולה בסקריפט של Robo שמבצעת תנועת צביטה החוצה:

{
  "eventType": "TWO_POINT_GESTURE",
  "coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}

ביצוע פעולת IME

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

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors מזהה את ווידג'ט ממשק המשתמש של היעד באמצעות היררכיית ממשק המשתמש של Android.

בדוגמה הבאה מוצגת פעולה של סקריפט Robo שמבצעת פעולת IME בווידג'ט של ממשק משתמש עם מזהה המשאב "com.google.samples.apps.topeka:id/first_name":

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

מקישים על 'חזרה'

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
eventType מציין את סוג הפעולה של סקריפט Robo.
"eventType": "PRESSED_BACK" שליחת אירוע KEYCODE_BACK למכשיר.
"eventType": "PRESSED_BACK_EMULATOR_28" משמש את מכשיר ההקלטה של סקריפטים של Robo ב-Android Studio כדי ללחוץ על 'הקודם' במהדמרים API 28.

דוגמה לפעולה של סקריפט Robo שמפעילה לחיצה על 'הקודם':

{
  "eventType": "PRESSED_BACK"
}

מקישים על 'דף הבית'.

הפעולה הזו שולחת אירוע KEYCODE_HOME למכשיר.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "GO_HOME" --

דוגמה לפעולה בסקריפט של Robo שמפעילה לחיצה על לחצן הבית:

{
  "eventType": "GO_HOME"
}

גלילה של רכיב עד שהוא גלוי לעין

הפעולה הזו גורמת ל-Robotest לגלול קדימה את הווידג'ט של ממשק המשתמש שתואם ל-elementDescriptors שצוין, עד שהווידג'ט של ממשק המשתמש שתואם ל-childElementDescriptors שצוין יופיע במסך, או עד שלא ניתן יהיה יותר לגלול את הווידג'ט, או עד שמגיעים למספר המקסימלי של 50 גלילות.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors מזהה את ווידג'ט ממשק המשתמש שגלול באמצעות היררכיית ממשק המשתמש של Android.
childElementDescriptors מזהה את ווידג'ט ממשק המשתמש שרוצים לגלול אליו באמצעות היררכיית ממשק המשתמש של Android.

הדוגמה הבאה היא פעולה של סקריפט Robo שמגלגלת את ווידג'ט ממשק המשתמש עם מזהה המשאב "my.app.package:id/scrollable_card_container" עד שווידג'ט ממשק המשתמש עם הטקסט "Orange" מופיע במסך (או עד שלא ניתן לבצע יותר גלישות או שמגיעים למספר המקסימלי של 50 גלישות):

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

החלקה

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "VIEW_SWIPED" --
swipeDirection מציין את כיוון ההחלקה:
  • Left
  • Right
  • Up
  • Down
  • Forward – הערך יכול להיות Down או Right, בהתאם לאפשרות הגלילה האנכית או האופקית של הווידג'ט של ממשק המשתמש היעד.
  • Backward – הערך Up או Left, בהתאם לאפשרות הגלילה האנכית או האופקית של הווידג'ט של ממשק המשתמש היעד.
elementDescriptors מזהה את ווידג'ט ממשק המשתמש של היעד באמצעות היררכיית ממשק המשתמש של Android.

דוגמה לפעולה בסקריפט של Robo שגורמת להחלקה למעלה של ווידג'ט בממשק המשתמש עם מזהה המשאב "my.app.package:id/custom_content":

{
  "eventType": "VIEW_SWIPED",
  "swipeDirection": "Up",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/custom_content"
    }
  ]
}

צילום מסך

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "TAKE_SCREENSHOT" --
screenshotName מציין את שם הקובץ של צילום המסך.

דוגמה לפעולה של סקריפט Robo שצילום מסך:

{
  "eventType": "TAKE_SCREENSHOT",
  "screenshotName": "my_screenshot"
}

מקישים על נקודה במסך

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "POINT_TAP" --
pointTapXCoordinate קואורדינטת ה-X של הנקודה שנלחצה בפיקסלים. הערך הזה לא יכול להיות בו-זמנית עם הערכים pointTapXPercent ו-pointTapYPercent.
pointTapYCoordinate קואורדינטת ה-Y בפיקסלים של הנקודה שנלחצה. הערך הזה לא יכול להיות בו-זמנית עם הערכים pointTapXPercent ו-pointTapYPercent.
pointTapXPercent קואורדינטת ה-X באחוזים של הנקודה שנלחצה. הערך הזה לא יכול להיות בו-זמנית עם הערכים pointTapXCoordinate ו-pointTapYCoordinate.
pointTapYPercent קואורדינטת ה-Y באחוזים של הנקודה שנלחצה. הערך הזה לא יכול להיות בו-זמנית עם הערכים pointTapXCoordinate ו-pointTapYCoordinate.

דוגמה לפעולה בסקריפט של Robo שמבצעת הקשה באמצע המסך:

{
  "eventType": "POINT_TAP",
  "pointTapXPercent": 50,
  "pointTapYPercent": 50
}

מקישים על נקודה בתוך רכיב

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent אחוז קואורדינטת X בתוך אלמנט היעד.
pointTapYPercent קואורדינטת ה-Y באחוזים בתוך אלמנט היעד.
elementDescriptors מזהה את ווידג'ט ממשק המשתמש של היעד באמצעות היררכיית ממשק המשתמש של Android.

דוגמה לפעולה בסקריפט של Robo שמזיזה את פס ההזזה של סרגל החיפוש ימינה:

{
  "eventType": "POINT_TAP_ELEMENT",
  "pointTapXPercent": 80,
  "pointTapYPercent": 50,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/my_seekbar"
    }
  ]
}

סיום הסריקה

הפעולה הזו תפסיק את בדיקת ה-Robo.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "TERMINATE_CRAWL" --

דוגמה לפעולה של סקריפט Robo שגורמת להפסקה של בדיקת Robo:

{
  "eventType": "TERMINATE_CRAWL"
}

המתן

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime מציין את משך ההמתנה, באלפיות שנייה.

דוגמה לפעולה בסקריפט של Robo שממתינה שלוש שניות:

{
  "eventType": "DELAYED_MESSAGE_POSTED",
  "delayTime": 3000
}

המתנה לרכיב

הפעולה הזו גורמת ל-Robo Test להמתין עד שרכיב יופיע במסך, עד לתפוגת הזמן שצוינה.

בטבלה הבאה מפורטים המאפיינים הנדרשים:

מאפיין תיאור
"eventType": "WAIT_FOR_ELEMENT" --
delayTime מציין את הזמן הקצוב לתפוגה של ההמתנה, באלפיות שנייה.
elementDescriptors מזהה את ווידג'ט ממשק המשתמש שעליו ממתינים באמצעות היררכיית ממשק המשתמש של Android.

בדוגמה הבאה מוצגת פעולה בסקריפט של Robo שמחכה עד 30 שניות עד שווידג'ט של ממשק משתמש עם מזהה המשאב "my.app.package:id/confirmation_button" יופיע במסך:

{
  "eventType": "WAIT_FOR_ELEMENT",
  "delayTime": 30000,
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/confirmation_button"
    }
  ]
}

השלבים הבאים