คู่มืออ้างอิงสคริปต์ Robo

เอกสารนี้มีข้อมูลอ้างอิงเกี่ยวกับสคริปต์ Robo ซึ่งรวมถึงโครงสร้าง ความสามารถ การใช้งาน การบันทึก และการดำเนินการ สคริปต์ Robo คือการทดสอบที่ทำงานด้านการรับประกันคุณภาพด้วยตนเอง (QA) สำหรับแอปบนอุปกรณ์เคลื่อนที่โดยอัตโนมัติ และเปิดใช้การผสานรวมอย่างต่อเนื่อง (CI) และกลยุทธ์การทดสอบก่อนการเปิดตัว สคริปต์ Robo เป็นไฟล์ JSON ที่อธิบายลำดับของอินเทอร์เฟซผู้ใช้ (UI) และการทำงานอื่นๆ

คุณสามารถสร้างสคริปต์ Robo ด้วยวิธีต่อไปนี้

  • ใช้ฟีเจอร์การบันทึกสคริปต์ Robo (Android เท่านั้น)

  • สร้างสคริปต์ Robo ด้วยตนเอง (Android และ iOS+)

  • บันทึกสคริปต์ Robo แล้วแก้ไขด้วยตนเอง (Android เท่านั้น)

ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้สคริปต์ Robo ได้ที่เรียกใช้สคริปต์ Robo

บทนำ

สคริปต์ Robo มีไว้สำหรับการทดสอบ Robo ควบคู่ไปกับอินพุตอื่นๆ เช่น Android Application Package (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"
      }
    ]
  }
]

รองรับสคริปต์ Robo บน iOS+

Robo สำหรับ iOS+ (เบต้า) มีการรองรับแบบจำกัดสำหรับสคริปต์ Robo ไวยากรณ์สคริปต์ Robo สำหรับ iOS+ เหมือนกับไวยากรณ์ของ Android และฟีเจอร์ที่รองรับใน iOS+ จะทำงานคล้ายกับเวอร์ชันเก่าของ Android

การดำเนินการต่อไปนี้ได้รับการสนับสนุนใน iOS+:

  • การยืนยัน
  • คลิก
  • คลิกค้าง
  • การปัดหน้าจอ
  • ละเว้นองค์ประกอบทั้งหมด
  • รอ
  • ถ่ายภาพหน้าจอ
  • สิ้นสุดการรวบรวมข้อมูล

แอตทริบิวต์การระบุต่อไปนี้ในข้อบ่งชี้องค์ประกอบได้รับการสนับสนุนใน iOS+

  • ชื่อชั้นเรียน
  • ชื่อคลาสระดับบน
  • คำอธิบายเนื้อหา (และนิพจน์ทั่วไป)
  • ข้อความ (และนิพจน์ทั่วไป)

เงื่อนไขทริกเกอร์ในข้อบ่งชี้บริบทต่อไปนี้รองรับใน iOS+

  • แสดงแอปที่อยู่ภายใต้การทดสอบ
  • มีองค์ประกอบอยู่
  • ดำเนินการสคริปต์ที่ไม่ใช่ Robo

โครงสร้าง

สคริปต์ Robo มีแอตทริบิวต์หลายรายการที่อธิบายวิธีการเรียกใช้ Robo แอตทริบิวต์เหล่านี้ส่วนใหญ่ไม่บังคับพร้อมค่าเริ่มต้นที่กำหนดไว้ล่วงหน้า

แอตทริบิวต์ คำอธิบาย
id เลขจำนวนเต็มที่ช่วยติดตามสคริปต์ Robo นี้ในเอาต์พุตการรวบรวมข้อมูล Robo มีสคริปต์ Robo ในตัวพร้อม id ของตนเอง แม้ว่า id เดียวกันในสคริปต์ Robo ที่ต่างกันจะไม่มีผลกับลักษณะการทำงานของสคริปต์ แต่การแยกการดำเนินการจากสคริปต์ Robo เหล่านี้ในเอาต์พุตการรวบรวมข้อมูลอาจเป็นเรื่องท้าทาย เราขอแนะนำให้กำหนด id ที่ไม่ซ้ำกันตั้งแต่ 1000 ขึ้นไปสำหรับสคริปต์ Robo เพื่อหลีกเลี่ยงความขัดแย้ง
description คล้ายกับ id แต่สื่อความหมายมากกว่า
crawlStage ขั้นตอนของการรวบรวมข้อมูล Robo จะใช้สคริปต์ Robo นี้ โดยค่าเริ่มต้น ระยะการ Crawl จะเป็นขั้นตอนหลักในการ Crawl
priority ลำดับความสำคัญของสคริปต์ Robo นี้เมื่อเปรียบเทียบกับสคริปต์ Robo อื่นๆ โดยค่าเริ่มต้น สคริปต์ Robo ทั้งหมดมีลำดับความสำคัญ 1
maxNumberOfRuns ระบุจำนวนครั้งในระหว่างการ Crawl Robo จะเรียกใช้สคริปต์ Robo นี้ได้ โดยค่าเริ่มต้น Robo จะเรียกใช้สคริปต์ Robo ได้เพียงครั้งเดียว
contextDescriptor อธิบายบริบทหรือเงื่อนไขที่ทริกเกอร์สคริปต์ Robo นี้ หากไม่ระบุ ระบบจะถือว่าเงื่อนไขในการเรียกใช้ของสคริปต์ Robo นี้เป็นไปตามเงื่อนไขเสมอ กล่าวคือสคริปต์ Robo จะไม่มีเงื่อนไข
actions การดำเนินการทั้งหมดของสคริปต์ Robo นี้

ไฟล์หนึ่งจะมีคอลเล็กชันสคริปต์ Robo อย่างน้อย 1 รายการ

ต่อไปนี้คือตัวอย่างของไฟล์ที่มีสคริปต์ Robo ที่ไม่มีเงื่อนไข 2 รายการ โดยแต่ละสคริปต์จะมีการดำเนินการเดียวซึ่งจะดำเนินการเพียงครั้งเดียวเมื่อเริ่มต้นการรวบรวมข้อมูล

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

ข้อบ่งชี้บริบท

ข้อบ่งชี้บริบทจะกำหนดบริบทหรือเงื่อนไขที่ทริกเกอร์สคริปต์ Robo โดยใช้แอตทริบิวต์ 1 รายการหรือหลายแอตทริบิวต์รวมกัน ดังนี้

แอตทริบิวต์ คำอธิบาย
"condition": "always" ทริกเกอร์สคริปต์ Robo เสมอ
"condition": "element_present" ตรวจสอบว่ามีวิดเจ็ต UI ที่ตรงกับ elementDescriptors หรือข้อความที่ระบุโดย visionText ปรากฏอยู่บนหน้าจอ
"condition": "element_disabled" ตรวจสอบว่าวิดเจ็ต UI ที่ตรงกับ elementDescriptors แสดงอยู่บนหน้าจอและโต้ตอบด้วยไม่ได้
"condition": "element_checked" ตรวจสอบว่าวิดเจ็ต UI ที่ตรงกับ elementDescriptors แสดงอยู่บนหน้าจอและเลือกไว้
"condition": "app_under_test_shown" ตรวจสอบว่าการทดสอบแอปต่ำกว่านั้นทำงานอยู่ในเบื้องหน้า
"condition": "default_launcher_shown" ตรวจสอบว่าหน้าจอหลักของอุปกรณ์แสดงขึ้นมา ซึ่งหมายความว่าไม่มีแอปใดทำงานอยู่ในเบื้องหน้า
"condition": "non_roboscript_action_performed" ตรวจสอบว่าการดำเนินการต่อเนื่อง nonRoboscriptActionCount รายการล่าสุดจากการทดสอบ Robo ไม่ใช่การดำเนินการสคริปต์ Robo
negateCondition หากตั้งค่าเป็น true ระบบจะลบล้าง condition ตัวอย่างเช่น คุณใช้แอตทริบิวต์นี้เพื่อตรวจสอบว่าวิดเจ็ต UI ไม่ได้แสดงอยู่บนหน้าจอหรือไม่ หรือแอปอันเดอร์ทดสอบไม่ได้ทำงานอยู่ในเบื้องหน้า
elementDescriptors ตัวบอกองค์ประกอบอย่างน้อย 1 รายการที่ระบุวิดเจ็ต UI บนหน้าจอ โดยใช้ร่วมกับเงื่อนไข element_present, element_disabled และ element_checked พิเศษสำหรับ visionText สำหรับข้อมูลเพิ่มเติม โปรดดูที่ข้อบ่งชี้องค์ประกอบ
visionText ระบบตรวจพบข้อความบนหน้าจอโดยใช้ Optical Character Recognition (OCR) API visionText จะใช้ร่วมกับเงื่อนไข element_present พิเศษสำหรับ elementDescriptors
nonRoboscriptActionCount จำนวนการดำเนินการติดต่อกันของสคริปต์ที่ไม่ใช่ Robo ที่ทำก่อนหน้านี้ โดยใช้ร่วมกับเงื่อนไข non_roboscript_action_performed เพื่อทริกเกอร์สคริปต์ Robo หลังจากการดำเนินการ Robo ทุกๆ nonRoboscriptActionCount รายการ โดยค่าเริ่มต้นจะเป็น 1

ต่อไปนี้คือตัวอย่างของสคริปต์ Robo ที่ทริกเกอร์โดยวิดเจ็ต UI ที่มีรหัสทรัพยากร "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" ตรวจพบโดย Optical Character Recognition (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 จะแสดงเป็นกลุ่มของคู่แอตทริบิวต์-ค่าอย่างน้อย 1 คู่ ซึ่งอธิบายไว้ในตารางต่อไปนี้

แอตทริบิวต์ คำอธิบาย
eventType ระบุประเภทการดำเนินการ เช่น คลิก แก้ไขข้อความ ฯลฯ โดยต้องระบุสำหรับการดำเนินการทั้งหมด
elementDescriptors คำอธิบายที่ระบุวิดเจ็ต UI จำเป็นสำหรับการดำเนินการทั้งหมดที่มีวิดเจ็ต UI เป้าหมาย เช่น การคลิกปุ่มใดปุ่มหนึ่ง
optional หากตั้งค่าเป็น true ระบบจะข้ามการดำเนินการนี้เมื่อไม่สามารถทำได้ เช่น ระบบจะข้ามการดำเนินการนี้เมื่อไม่พบวิดเจ็ต UI เป้าหมายบนหน้าจอ โดยไม่ทำให้สคริปต์ Robo ที่มีอยู่ล้มเหลว ค่าเริ่มต้นคือ false
replacementText ข้อความที่จะป้อนลงในวิดเจ็ต UI เป้าหมาย จำเป็นสำหรับการดำเนินการแก้ไขข้อความ
swipeDirection ระบุทิศทางการปัด จำเป็นสำหรับการปัด
delayTime ระบุระยะเวลาที่ต้องรอ หน่วยเป็นมิลลิวินาที จำเป็นสำหรับการรอ
pointTapXCoordinate และ pointTapYCoordinate พิกัดพิกเซล X และ Y ของจุดที่แตะ พิเศษสำหรับ pointTapXPercent และ pointTapYPercent ต้องใช้สำหรับการดำเนินการแตะจุด
pointTapXPercent และ pointTapYPercent เปอร์เซ็นต์พิกัด X และ Y ของจุดที่แตะ พิเศษพร้อมกันสำหรับ pointTapXCoordinate และ pointTapYCoordinate ต้องใช้สำหรับการดำเนินการแตะจุด

ต่อไปนี้คือตัวอย่างของสคริปต์ Robo ที่มีการดำเนินการ 2 อย่างโดยไม่มีวิดเจ็ต UI เป้าหมาย ซึ่งหมายความว่าการดำเนินการเหล่านี้จะไม่ทำงานในวิดเจ็ต UI ที่เจาะจง

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

ตัวบอกองค์ประกอบ

ข้อบ่งชี้องค์ประกอบจะระบุวิดเจ็ต UI โดยใช้แอตทริบิวต์ที่ระบุต่อไปนี้อย่างน้อย 1 รายการ

แอตทริบิวต์ คำอธิบาย
className
ancestorClassName ชื่อคลาสของระดับบนลำดับชั้น UI ขององค์ประกอบ ระดับบนคือโหนดระดับบนสุดในลำดับชั้น UI ขององค์ประกอบ รวมถึงตัวองค์ประกอบเอง
resourceId
resourceIdRegex นิพจน์ทั่วไปของ Java ที่จะจับคู่ resourceId
contentDescription
contentDescriptionRegex นิพจน์ทั่วไปของ Java ที่จะจับคู่ contentDescription
text (ที่ปรากฏบนหน้าจอ)
textRegex นิพจน์ทั่วไปของ Java ที่จะจับคู่ text
groupViewChildPosition, recyclerViewChildPosition หรือ adapterViewChildPosition แสดงตำแหน่งย่อยของวิดเจ็ต UI โดยขึ้นอยู่กับประเภทของวิดเจ็ตหลัก

บ่อยครั้งที่ไม่มีการกำหนดแอตทริบิวต์เหล่านี้ เช่น ปุ่มอาจไม่มีข้อความและคำอธิบายเนื้อหา แม้จะมีค่าแอตทริบิวต์บางรายการอยู่ แต่ค่าอาจซ้ำกันในหน้าจอแอปหนึ่งๆ (รวมถึง resourceId)

เช่น โดยทั่วไปแล้ว การแยกความแตกต่างของรายการต่างๆ ทำได้โดยใช้ตำแหน่งย่อยที่แตกต่างกันภายในวิดเจ็ตหลักเท่านั้น ซึ่งหมายความว่าการใช้เพียงคำอธิบายองค์ประกอบเดียวเพื่อระบุวิดเจ็ต UI จะไม่เพียงพอ ดังนั้น แอตทริบิวต์ elementDescriptors ของการดำเนินการจะมีลำดับข้อบ่งชี้องค์ประกอบที่เรียงลำดับให้เหมือนกับรายการแรกตามวิดเจ็ต UI เป้าหมาย แอตทริบิวต์ที่ 2 สอดคล้องกับวิดเจ็ตหลักของวิดเจ็ต UI เป้าหมาย และอื่นๆ ระบบจะจับคู่วิดเจ็ต UI เป้าหมายของการดำเนินการเมื่อข้อบ่งชี้องค์ประกอบทั้งหมดตรงกับลำดับชั้นย่อยของวิดเจ็ต UI ที่เกี่ยวข้อง

ต่อไปนี้คือตัวอย่างของสคริปต์ Robo ที่มีการเปลี่ยนแปลงข้อความและการคลิก ซึ่งทั้ง 2 อย่างนี้ คุณต้องระบุวิดเจ็ต UI เป้าหมายโดยใช้ตัวบอกลักษณะองค์ประกอบที่มีให้

[
  {
    "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 โดยไม่มีการแจ้งเตือนบนหน้าจอที่เข้าสู่โหมดสลีปเป็นเวลา 3 วินาที จากนั้นการ Crawl จะหยุดลง

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

พารามิเตอร์เทมเพลต

พารามิเตอร์เทมเพลตคือตัวยึดตำแหน่งในสคริปต์ Robo ซึ่งแทนที่ด้วยค่าจริงเมื่อการทดสอบ Robo โหลดสคริปต์ Robo เพื่อการดำเนินการ พารามิเตอร์เทมเพลตนำหน้าด้วยเครื่องหมายขีดล่าง 2 ขีด ตามด้วยเครื่องหมายเปอร์เซ็นต์ และต่อท้ายด้วยเครื่องหมายเปอร์เซ็นต์ตามด้วยขีดล่าง 2 ขีด

สคริปต์ Robo รองรับพารามิเตอร์เทมเพลตต่อไปนี้

  • __%APP_PACKAGE_NAME%__ - ชื่อแพ็กเกจของการทดสอบแอปอันเดอร์

ต่อไปนี้คือตัวอย่างของสคริปต์ Robo ที่หยุดกระบวนการแอปภายใต้การทดสอบ

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

ความคิดเห็น

สคริปต์ Robo อาจมีบรรทัดความคิดเห็นซึ่งเป็นบรรทัดที่เริ่มต้นด้วย # หรือ //

ต่อไปนี้เป็นตัวอย่างของสคริปต์ Robo ที่มีความคิดเห็น 2 รายการ

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

ความสามารถ

โดยค่าเริ่มต้น สคริปต์ Robo จะยังคงใช้งานได้จนกว่าการดำเนินการทั้งหมดของสคริปต์ Robo จะเสร็จสมบูรณ์ (หรือพยายามดำเนินการอย่างน้อย) การทดสอบ Robo จะพยายามจับคู่การทำงานของสคริปต์ Robo ทุกครั้งที่มีการเลือกการดำเนินการ สคริปต์ Robo ใช้เทคนิคต่อไปนี้เพื่อเพิ่มความแข็งแกร่ง

เทคนิค คำอธิบาย
การจับคู่ที่ตรงกันบางส่วน หากการทำงานของสคริปต์ Robo ปัจจุบันไม่สามารถจับคู่ได้ทั้งหมด ระบบจะผ่อนปรนเกณฑ์การจับคู่และจะลองจับคู่ใหม่ การจับคู่บางส่วนจะไม่พิจารณาข้อบ่งชี้องค์ประกอบด้านนอกสุดขณะจับคู่วิดเจ็ต UI เป้าหมายของการดำเนินการของสคริปต์ Robo

หากการจับคู่บางส่วนสำเร็จ การดำเนินการของสคริปต์ Robo ที่เกี่ยวข้องจะดำเนินการตามปกติ เทคนิคนี้รองรับสถานการณ์ที่โครงสร้างของแอปเปลี่ยนแปลง เช่น ระหว่างเวอร์ชันของแอป เมื่อมีการจัดเรียงองค์ประกอบหน้าจอใหม่

ข้ามการดำเนินการปัจจุบัน หากการดำเนินการของสคริปต์ Robo ปัจจุบันจับคู่ทั้งหมดหรือบางส่วนไม่ได้ Robo จะพยายามจับคู่การดำเนินการของสคริปต์ Robo ที่ตามมา หากการดำเนินการที่ตามมาตรงกันทั้งหมดหรือบางส่วน การทดสอบ Robo จะข้าม (และไม่กลับไปที่) การดำเนินการของสคริปต์ Robo ปัจจุบันและดำเนินการลำดับต่อมา

เทคนิคนี้รองรับกรณีที่ลักษณะการทำงานของแอปมีการเปลี่ยนแปลงระหว่างเวอร์ชันหรือมีความไม่สม่ำเสมอ เช่น เมื่อกล่องโต้ตอบที่เป็นช่วงๆ อาจปรากฏขึ้นในหน้าจอที่แตกต่างกันระหว่างการบันทึกเทียบกับการเล่นสคริปต์ Robo ซ้ำ

ระงับ หากการดำเนินการของสคริปต์ Robo ในปัจจุบันหรือหลังจากนั้นไม่สามารถจับคู่ได้ทั้งหมดหรือบางส่วน สคริปต์ Robo จะถูกระงับชั่วคราวและการทดสอบ Robo จะเลือกการดำเนินการที่จะดำเนินการโดยใช้กลยุทธ์อื่น หลังจากการดำเนินการนี้เสร็จสิ้น การทดสอบ Robo จะดำเนินการเรียกใช้สคริปต์ Robo ต่อ

ตราบใดที่จับคู่การดำเนินการของสคริปต์ Robo ในปัจจุบันหรือหลังจากนั้นไม่ได้ สคริปต์ Robo จะถูกระงับต่อไปไม่ว่าจะดำเนินการจำนวนเท่าใด ดังนั้น สคริปต์ Robo จึงไม่จำเป็นต้องเป็นคำนำหน้าสำหรับการทดสอบ Robo และคุณสลับการทำงานของสคริปต์ Robo กับการดำเนินการทดสอบ Robo แบบมาตรฐานได้ เทคนิคนี้รองรับกรณีที่ลักษณะการทำงานของแอปไม่สม่ำเสมอ หรือเมื่อการเปลี่ยนแปลงระหว่างเวอร์ชันของแอปมีขนาดใหญ่พอที่การทดสอบ Robo ต้อง "เติมเต็มช่องว่าง" ด้วยการดำเนินการมาตรฐาน

ลำดับความสำคัญ

หากสคริปต์ Robo เข้าถึง maxNumberOfRuns สคริปต์จะทริกเกอร์ในการรวบรวมข้อมูลหนึ่งๆ ไม่ได้อีกต่อไป หากบริบทปัจจุบันสามารถทริกเกอร์สคริปต์ Robo ได้มากกว่า 1 รายการ ระบบจะจัดลำดับความสำคัญของสคริปต์ Robo ตามลำดับดังต่อไปนี้

  1. มีแอตทริบิวต์ contextDescriptor
  2. มี priority สูงสุด (โดยค่าเริ่มต้น สคริปต์ Robo ทั้งหมดมีการดำเนินการ priority ของ 1 เหมือนกัน)
  3. จะปรากฏรายการแรกสุดในรายการสคริปต์ Robo หากลำดับความสำคัญของสคริปต์ Robo เหมือนกัน

ต่อไปนี้คือตัวอย่างของไฟล์ที่มีสคริปต์ Robo 3 รายการซึ่งดำเนินการเดียวกันและมีการทริกเกอร์โดยเงื่อนไขเดียวกัน ซึ่งก็คือการทดสอบแอปอันเดอร์ในเบื้องหน้า

[
  {
    "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"
    }
  ]
}

ขั้นตอนการ Crawl

สคริปต์ Robo ใช้งานได้ในขั้นตอนต่างๆ ของการรวบรวมข้อมูล Robo ที่ระบุ:

ขั้นตอนการ Crawl คำอธิบาย
pre_crawl ก่อนที่ Robo จะเปิดตัวและเริ่มรวบรวมข้อมูลการทดสอบแอปอันเดอร์
post_crawl หลังจาก Robo รวบรวมข้อมูลแอปอันเดอร์ทดสอบเสร็จแล้ว
crawl ขั้นตอนการรวบรวมข้อมูลหลักเมื่อ Robo รวบรวมข้อมูลการทดสอบแอปอันเดอร์
close_screen เมื่อ Robo พยายามจะย้อนกลับ (backtrack) จากหน้าจอที่กำหนด เมื่อมีการสำรวจการทำงานที่เป็นไปได้ทั้งหมดบนหน้าจอนี้ โดยค่าเริ่มต้น Robo จะกดย้อนกลับ ซึ่งเป็นสิ่งที่ไม่พึงประสงค์ในบางสถานการณ์

หากไม่ได้ระบุแอตทริบิวต์ 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 มีการทำงานตามเงื่อนไขได้ การทำงานตามเงื่อนไขมีแอตทริบิวต์เพิ่มเติม 3 รายการที่อธิบายว่า Robo ทำงานเป็นอย่างไร

แอตทริบิวต์ คำอธิบาย
priority ลำดับความสำคัญของการดำเนินการแบบมีเงื่อนไขนี้เมื่อเทียบกับการดำเนินการแบบมีเงื่อนไขอื่นๆ ภายในสคริปต์ Robo ที่มี โดยค่าเริ่มต้น การดำเนินการแบบมีเงื่อนไขทั้งหมดจะมีลำดับความสำคัญเป็น 1
maxNumberOfRuns จำนวนครั้งที่ดำเนินการแบบมีเงื่อนไขนี้ได้ในระหว่างการเรียกใช้ 1 รายการของสคริปต์ Robo ที่มีสคริปต์ดังกล่าว โดยค่าเริ่มต้น การดำเนินการแบบมีเงื่อนไขทั้งหมดจะดำเนินการได้สูงสุด 1 ครั้งในการดำเนินการเดียวจากสคริปต์ Robo ที่มี
contextDescriptor บริบท/เงื่อนไขที่ทริกเกอร์การดำเนินการแบบมีเงื่อนไขนี้ แต่มีโครงสร้างเดียวกันและมีความสามารถคล้ายกับ ContextDescriptor ของสคริปต์ Robo

เมื่อทริกเกอร์แล้ว สคริปต์ Robo จะดำเนินการอย่างไม่มีเงื่อนไขไปทีละอย่างตามลักษณะที่ปรากฏ หากสคริปต์ Robo มีการดำเนินการตามเงื่อนไข ระบบจะพิจารณาการดำเนินการดังกล่าวทุกครั้งก่อนเลือกการดำเนินการที่ไม่มีเงื่อนไข หากมีการเรียกใช้การดำเนินการแบบมีเงื่อนไขและเลือกตามลำดับความสำคัญและจำนวนการเรียกใช้ที่เหลือ สคริปต์ Robo จะดำเนินการแบบมีเงื่อนไขนี้ มิเช่นนั้น สคริปต์ Robo จะดำเนินการที่ไม่มีเงื่อนไขต่อไปนี้ สคริปต์ Robo ต้องมีการดำเนินการที่ไม่มีเงื่อนไขอย่างน้อย 1 รายการจึงจะใช้งานได้

ต่อไปนี้คือตัวอย่างของสคริปต์ 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 ละเว้นวิดเจ็ต UI บางรายการหรือวิดเจ็ต UI ทั้งหมดบนหน้าจอหนึ่งๆ วิธีการเหล่านี้จะแสดงเป็นการละเว้น "การดำเนินการ" ด้วย eventType ELEMENT_IGNORED และ ALL_ELEMENTS_IGNORED ตามที่สอดคล้องกัน

เมื่อใดก็ตามที่แอตทริบิวต์ contextDescriptor ของสคริปต์ Robo ที่มีการละเว้นการดำเนินการตรงกับหน้าจอที่ระบุ Robo จะไม่โต้ตอบกับวิดเจ็ต UI ที่กำหนดเป้าหมายโดยการละเว้น (เว้นแต่การดำเนินการของสคริปต์ Robo อื่นๆ จะทำให้ Robo ดำเนินการกับวิดเจ็ต UI ที่ละเว้นรายการใดรายการหนึ่ง)

สคริปต์ Robo อาจมีทั้งการละเว้น การกระทำที่มีเงื่อนไข และการดำเนินการที่ไม่มีเงื่อนไขผสมกัน การละเว้นการทำงานอื่นๆ ของสคริปต์ Robo นั้นแตกต่างจากการทำงานอื่นๆ ของสคริปต์ Robo ตราบใดที่การดำเนินการดังกล่าวมี contextDescriptor ของสคริปต์ Robo ตรงกับหน้าจอระหว่างการ Crawl ของ Robo ไม่ว่าค่าของแอตทริบิวต์ priority และ maxNumberOfRuns จะเป็นอะไรก็ตาม

ต่อไปนี้เป็นตัวอย่างของไฟล์ที่มีสคริปต์ Robo 2 สคริปต์ สคริปต์ Robo แรกทำให้ Robo ไม่สนใจวิดเจ็ต UI ทั้งหมดบนหน้าจอที่มีวิดเจ็ต UI ที่มีรหัสทรัพยากร "my.app.package:id/ignored_screen" สคริปต์ Robo ที่สองทำให้ Robo ไม่สนใจวิดเจ็ต UI ที่มีรหัสทรัพยากรตรงกับนิพจน์ทั่วไปของ Java ".*:id/done" บนหน้าจอที่มีวิดเจ็ต UI ที่มีรหัสทรัพยากร "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

การยืนยัน

หากเงื่อนไขที่ยืนยันเป็น "จริง" สคริปต์ Robo จะดำเนินการต่อไปซึ่งอาจเป็นการยืนยันอีกครั้งหนึ่ง มิเช่นนั้น การดำเนินการสคริปต์ Robo จะถูกระงับเนื่องจากการยืนยันล้มเหลว

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ASSERTION" --
contextDescriptor อธิบายบริบทหรือเงื่อนไขที่ยืนยัน แต่มีโครงสร้างเดียวกันและมีความสามารถคล้ายกับ ContextDescriptor ของสคริปต์ Robo

ต่อไปนี้คือตัวอย่างของการยืนยันสคริปต์ Robo ที่ตรวจสอบว่าการทดสอบแอปอันเดอร์อยู่ในเบื้องหน้า

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

ต่อไปนี้คือตัวอย่างของการยืนยันสคริปต์ Robo ที่ตรวจสอบว่ามีวิดเจ็ต UI ที่มีรหัสทรัพยากร "com.google.samples.apps.topeka:id/done" ปรากฏอยู่บนหน้าจอ

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

ต่อไปนี้คือตัวอย่างของการยืนยันสคริปต์ Robo ที่ตรวจสอบว่าไม่พบ "Settings" บนหน้าจอที่ใช้ OCR

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

คลิก

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
eventType ระบุประเภทการทํางานของสคริปต์ Robo
"eventType": "VIEW_CLICKED" คลิกองค์ประกอบเป้าหมายของ App-under-test
"eventType": "SOFT_KEYBOARD_CLICK" คลิกองค์ประกอบเป้าหมายของแป้นพิมพ์เสมือน
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" คลิกองค์ประกอบแบบสุ่มของแป้นพิมพ์เสมือนได้สูงสุด maxNumberOfRuns ครั้ง
"eventType": "LIST_ITEM_CLICKED" ซึ่งจะใช้โดยโปรแกรมบันทึกสคริปต์ Robo ใน Android Studio สำหรับการคลิกรายการ
elementDescriptors ระบุวิดเจ็ต UI ที่มีการคลิกโดยใช้ลำดับชั้น UI ของ Android พิเศษสำหรับ visionText
visionText ระบุองค์ประกอบที่มีการคลิกโดยใช้ OCR พิเศษสำหรับ elementDescriptors
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 ที่คลิก "Privacy Policy" ที่ตรวจพบในหน้าจอโดยใช้ OCR

{
  "eventType": "VIEW_CLICKED",
  "visionText": "Privacy Policy"
}

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่คลิกองค์ประกอบแป้นพิมพ์แบบซอฟต์ที่มีคำอธิบายเนื้อหา "Emoji button"

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

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่คลิกองค์ประกอบของแป้นพิมพ์แบบนุ่มแบบสุ่มสูงสุด 5 ครั้ง

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

ปิดใช้แป้นพิมพ์เสมือน

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "DISABLE_KEYBOARD" --

ต่อไปนี้เป็นตัวอย่างการทำงานของสคริปต์ Robo ที่ปิดใช้แป้นพิมพ์เสมือน

{
  "eventType": "DISABLE_KEYBOARD"
}

เรียกใช้คำสั่ง Shell adb

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ADB_SHELL_COMMAND" --
command คำสั่ง Shell ของ 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 จะมอบสิทธิ์ทั้งหมดให้กับการทดสอบแอปต่ำกว่าเกณฑ์เมื่อเริ่มต้นการ Crawl ทุกครั้ง ดังนั้นการดำเนินการนี้จึงไม่ใช่การดำเนินการ อย่าใช้การดำเนินการนี้ในสคริปต์ Robo

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "PERMISSIONS_REQUEST" --

ละเว้นองค์ประกอบทั้งหมดบนหน้าจอ

การดำเนินการนี้ทำให้ Robo ละเว้นองค์ประกอบทั้งหมดบนหน้าจอใดก็ตามที่ทริกเกอร์สคริปต์ Robo ที่มีอยู่

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ALL_ELEMENTS_IGNORED" --

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ทำให้ Robo ละเว้นองค์ประกอบทั้งหมดบนหน้าจอ

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

ละเว้นองค์ประกอบ

การดำเนินการนี้ทำให้ Robo ละเว้นองค์ประกอบเดียว (หรือหลายองค์ประกอบ) ที่ตรงกับ elementDescriptors ที่ระบุ

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ELEMENT_IGNORED" --
elementDescriptors ระบุวิดเจ็ต UI ที่ละเว้นโดยใช้ลำดับชั้น UI ของ Android

คุณจะระบุแอตทริบิวต์ต่อไปนี้หรือไม่ก็ได้

  • ignoreChildren - หากตั้งค่าเป็น true Robo จะไม่สนใจองค์ประกอบสืบทอดทั้งหมดของวิดเจ็ต UI ที่ละเว้นด้วย โดยค่าเริ่มต้นจะเป็น false

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ทำให้ Robo ละเว้นองค์ประกอบทั้งหมด ซึ่งคำอธิบายเนื้อหาขึ้นต้นด้วย "Avatar"

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

ข้อความอินพุต

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
eventType ระบุประเภทการทํางานของสคริปต์ Robo
"eventType": "VIEW_TEXT_CHANGED" ป้อนข้อความที่ระบุลงในวิดเจ็ต UI เป้าหมาย
"eventType": "ENTER_TEXT" ป้อนข้อความที่ระบุลงในวิดเจ็ต UI เป้าหมาย แล้วส่งเหตุการณ์ KEYCODE_ENTER ไปยังวิดเจ็ต UI นี้
elementDescriptors ระบุวิดเจ็ต UI เป้าหมายโดยใช้ลำดับชั้น UI ของ Android
replacementText ข้อความที่จะป้อนลงในวิดเจ็ต UI เป้าหมาย

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ป้อน "John" ลงในวิดเจ็ต UI ที่มีรหัสทรัพยากร "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 ระบุวิดเจ็ต UI เป้าหมายโดยใช้ลำดับชั้น UI ของ Android พิเศษสำหรับ visionText
visionText ระบุองค์ประกอบที่มีการคลิกนานโดยใช้ OCR พิเศษสำหรับ elementDescriptors

คุณจะระบุแอตทริบิวต์ต่อไปนี้หรือไม่ก็ได้

  • delayTime - ระบุระยะเวลาในการกดคลิกยาวๆ หนึ่งเป็นมิลลิวินาที

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่คลิกวิดเจ็ต UI เป็นเวลา 5 วินาทีพร้อมกับคำอธิบายเนื้อหา "Avatar 8"

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

ทำท่าทางสัมผัสแบบจุดเดียว

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ONE_POINT_GESTURE" --
coordinates พิกัด 2 แบบสำหรับท่าทางสัมผัสแบบจุดเดียว ซึ่งมีรูปแบบ "(x1,y1)->(x2,y2)" เป็นเปอร์เซ็นต์หรือพิกเซล

คุณจะระบุแอตทริบิวต์ต่อไปนี้หรือไม่ก็ได้

  • dragAndDrop - หากตั้งค่าเป็น true ท่าทางสัมผัสแบบจุดเดียวจะใช้การลากและวาง โดยค่าเริ่มต้นจะเป็น false

ต่อไปนี้คือตัวอย่างของการดำเนินการโดยใช้ท่าทางสัมผัสแบบจุดเดียวของสคริปต์ Robo ที่เลื่อนลง

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

ทำท่าทางสัมผัสแบบ 2 จุด

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "TWO_POINT_GESTURE" --
coordinates พิกัด 4 จุดสำหรับท่าทางสัมผัสแบบ 2 จุด ในรูปแบบ "(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" เป็นเปอร์เซ็นต์หรือพิกเซล

ต่อไปนี้เป็นตัวอย่างการทำงานของสคริปต์ Robo ที่ทำท่าทางสัมผัสแบบบีบออก

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

ดำเนินการ IME

การดำเนินการนี้จะกดปุ่มการทำงานปัจจุบัน เช่น ถัดไป เสร็จสิ้น และค้นหา ในตัวแก้ไขวิธีการป้อนข้อมูล (IME) สำหรับวิดเจ็ต UI เป้าหมายที่ระบุ

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors ระบุวิดเจ็ต UI เป้าหมายโดยใช้ลำดับชั้น UI ของ Android

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ดำเนินการ IME ในวิดเจ็ต UI ที่มีรหัสทรัพยากร "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"
}

เลื่อนองค์ประกอบเข้ามาในมุมมอง

การดำเนินการนี้ทำให้การทดสอบ Robo เลื่อนไปด้านหน้าวิดเจ็ต UI ที่ตรงกับ elementDescriptors ที่ระบุจนกว่าวิดเจ็ต UI ที่ตรงกับ childElementDescriptors ที่ระบุจะปรากฏบนหน้าจอ หรือเลื่อนวิดเจ็ตที่เลื่อนแล้วไม่ได้เลยหรือเลื่อนจนครบจำนวนสูงสุด 50 การเลื่อนแล้ว

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors ระบุวิดเจ็ต UI ที่เลื่อนโดยใช้ลำดับชั้น UI ของ Android
childElementDescriptors ระบุวิดเจ็ต UI สำหรับเลื่อนโดยใช้ลำดับชั้น UI ของ Android

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่เลื่อนวิดเจ็ต UI ที่มีรหัสทรัพยากร "my.app.package:id/scrollable_card_container" จนกระทั่งวิดเจ็ต UI ที่มีข้อความ "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 ขึ้นอยู่กับความสามารถในการเลื่อนในแนวตั้งหรือแนวนอนของวิดเจ็ต UI เป้าหมาย
  • Backward - Up หรือ Left ขึ้นอยู่กับความสามารถในการเลื่อนในแนวตั้งหรือแนวนอนของวิดเจ็ต UI เป้าหมาย
elementDescriptors ระบุวิดเจ็ต UI เป้าหมายโดยใช้ลำดับชั้น UI ของ Android

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ปัดวิดเจ็ต UI ขึ้นด้วยรหัสทรัพยากร "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 ระบุวิดเจ็ต UI เป้าหมายโดยใช้ลำดับชั้น UI ของ 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 ที่รอ 3 วินาที

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

รอองค์ประกอบ

การดำเนินการนี้ทำให้การทดสอบ Robo ต้องรอให้องค์ประกอบปรากฏบนหน้าจอจนถึงระยะหมดเวลาที่ระบุไว้

ตารางต่อไปนี้แสดงรายการแอตทริบิวต์ที่จำเป็น

แอตทริบิวต์ คำอธิบาย
"eventType": "WAIT_FOR_ELEMENT" --
delayTime ระบุระยะหมดเวลาการรอเป็นมิลลิวินาที
elementDescriptors ระบุวิดเจ็ต UI ที่รอโดยใช้ลำดับชั้น UI ของ Android

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่รอถึง 30 วินาทีเพื่อให้วิดเจ็ต UI ที่มีรหัสทรัพยากร "my.app.package:id/confirmation_button" ปรากฏขึ้นบนหน้าจอ

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

ขั้นตอนถัดไป