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

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

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

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

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

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

ตัวบอกบริบท

ตัวบ่งชี้บริบทจะกําหนดบริบทหรือเงื่อนไขที่ทริกเกอร์ Roboscript โดยใช้แอตทริบิวต์อย่างน้อย 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 ระบบจะตรวจหาข้อความบนหน้าจอโดยใช้ API การรู้จำอักขระด้วยภาพ (OCR) 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" ที่ตรวจพบโดยการรู้จำอักขระด้วยภาพ (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 เป้าหมายบนหน้าจอ โดยไม่ทำให้สคริปต์ Roboscript ทำงานผิดพลาด โดยค่าเริ่มต้น ค่านี้คือ 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"
      }
    ]
  }
]

ตัวเลือกการดําเนินการ

คุณอาจใส่ออบเจ็กต์ JSON ที่ระบุตัวเลือกการดำเนินการสำหรับสคริปต์ Robo นั้นไว้หน้ารายการการดำเนินการในสคริปต์ 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": "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 ในปัจจุบันจับคู่ได้ไม่สมบูรณ์ ระบบจะผ่อนปรนเกณฑ์การจับคู่และพยายามจับคู่อีกครั้ง การจับคู่บางส่วนจะไม่พิจารณาตัวบ่งชี้องค์ประกอบด้านนอกสุดขณะจับคู่วิดเจ็ต UI เป้าหมายของการดำเนินการสคริปต์ 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": "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 ไม่เกิน 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 ครั้ง โดยค่าเริ่มต้น การดำเนินการแบบมีเงื่อนไขทั้งหมดจะดำเนินการได้สูงสุด 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 อาจมีการดำเนินการแบบไม่สนใจ แบบมีเงื่อนไข และแบบไม่มีเงื่อนไขผสมกัน การละเว้นการดําเนินการจะทํางานได้ตราบใดที่ contextDescriptor ของสคริปต์ Robo ที่รวมอยู่นั้นตรงกับหน้าจอระหว่างการ Crawl ของ Robo โดยไม่คำนึงถึงค่าของแอตทริบิวต์ priority และ maxNumberOfRuns

ต่อไปนี้เป็นตัวอย่างไฟล์ที่มีสคริปต์ Robo 2 รายการ สคริปต์ Robo แรกทําให้ 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

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

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

  • delayTime - ระบุระยะเวลาการกดค้างไว้เป็นมิลลิวินาที

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

{
  "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 ที่กดปุ่ม Home

{
  "eventType": "GO_HOME"
}

เลื่อนองค์ประกอบให้แสดง

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

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

แอตทริบิวต์ คำอธิบาย
"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

ต่อไปนี้คือตัวอย่างการดําเนินการของ Roboscript ที่เลื่อนแถบเลื่อนของแถบเลื่อนไปทางขวา

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

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