คู่มืออ้างอิงสคริปต์ 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"
      }
    ]
  }
]

การรองรับสคริปต์ Robo สำหรับ iOS+

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

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

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

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

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

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

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

โครงสร้าง

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

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

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

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

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

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

ตัวอธิบายบริบทจะกำหนดบริบทหรือเงื่อนไขที่ทริกเกอร์ Robo script โดยใช้แอตทริบิวต์อย่างน้อย 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 ระบบจะตรวจหาข้อความบนหน้าจอโดยใช้การรู้จำอักขระด้วยภาพ (OCR) API visionText ใช้ร่วมกับเงื่อนไข element_present ใช้ร่วมกับ elementDescriptors ไม่ได้
nonRoboscriptActionCount จำนวนการดำเนินการของสคริปต์ที่ไม่ใช่ Robo ที่ดำเนินการก่อนหน้านี้ ใช้ร่วมกับเงื่อนไข non_roboscript_action_performed เพื่อทริกเกอร์สคริปต์ Robo หลังจากดำเนินการ nonRoboscriptActionCount Robo ทุกครั้ง โดยค่าเริ่มต้นจะเป็น 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" ที่ตรวจพบโดยการรู้จำอักขระด้วยภาพ (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" : "WAIT",
      "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": "WAIT",
    "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 จะหยุดการ Crawl หลังจากที่สคริปต์ Robo เสร็จสมบูรณ์ โดยค่าเริ่มต้นจะเป็น false

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

"roboscript": {
  "executionMode": {
    "strict": true,
    "notify": false
  },
  "postscript": {
    "terminate": true
  }
}
[
  {
    "eventType": "WAIT",
    "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-3 รายการ

# 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 ต้อง "เติมเต็มช่องว่าง" ด้วยการดำเนินการมาตรฐาน

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

หากสคริปต์ Robo ถึงmaxNumberOfRunsแล้ว ระบบจะไม่ทริกเกอร์สคริปต์นั้นอีก ในการ Crawl ที่กำหนด หากสคริปต์ 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": "WAIT",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "WAIT",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "WAIT",
        "delayTime": 3000
      }
    ]
  }
]

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

  1. "Robo script 2" เนื่องจากมีลำดับความสำคัญสูงสุด
  2. "Robo script 1" เนื่องจากจะปรากฏก่อนในสคริปต์ Robo ที่เหลือที่เกี่ยวข้อง ซึ่งมีลำดับความสำคัญเดียวกัน
  3. "Robo script 3" เป็นสคริปต์ Robo สุดท้ายที่ใช้ได้

การเรียกใช้ซ้ำ

โดยค่าเริ่มต้น Robo จะเรียกใช้สคริปต์ Robo อย่างมาก 1 ครั้งระหว่างการ Crawl คุณปรับค่านี้ได้ผ่านแอตทริบิวต์ maxNumberOfRuns

ต่อไปนี้เป็นตัวอย่างสคริปต์ Robo ที่นำแอปที่อยู่ระหว่างทดสอบไปไว้เบื้องหลังได้สูงสุด 10 ครั้ง

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

ขั้นตอนการ Crawl

สคริปต์ Robo จะใช้ได้ในขั้นตอนต่างๆ ของการ Crawl ด้วย Robo ที่กำหนด

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

หากไม่ได้ระบุแอตทริบิวต์ crawlStage ของสคริปต์ Robo ระบบจะถือว่าแอตทริบิวต์ดังกล่าวเป็น crawl

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

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

ต่อไปนี้คือตัวอย่างสคริปต์ Robo ที่สั่งให้ Robo คลิก "Cancel" ทุกครั้งที่พยายามย้อนกลับจากกล่องโต้ตอบ การยืนยัน

{
  "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 จำนวนครั้งที่ดำเนินการตามเงื่อนไขนี้ได้ในระหว่างการ เรียกใช้สคริปต์ Robo ที่มีอยู่ โดยค่าเริ่มต้น การดำเนินการแบบมีเงื่อนไขทั้งหมดจะดำเนินการได้สูงสุด 1 ครั้งในการเรียกใช้สคริปต์ Robo ที่มีการดำเนินการดังกล่าว 1 ครั้ง
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": "WAIT",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "WAIT",
      "delayTime": 10000
    }
}

การละเว้นการดำเนินการ

สคริปต์ Robo อาจมีวิธีการให้ Robo ละเว้นวิดเจ็ต UI ที่เฉพาะเจาะจงหรือวิดเจ็ต UI ทั้งหมดในหน้าจอหนึ่งๆ คำสั่งเหล่านี้แสดงเป็นการละเว้น "การดำเนินการ" ด้วย eventType ELEMENT_IGNORED และ ALL_ELEMENTS_IGNORED ตามลำดับ

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

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

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

ระบบจะโหลดวิดเจ็ต Child ของ 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 test

การยืนยัน

หากเงื่อนไขที่ยืนยันเป็นจริง สคริปต์ 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" คลิกองค์ประกอบเป้าหมายของแอปที่อยู่ระหว่างการทดสอบ
"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 ไม่ได้
matchIndex ระบุดัชนีของอินสแตนซ์ขององค์ประกอบเป้าหมายที่ตรงกัน เมื่อระบุองค์ประกอบเป้าหมายโดยใช้ visionText หากเป็น 0 การดำเนินการสคริปต์ Robo จะเลือกองค์ประกอบแรกที่ตรงกัน หากเป็น 1 การดำเนินการสคริปต์ Robo จะเลือกองค์ประกอบที่ 2 ที่ตรงกัน และอื่นๆ การเรียงลำดับจะกำหนดจากซ้ายไปขวาและจากบนลงล่าง ค่าเริ่มต้นคือ 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" ที่ตรวจพบเป็นครั้งที่ 2 บนหน้าจอโดยใช้ OCR

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

ต่อไปนี้คือตัวอย่างการดำเนินการของสคริปต์ 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"
}

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

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

แอตทริบิวต์ คำอธิบาย
"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 โรโบจะไม่สนใจวิดเจ็ต UI ที่ถูกละเว้นทั้งหมด โดยค่าเริ่มต้นจะเป็น false

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

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

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

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

แอตทริบิวต์ คำอธิบาย
eventType ระบุประเภทการดำเนินการของสคริปต์ Robo
"eventType": "VIEW_TEXT_CHANGED" ป้อนข้อความที่ระบุลงในวิดเจ็ต UI เป้าหมาย
"eventType": "ENTER_TEXT" ป้อนข้อความที่ระบุลงในวิดเจ็ต UI เป้าหมาย แล้วส่ง KEYCODE_ENTER event ไปยังวิดเจ็ต 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 ไม่ได้
matchIndex ระบุดัชนีของอินสแตนซ์ขององค์ประกอบเป้าหมายที่ตรงกัน เมื่อระบุองค์ประกอบเป้าหมายโดยใช้ visionText หากเป็น 0 การดำเนินการสคริปต์ Robo จะเลือกองค์ประกอบแรกที่ตรงกัน หากเป็น 1 การดำเนินการสคริปต์ Robo จะเลือกองค์ประกอบที่ 2 ที่ตรงกัน และอื่นๆ การเรียงลำดับจะกำหนดจากซ้ายไปขวาและจากบนลงล่าง ค่าเริ่มต้นคือ 0 (ระบบจะเลือกรายการที่ตรงกันรายการแรก)

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

  • delayTime - ระบุระยะเวลาของการกดค้างสำหรับการคลิกแบบยาวเป็นมิลลิวินาที

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

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

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

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

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

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

  • dragAndDrop - หากตั้งค่าเป็น true ท่าทางสัมผัสแบบ 1 นิ้วจะดำเนินการ ลากและวาง โดยค่าเริ่มต้นจะเป็น 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"
    }
  ]
}

สิ้นสุดการ Crawl

การดำเนินการนี้จะหยุดการทดสอบ Robo

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

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

ตัวอย่างการทำงานของสคริปต์ Robo ที่หยุดการทดสอบ Robo มีดังนี้

{
  "eventType": "TERMINATE_CRAWL"
}

รอ

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

แอตทริบิวต์ คำอธิบาย
"eventType": "WAIT" (or "DELAYED_MESSAGE_POSTED") --
delayTime ระบุระยะเวลารอเป็นมิลลิวินาที

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

{
  "eventType": "WAIT",
  "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"
    }
  ]
}

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