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

เอกสารนี้มีข้อมูลอ้างอิงเกี่ยวกับสคริปต์ Robo ซึ่งรวมถึง โครงสร้าง ความสามารถ การใช้งาน การบันทึก และการดำเนินการ สคริปต์ Robo คือ การทดสอบที่ทำให้งานการประกันคุณภาพ (QA) ด้วยตนเองสำหรับแอปบนอุปกรณ์เคลื่อนที่เป็นแบบอัตโนมัติ และ เปิดใช้กลยุทธ์การรวมอย่างต่อเนื่อง (CI) และการทดสอบก่อนเปิดตัว Robo script คือไฟล์ 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 ระบบจะตรวจหาข้อความบนหน้าจอโดยใช้ API การรู้จำอักขระด้วยภาพ (OCR) 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 นั้นเพื่อดำเนินการ พารามิเตอร์ เทมเพลตจะมีคำนำหน้าเป็นขีดล่างคู่ตามด้วยเครื่องหมายเปอร์เซ็นต์ และมีคำต่อท้ายเป็นเครื่องหมายเปอร์เซ็นต์ตามด้วยขีดล่างคู่

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

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

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

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

ความคิดเห็น

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

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

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

ความสามารถ

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

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

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

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

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

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

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

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

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

  1. มีแอตทริบิวต์ contextDescriptor
  2. มี priority สูงสุด (โดยค่าเริ่มต้น สคริปต์ Robo ทั้งหมดจะมีpriorityการดำเนินการ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 แอปที่อยู่ระหว่างการทดสอบเสร็จแล้ว สคริปต์ Robo ต้องมีความยาวไม่เกิน 15 วินาที ไม่เช่นนั้นการ Crawl อาจสิ้นสุดลงเนื่องจากหมดเวลาpost_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

ระบบจะโหลดวิดเจ็ต Children ของ 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, 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 รายการสำหรับการสัมผัสด้วย 1 นิ้ว ซึ่งจัดรูปแบบเป็น "(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"
    }
  ]
}

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