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

במסמך הזה מפורט מידע על סקריפטים של 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+:

  • הצהרת בעלות
  • קליק
  • לחיצה ארוכה
  • החלקה
  • התעלמות מכל הרכיבים
  • המתן
  • צילום מסך
  • סיום הסריקה

המאפיינים המזהים הבאים בתיאור הרכיבים נתמכים ב-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 אחרי כל פעולה של nonRoboscriptActionCount ב-Robo. כברירת מחדל, הערך הוא 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.

הדוגמה הבאה היא לסקריפט 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 שמנקה את נתוני המשתמש של האפליקציה בבדיקה לפני שהיא מתחילה לסרוק אותם:

{
  "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 עם סקריפט מצורף, 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

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

מאפיין תיאור
"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"
    }
  ]
}

השלבים הבאים