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

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

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

  • ใช้คุณสมบัติการบันทึกสคริปต์ Robo (แอนดรอยเท่านั้น)

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

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

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการใช้สคริปต์ 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"
      }
    ]
  }
]

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

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

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

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

คุณลักษณะการระบุต่อไปนี้ในตัวอธิบายองค์ประกอบได้รับการสนับสนุนใน iOS+:

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

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

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

โครงสร้าง

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

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

ไฟล์เดียวประกอบด้วยคอลเลกชันของสคริปต์ Robo หนึ่งรายการขึ้นไป

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

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

คำอธิบายบริบท

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

คุณลักษณะ คำอธิบาย
"condition": "always" ทริกเกอร์สคริปต์ Robo เสมอ
"condition": "element_present" ตรวจสอบว่าวิดเจ็ต 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 ตัวอธิบายองค์ประกอบตั้งแต่หนึ่งรายการขึ้นไปที่ระบุวิดเจ็ต UI บนหน้าจอ โดยใช้ร่วมกับเงื่อนไข element_present , element_disabled และ element_checked เอกสิทธิ์ร่วมกันกับ visionText สำหรับข้อมูลเพิ่มเติม โปรดดูที่ Element descriptors
visionText ตรวจพบข้อความบนหน้าจอโดยใช้ Optical Character Recognition (OCR) API visionText ใช้ร่วมกับเงื่อนไข element_present ไม่เกิดร่วมกันกับ elementDescriptors
nonRoboscriptActionCount จำนวนการดำเนินการต่อเนื่องที่ไม่ใช่สคริปต์ Robo ที่ดำเนินการก่อนหน้านี้ โดยใช้ร่วมกับเงื่อนไข non_roboscript_action_performed เพื่อทริกเกอร์สคริปต์ Robo หลังจากการกระทำ Robo nonRoboscriptActionCount ทุกครั้ง โดยค่าเริ่มต้น จะเป็น 1

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

คุณลักษณะ คำอธิบาย
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 ที่มีการดำเนินการสองรายการโดยไม่มีวิดเจ็ต UI เป้าหมาย ซึ่งหมายความว่าการดำเนินการเหล่านี้ไม่ทำงานบนวิดเจ็ต UI ที่เฉพาะเจาะจง:

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

ตัวอธิบายองค์ประกอบ

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

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

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

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

ต่อไปนี้เป็นตัวอย่างของสคริปต์ Robo ที่มีการเปลี่ยนแปลงข้อความและการคลิก ซึ่งทั้งสองอย่างนี้กำหนดให้คุณต้องระบุวิดเจ็ต 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
    • notify - หากตั้งค่าเป็น false สคริปต์ Robo จะไม่แสดงการแจ้งเตือนบนหน้าจอเมื่อเริ่มต้นและสิ้นสุดการดำเนินการ โดยค่าเริ่มต้น มันเป็น true
  • postscript - ตัวเลือกการดำเนินการที่ใช้หลังจากสคริปต์ Robo เสร็จสมบูรณ์:
    • terminate - หากตั้งค่าเป็น true การทดสอบ Robo จะหยุดรวบรวมข้อมูลหลังจากสคริปต์ Robo เสร็จสมบูรณ์ โดยค่าเริ่มต้นจะเป็น false

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

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

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

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

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

  • __%APP_PACKAGE_NAME%__ - ชื่อแพ็คเกจของแอปที่อยู่ระหว่างการทดสอบ

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

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

ความคิดเห็น

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

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

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

ความสามารถ

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

ขั้นตอนการรวบรวมข้อมูล

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

ขั้นตอนการรวบรวมข้อมูล คำอธิบาย
pre_crawl ก่อนที่ Robo จะเปิดตัวและเริ่มรวบรวมข้อมูลแอปที่อยู่ระหว่างการทดสอบ
post_crawl หลังจากที่ Robo รวบรวมข้อมูลแอปที่อยู่ระหว่างการทดสอบเสร็จแล้ว
crawl ขั้นตอนการรวบรวมข้อมูลหลัก เมื่อ Robo รวบรวมข้อมูลแอปที่อยู่ระหว่างการทดสอบ
close_screen เมื่อ Robo พยายามย้อนกลับ (ย้อนกลับ) จากหน้าจอที่กำหนด เมื่อมีการสำรวจการกระทำที่เป็นไปได้ทั้งหมดบนหน้าจอนี้ ตามค่าเริ่มต้น 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" ทุกครั้งที่พยายามย้อนกลับ (ย้อนกลับ) จากกล่องโต้ตอบการยืนยัน:

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

การกระทำตามเงื่อนไข

สคริปต์ Robo สามารถมีการดำเนินการตามเงื่อนไขได้ การดำเนินการตามเงื่อนไขมีคุณลักษณะเพิ่มเติมสามประการที่อธิบายว่า Robo ดำเนินการอย่างไร:

คุณลักษณะ คำอธิบาย
priority ลำดับความสำคัญของการดำเนินการตามเงื่อนไขนี้เมื่อเปรียบเทียบกับการดำเนินการตามเงื่อนไขอื่นๆ ภายในสคริปต์ Robo ที่มี ตามค่าเริ่มต้น การดำเนินการตามเงื่อนไขทั้งหมดจะมีลำดับความสำคัญเป็น 1
maxNumberOfRuns การดำเนินการตามเงื่อนไขนี้สามารถดำเนินการได้กี่ครั้งระหว่างการดำเนินการสคริปต์ Robo ที่มีสคริปต์หนึ่งครั้ง ตามค่าเริ่มต้น การดำเนินการตามเงื่อนไขทั้งหมดสามารถทำได้สูงสุดหนึ่งครั้งในการดำเนินการครั้งเดียวของสคริปต์ Robo ที่มี
contextDescriptor บริบท/เงื่อนไขที่ทริกเกอร์การดำเนินการตามเงื่อนไขนี้ มีโครงสร้างเดียวกันและมีความสามารถคล้ายกันกับ [contextDescriptor ของสคริปต์ Robo](#context-descriptor)

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

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

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

ละเลยการกระทำ

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

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

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

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

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

ปิดการใช้งานคีย์บอร์ดอ่อน

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

คุณลักษณะ คำอธิบาย
"eventType": "DISABLE_KEYBOARD" --

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่ปิดใช้งานซอฟต์คีย์บอร์ด:

{
  "eventType": "DISABLE_KEYBOARD"
}

ดำเนินการคำสั่งเชลล์ adb

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

คุณลักษณะ คำอธิบาย
"eventType": "ADB_SHELL_COMMAND" --
command คำสั่งเชลล์ Android Debug Bridge (adb) เพื่อดำเนินการ

แอ็ตทริบิวต์ต่อไปนี้เป็นทางเลือก:

  • expectedOutputRegex - เอาต์พุตที่คาดหวังของคำสั่งเป็นนิพจน์ทั่วไปของ Java หากผลลัพธ์ไม่ตรงกัน การทำงานของสคริปต์ Robo จะล้มเหลว ตามค่าเริ่มต้น จะเป็นสตริงว่าง ซึ่งหมายความว่าไม่ได้ตรวจสอบเอาต์พุต

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

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

ให้สิทธิ์

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

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

คุณลักษณะ คำอธิบาย
"eventType": "PERMISSIONS_REQUEST" --

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

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

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

คุณลักษณะ คำอธิบาย
"eventType": "ALL_ELEMENTS_IGNORED" --

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

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

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

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

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

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

แอ็ตทริบิวต์ต่อไปนี้เป็นทางเลือก:

  • delayTime - ระบุระยะเวลาในการกดลงของการคลิกแบบยาวในหน่วยมิลลิวินาที

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

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

ทำท่าทางแบบจุดเดียว

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

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

แอ็ตทริบิวต์ต่อไปนี้เป็นทางเลือก:

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

ต่อไปนี้เป็นตัวอย่างของการกระทำด้วยท่าทางแบบจุดเดียวของสคริปต์ Robo ที่ทำการปัดลง:

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

ทำท่าทางสองจุด

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

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

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

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

ดำเนินการ IME

การดำเนินการนี้จะกดปุ่มการดำเนินการปัจจุบัน เช่น ถัดไป เสร็จสิ้น และค้นหาบน Input Method Editor (IME) สำหรับวิดเจ็ต UI เป้าหมายที่ระบุ

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

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

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ 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 สำหรับการกดกลับไปที่ Emulators 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 เป้าหมายโดยใช้ลำดับชั้น Android UI

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

ต่อไปนี้คือตัวอย่างการทำงานของสคริปต์ Robo ที่เลื่อนแถบเลื่อนของแถบค้นหาไปทางขวา:

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

ยุติการรวบรวมข้อมูล

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

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

คุณลักษณะ คำอธิบาย
"eventType": "TERMINATE_CRAWL" --

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

{
  "eventType": "TERMINATE_CRAWL"
}

รอ

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

คุณลักษณะ คำอธิบาย
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime ระบุระยะเวลาในการรอ มีหน่วยเป็นมิลลิวินาที

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

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

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

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

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

คุณลักษณะ คำอธิบาย
"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"
    }
  ]
}

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