Catch up on highlights from Firebase at Google I/O 2023. Learn more

Przewodnik po skryptach Robo

Ten dokument zawiera informacje referencyjne dotyczące skryptów Robo, w tym strukturę, możliwości, użycie, nagrywanie i działania. Skrypty Robo to testy, które automatyzują ręczne zadania zapewniania jakości (QA) dla aplikacji mobilnych i umożliwiają ciągłą integrację (CI) oraz strategie testowania przed uruchomieniem. Skrypt Robo to plik JSON opisujący sekwencję interfejsu użytkownika (UI) i innych działań.

Możesz utworzyć skrypt Robo na następujące sposoby:

  • Użyj funkcji nagrywania skryptów Robo.
  • Utwórz ręcznie skrypt Robo.
  • Nagraj skrypt Robo, a następnie edytuj go ręcznie.

Aby dowiedzieć się więcej o używaniu skryptów Robo, zobacz Uruchamianie skryptu Robo .

Skrypt Robo jest dostarczany do Robo test wraz z innymi danymi wejściowymi, takimi jak testowany pakiet aplikacji na Androida (APK).

Poniżej znajduje się przykład skryptu Robo, który podpisuje użytkownika w aplikacji, co jest uruchamiane po uruchomieniu testowanej aplikacji:

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

Jeśli w pliku znajduje się pojedynczy skrypt Robo i ma on domyślny warunek wyzwalający app_under_test_shown , jak w powyższym przykładzie, możesz określić skrypt Robo w pliku przy użyciu prostszego formatu - tak jak sekwencję jego działań:

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

Struktura

Skrypt Robo ma kilka atrybutów opisujących sposób, w jaki Robo go wykonuje. Większość z tych atrybutów jest opcjonalna z predefiniowanymi wartościami domyślnymi:

Atrybut Opis
id Liczba całkowita, która pomaga śledzić ten skrypt Robo w wynikach indeksowania.
description Podobny do id , ale bardziej opisowy.
crawlStage Etap przeszukiwania Robo stosuje ten skrypt Robo w. Domyślnie jest to główny etap indeksowania.
priority Priorytet tego skryptu Robo w porównaniu do innych skryptów Robo. Domyślnie wszystkie skrypty Robo mają priorytet 1 .
maxNumberOfRuns Określa, ile razy podczas przeszukiwania Robo może wykonać ten skrypt Robo. Domyślnie Robo może jednorazowo wykonać skrypt Robo.
contextDescriptor Opisuje kontekst/warunek, który wyzwala ten skrypt Robo. Jeśli zostanie pominięty, warunek aktywacji tego skryptu Robo jest uważany za zawsze spełniony; innymi słowy, skrypt Robo jest bezwarunkowy.
actions Wszystkie działania tego skryptu Robo.

Pojedynczy plik zawiera zbiór jednego lub więcej skryptów Robo.

Poniżej znajduje się przykład pliku z dwoma bezwarunkowymi skryptami Robo, z których każdy zawiera pojedynczą akcję wykonywaną raz na początku przeszukiwania:

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

Deskryptor kontekstu

Deskryptor kontekstu definiuje kontekst/warunek, który wyzwala skrypt Robo, używając jednego lub kombinacji kilku atrybutów:

Atrybut Opis
"condition": "element_present" Sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika, który pasuje do elementDescriptors lub tekstu określonego przez visionText .
"condition": "element_disabled" Sprawdza, czy widżet interfejsu użytkownika pasujący do elementDescriptors jest obecny na ekranie i nie można z nim wchodzić w interakcje.
"condition": "element_checked" Sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika pasujący do elementDescriptors i czy jest on sprawdzany.
"condition": "app_under_test_shown" Sprawdza, czy testowana aplikacja działa na pierwszym planie.
"condition": "default_launcher_shown" Sprawdza, czy wyświetlany jest ekran główny urządzenia, co oznacza, że ​​na pierwszym planie nie działają żadne aplikacje.
"condition": "non_roboscript_action_performed" Sprawdza, czy ostatnia akcja wykonana przez test Robo nie jest akcją skryptu Robo.
negateCondition Jeśli ustawiona na true , neguje condition . Możesz na przykład użyć tego atrybutu, aby sprawdzić, czy widżet interfejsu użytkownika NIE jest obecny na ekranie lub czy testowana aplikacja NIE działa na pierwszym planie.
elementDescriptors Jeden lub więcej deskryptorów elementów, które identyfikują widżet interfejsu użytkownika na ekranie. Jest używany w połączeniu z warunkami element_present , element_disabled i element_checked . Wzajemnie wykluczające się z visionText . Aby uzyskać więcej informacji, zobacz sekcję Deskryptory elementów .
visionText Tekst na ekranie jest wykrywany za pomocą interfejsu API optycznego rozpoznawania znaków (OCR). visionText jest używany w połączeniu z warunkiem element_present . Wzajemnie wykluczające się z elementDescriptors .

Poniżej znajduje się przykład skryptu Robo uruchamianego przez widżet interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/page_header" widocznym na ekranie:

{
  "id": 1000,
  "contextDescriptor": {
    "condition": "element_present",
    "elementDescriptors": [
      {
        "resourceId": "my.app.package:id/page_header"
      }
    ]
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "elementDescriptors": [
        {
          "text": "Settings"
        }
      ]
    }
  ]
}

Poniżej znajduje się przykład skryptu Robo, który jest wyzwalany przez "Privacy Policy" wykrytą przez optyczne rozpoznawanie znaków (OCR):

{
  "id": 1000,
  "description": "Vision text Robo script",
  "contextDescriptor": {
    "condition": "element_present",
    "visionText": "Privacy Policy"
  },
  "actions": [
    {
      "eventType": "VIEW_CLICKED",
      "visionText": "Privacy Policy"
    }
  ]
}

Poniżej znajduje się przykład skryptu Robo, który czeka 5 sekund po każdej nieskryptowej akcji Robo:

{
  "contextDescriptor": {
    "condition": "non_roboscript_action_performed"
  },
  "maxNumberOfRuns" : 1000,
  "actions" : [
    {
      "eventType" : "DELAYED_MESSAGE_POSTED",
      "delayTime" : 5000
    }]
}

działania

Każda akcja w skrypcie Robo jest reprezentowana jako wiązka jednej lub więcej par atrybut-wartość, które są opisane w poniższej tabeli:

Atrybut Opis
eventType Określa typ akcji, np. kliknięcie, edycja tekstu itp. Wymagane dla każdej akcji.
elementDescriptors Deskryptory identyfikujące widżet interfejsu użytkownika. Wymagane dla wszystkich działań, które mają docelowy widżet interfejsu użytkownika, np. kliknięcie określonego przycisku.
optional Jeśli jest ustawiona na true , ta akcja jest pomijana, gdy nie można jej wykonać. Na przykład ta akcja jest pomijana, gdy nie może znaleźć docelowego widżetu interfejsu użytkownika na ekranie – bez niepowodzenia zawierającego go skryptu Robo. Domyślnie wartością jest false .
replacementText Tekst do wprowadzenia w docelowym widżecie interfejsu użytkownika. Wymagane do działań związanych z edycją tekstu.
swipeDirection Określa kierunek przesunięcia. Wymagane do akcji przesuwania.
delayTime Określa czas oczekiwania w milisekundach. Wymagane dla akcji oczekiwania.
pointTapXCoordinate i pointTapYCoordinate Współrzędne X i Y piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent . Wymagane do akcji typu point tap.
pointTapXPercent i pointTapYPercent Współrzędne procentowe X i Y punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate . Wymagane do akcji typu point tap.

Poniżej znajduje się przykład skryptu Robo z dwiema akcjami bez docelowych widżetów interfejsu użytkownika, co oznacza, że ​​te akcje nie działają na określonym widżecie interfejsu użytkownika:

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

Deskryptory elementów

Deskryptor elementu identyfikuje widżet interfejsu użytkownika za pomocą co najmniej jednego z następujących atrybutów identyfikujących:

Atrybut Opis
className
ancestorClassName Nazwa klasy przodka hierarchii interfejsu użytkownika elementu. Przodkiem jest dowolny z węzłów nadrzędnych w hierarchii interfejsu użytkownika elementu, w tym sam element.
resourceId
resourceIdRegex Wyrażenie regularne Java pasujące do resourceId .
contentDescription
contentDescriptionRegex Wyrażenie regularne Java pasujące do contentDescription .
text (który pojawia się na ekranie)
textRegex Wyrażenie regularne Java pasujące do text .
groupViewChildPosition , recyclerViewChildPosition lub adapterViewChildPosition Reprezentuje pozycję podrzędną widżetu interfejsu użytkownika w zależności od rodzaju widżetu nadrzędnego.

Często te atrybuty są niezdefiniowane, na przykład przycisk może nie mieć tekstu i opisu treści. Nawet jeśli niektóre wartości atrybutów są obecne, mogą nie być unikatowe na danym ekranie aplikacji (w tym resourceId ).

Na przykład rozróżnienie między elementami listy jest zwykle możliwe tylko przy użyciu ich różnych pozycji podrzędnych w ich widgecie nadrzędnym. Oznacza to, że użycie tylko jednego deskryptora elementu do identyfikacji widżetu interfejsu użytkownika jest zwykle niewystarczające. W związku z tym atrybut elementDescriptors akcji zawiera sekwencję deskryptorów elementów uporządkowanych w taki sposób, że pierwszy odpowiada docelowemu widżetowi interfejsu użytkownika, drugi odpowiada widżetowi nadrzędnemu docelowego widżetu interfejsu użytkownika itd. Docelowy widżet interfejsu użytkownika akcji jest dopasowany, gdy wszystkie jego deskryptory elementów pasują do odpowiedniej podhierarchii widżetu interfejsu użytkownika.

Poniżej znajduje się przykład skryptu Robo ze zmianą tekstu i kliknięciem, z których oba wymagają zidentyfikowania docelowego widżetu interfejsu użytkownika za pomocą dostarczonych deskryptorów elementów:

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

Opcje wykonania

Opcjonalnie możesz poprzedzić listę akcji w skrypcie Robo obiektem JSON, który określa opcje wykonania dla tego skryptu Robo. Ten nagłówek konfiguracji zaczyna się od słowa kluczowego roboscript , po którym następuje reprezentacja JSON żądanych opcji wykonania.

Skrypty Robo obsługują następujące opcje wykonania:

  • executionMode - opcje wykonania stosowane podczas działania skryptu Robo:
  • postscript - opcje wykonania zastosowane po wykonaniu skryptu Robo:
    • terminate — jeśli ustawiono na true , test Robo zatrzymuje indeksowanie po zakończeniu skryptu Robo.

Poniżej znajduje się przykład skryptu Robo wykonanego w trybie strict , który jest uśpiony przez trzy sekundy, po czym indeksowanie zostaje zatrzymane:

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

Parametry szablonu

Parametr szablonu to symbol zastępczy w skrypcie Robo, który jest zastępowany rzeczywistą wartością, gdy test Robo ładuje ten skrypt Robo do wykonania. Parametry szablonu są poprzedzone podwójnym podkreśleniem, po którym następuje znak procentu, i są poprzedzone znakiem procentu, po którym następuje podwójne podkreślenie.

Skrypty Robo obsługują następujący parametr szablonu:

  • __%APP_PACKAGE_NAME%__ — nazwa pakietu testowanej aplikacji.

Poniżej znajduje się przykład skryptu Robo, który zatrzymuje proces testowania aplikacji:

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

Uwagi

Skrypt Robo może zawierać linie komentarza, które zaczynają się od # lub // .

Poniżej znajduje się przykład skryptu Robo z kilkoma komentarzami:

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

Możliwości

Domyślnie, dopóki wszystkie działania skryptu Robo nie zostaną zakończone (lub przynajmniej podjęte), skrypt Robo pozostaje aktywny. Test Robo próbuje dopasować akcję skryptu Robo za każdym razem, gdy wybiera akcję do wykonania. Skrypt Robo wykorzystuje następujące techniki w celu zwiększenia niezawodności:

Technika Opis
Częściowe dopasowanie Jeśli nie można w pełni dopasować bieżącej akcji skryptu Robo, kryteria dopasowania zostaną złagodzone, a dopasowanie zostanie ponowione. Częściowe dopasowanie nie uwzględnia najbardziej zewnętrznego deskryptora elementu podczas dopasowywania docelowego widżetu interfejsu użytkownika akcji skryptu Robo.

Jeśli częściowe dopasowanie powiedzie się, odpowiednia akcja skryptu Robo jest wykonywana jak zwykle. Ta technika obsługuje scenariusze, w których struktura aplikacji zmienia się, na przykład między wersjami aplikacji, gdy elementy ekranu są zmieniane.

Pomiń bieżącą akcję Jeśli bieżąca akcja skryptu Robo nie może zostać w pełni lub częściowo dopasowana, Robo próbuje dopasować następną akcję skryptu Robo. Jeśli następna akcja jest całkowicie lub częściowo zgodna, test Robo pomija (i nigdy do niej nie powraca) bieżącą akcję skryptu Robo i wykonuje następną.

Ta technika obsługuje scenariusze, w których zachowanie aplikacji zmienia się między wersjami lub jest niestabilne, na przykład gdy sporadyczne okno dialogowe może pojawiać się na różnych ekranach podczas nagrywania i odtwarzania skryptu Robo.

Wstrzymać Jeśli ani bieżące, ani kolejne akcje skryptu Robo nie mogą zostać w pełni lub częściowo dopasowane, skrypt Robo zostaje tymczasowo zawieszony, a Robo test wybiera akcję do wykonania przy użyciu innych swoich strategii. Po zakończeniu tej akcji Robo test wznawia wykonywanie skryptu Robo.

Dopóki nie można dopasować bieżących lub kolejnych akcji skryptu Robo, skrypt Robo pozostaje zawieszony na dowolną liczbę akcji. W związku z tym skrypty Robo niekoniecznie muszą być prologiem do testu Robo, a akcje skryptu Robo można przeplatać ze standardowymi akcjami testowymi Robo. Ta technika obsługuje scenariusze, w których zachowanie aplikacji jest niestabilne lub gdy zmiany między wersjami aplikacji są na tyle duże, że test Robo musi „wypełnić luki” swoimi standardowymi działaniami.

Priorytety

Jeśli skrypt Robo osiągnie wartość maxNumberOfRuns , nie może już zostać uruchomiony w danym przeszukiwaniu. Jeśli bieżący kontekst może uruchomić więcej niż jeden skrypt Robo, pierwszeństwo ma wybór w następującej kolejności skryptu Robo, który:

  1. Ma atrybut contextDescriptor .
  2. Ma najwyższy priority (domyślnie wszystkie skrypty Robo mają ten sam priority wykonania 1 ).
  3. Pojawia się najwcześniej na liście skryptów Robo, jeśli priorytety skryptów Robo są takie same.

Poniżej znajduje się przykład pliku z trzema skryptami Robo, które wykonują tę samą akcję i są wyzwalane przez ten sam warunek — testowana aplikacja znajduje się na pierwszym planie:

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

Kiedy testowana aplikacja znajduje się na pierwszym planie, Robo uruchamia następujące czynności w podanej kolejności:

  1. "Robo script 2" , ponieważ ma najwyższy priorytet.
  2. "Robo script 1" , ponieważ pojawia się wcześniej wśród pozostałych odpowiednich skryptów Robo o takim samym priorytecie.
  3. "Robo script 3" jako ostatni odpowiedni skrypt Robo.

Powtarzające się biegi

Domyślnie Robo uruchamia skrypt Robo najwyżej raz podczas indeksowania. Można to dostosować za pomocą atrybutu maxNumberOfRuns .

Poniżej znajduje się przykład skryptu Robo, który przełącza testowaną aplikację w tło nawet 10 razy:

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

Etap czołgania się

Skrypty Robo mają zastosowanie na różnych etapach danego indeksowania Robo:

Etap czołgania się Opis
pre_crawl Zanim Robo uruchomi się i zacznie indeksować testowaną aplikację.
post_crawl Gdy Robo zakończy indeksowanie testowanej aplikacji.
crawl Główny etap indeksowania, podczas którego Robo indeksuje testowaną aplikację.
close_screen Kiedy Robo próbuje wrócić (wycofać się) z danego ekranu, kiedy zbadane są wszystkie możliwe działania na tym ekranie. Domyślnie Robo naciska, co jest niepożądane w niektórych scenariuszach.

Jeśli atrybut crawlStage skryptu Robo nie jest określony, zakłada się, że jest to crawl .

Poniżej znajduje się przykład skryptu Robo, który czyści dane użytkownika testowanej aplikacji, zanim Robo zacznie je indeksować:

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

Poniżej znajduje się przykład skryptu Robo, który instruuje Robo, aby kliknął "Cancel" za każdym razem, gdy próbuje wrócić (cofnąć się) z okna dialogowego potwierdzenia:

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

Akcje warunkowe

Skrypt Robo może zawierać akcje warunkowe. Akcje warunkowe mają trzy dodatkowe atrybuty, które opisują, w jaki sposób Robo je wykonuje:

Atrybut Opis
priority Priorytet tej akcji warunkowej w porównaniu z innymi akcjami warunkowymi w zawierającym ją skrypcie Robo. Domyślnie wszystkie akcje warunkowe mają priorytet 1 .
maxNumberOfRuns Ile razy można wykonać tę akcję warunkową podczas jednego wykonania zawierającego ją skryptu Robo. Domyślnie wszystkie akcje warunkowe można wykonać najwyżej raz w jednym wykonaniu zawierającego je skryptu Robo.
contextDescriptor Kontekst/warunek, który wyzwala to działanie warunkowe. Ma taką samą strukturę i oferuje podobne możliwości jak [deskryptor kontekstu skryptu Robo](#context-descriptor).

Po uruchomieniu skrypt Robo wykonuje swoje bezwarunkowe akcje jedna po drugiej w kolejności pojawiania się. Jeśli skrypt Robo zawiera akcje warunkowe, są one brane pod uwagę za każdym razem przed wybraniem akcji bezwarunkowej do wykonania. Jeśli jakakolwiek akcja warunkowa zostanie uruchomiona i wybrana na podstawie jej priorytetu i pozostałej liczby uruchomień, skrypt Robo wykona tę akcję warunkową. W przeciwnym razie skrypt Robo wykona następującą bezwarunkową akcję. Aby skrypt Robo był ważny, musi zawierać co najmniej jedną akcję bezwarunkową.

Poniżej znajduje się przykład bezwarunkowego skryptu Robo z akcją warunkową, która odrzuca wyskakujące okna dialogowe, jeśli pojawią się one w dowolnym momencie wykonywania skryptu 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
    }
}

Ignorowanie działań

Skrypt Robo może zawierać instrukcje dla Robo dotyczące ignorowania określonych widżetów interfejsu użytkownika lub wszystkich widżetów interfejsu użytkownika na określonym ekranie. Te instrukcje są reprezentowane jako ignorujące „akcje” z eventType ELEMENT_IGNORED i odpowiednio ALL_ELEMENTS_IGNORED .

Ilekroć atrybut contextDescriptor skryptu Robo zawierającego akcje ignorowania pasuje do danego ekranu, Robo nie wchodzi w interakcje z żadnymi widżetami interfejsu użytkownika, na które są skierowane jego akcje ignorowania (chyba że jakaś inna akcja skryptu Robo zmusza Robo do wykonania akcji na jednym z ignorowanych widżetów interfejsu użytkownika).

Skrypt Robo może zawierać kombinację działań ignorujących, warunkowych i bezwarunkowych. W przeciwieństwie do innych akcji skryptu Robo, akcje ignorowania są stosowane, o ile ich zawierający atrybut contextDescriptor skryptu Robo pasuje do ekranu podczas przeszukiwania Robo, niezależnie od wartości atrybutów priority i maxNumberOfRuns .

Poniżej znajduje się przykład pliku z dwoma skryptami Robo. Pierwszy skrypt Robo sprawia, że ​​Robo ignoruje wszystkie widżety interfejsu użytkownika na ekranie zawierającym widżet interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/ignored_screen" . Drugi skrypt Robo sprawia, że ​​Robo ignoruje widżety interfejsu użytkownika, których identyfikatory zasobów pasują do wyrażenia regularnego Java ".*:id/done" na ekranie zawierającym widżet interfejsu użytkownika o identyfikatorze zasobu "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"
          }
        ]
      }
    ]
  }
]

Obsługa RecyclerView i AdapterView

Elementy podrzędne widżetów RecyclerView i AdapterView są ładowane dynamicznie i mogą być wyświetlane wiele przeciągnięć od bieżącego ekranu. Ponieważ rozmiar ekranu i liczba przesunięć wymaganych do dotarcia do tego elementu podrzędnego jest różna dla różnych typów urządzeń, o wiele bardziej niezawodne jest poleganie na pozycji danych elementu podrzędnego, która jest bezwzględna. Mniej solidnym podejściem jest poleganie na liczbie przesunięć, które są wymagane, aby przenieść to dziecko na ekran, a następnie użyć jego pozycji na ekranie.

W związku z tym skrypt Robo przechwytuje bezwzględne pozycje danych elementów podrzędnych RecyclerView, które są obiektami docelowymi akcji skryptu Robo jako recyclerViewChildPosition . Skrypt Robo przechwytuje również bezwzględne pozycje danych elementów podrzędnych AdapterView, które są celem akcji skryptu Robo jako adapterViewChildPosition .

Akcje na elementach podrzędnych RecyclerView i AdapterView są wykonywane w następujących krokach:

  1. Test Robo zapewnia, że ​​odpowiednie dziecko jest wyświetlane na ekranie poprzez akcję pozycjonowania na jego zawierającym RecyclerView lub AdapterView.

  2. Test Robo wykonuje zarejestrowaną akcję bezpośrednio na elemencie potomnym, ponieważ jest on już wyświetlany na ekranie.

Poniżej znajduje się przykład akcji kliknięcia elementu podrzędnego 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
    }
  ]
}

Poniżej przedstawiono przykład akcji kliknięcia elementu podrzędnego 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
    }
  ]
}

Nagraj skrypt Robo w Android Studio i uruchom go w Test Lab

Możesz utworzyć skrypt Robo w Android Studio, który zapisuje skrypt jako plik JSON. Następnie możesz przesłać plik JSON do Firebase Test Lab wraz z aplikacją i odpowiednio uruchomić test.

Gdy uruchamiasz test Robo z dołączonym skryptem, Robo testuje pierwsze kroki przez wstępnie ustawione działania, a następnie eksploruje aplikację w zwykły sposób.

Aby utworzyć plik JSON skryptu Robo w Android Studio, wykonaj czynności opisane w temacie Rejestrowanie skryptu Robo za pomocą Test Lab w Android Studio .

Akcje skryptu Robo

Następujący wspólny atrybut opcjonalny ma zastosowanie do wszystkich działań:

  • description — pomaga śledzić wykonanie tej akcji skryptu Robo w wynikach testu Robo.

Twierdzenie

Jeśli potwierdzony warunek jest prawdziwy, skrypt Robo przechodzi do następnej akcji, którą może być kolejna asercja. W przeciwnym razie wykonanie skryptu Robo zostanie zatrzymane z powodu nieudanej asercji.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ASSERTION" --
contextDescriptor Opisuje potwierdzony kontekst lub warunek. Ma taką samą strukturę i oferuje podobne możliwości jak contextDescriptor skryptu Robo .

Poniżej znajduje się przykład asercji skryptu Robo, która sprawdza, czy testowana aplikacja znajduje się na pierwszym planie:

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

Poniżej znajduje się przykład asercji skryptu Robo, która sprawdza, czy na ekranie znajduje się widżet interfejsu użytkownika o identyfikatorze zasobu "com.google.samples.apps.topeka:id/done" :

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

Poniżej znajduje się przykład potwierdzenia skryptu Robo, który sprawdza, czy "Settings" NIE są wykrywane na ekranie za pomocą OCR:

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

Kliknij

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
eventType Określa typ akcji skryptu Robo.
"eventType": "VIEW_CLICKED" Klika element docelowy testowanej aplikacji.
"eventType": "SOFT_KEYBOARD_CLICK" Klika docelowy element klawiatury programowej.
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" Klika losowe elementy klawiatury programowej do maxNumberOfRuns razy.
"eventType": "LIST_ITEM_CLICKED" Używany przez rejestrator skryptów Robo w Android Studio do klikania elementów listy.
elementDescriptors Identyfikuje kliknięty widżet interfejsu użytkownika za pomocą hierarchii interfejsu użytkownika systemu Android. Wzajemnie wykluczające się z visionText .
visionText Identyfikuje kliknięty element za pomocą OCR. Wzajemnie wykluczające się z elementDescriptors .
maxNumberOfRuns Określa, ile razy należy kliknąć losowy element klawiatury programowej, gdy eventType jest SOFT_KEYBOARD_RANDOM_CLICK . Wartość domyślna to 1 .

Poniżej znajduje się przykład działania skryptu Robo, które polega na kliknięciu przycisku o identyfikatorze zasobu "com.google.samples.apps.topeka:id/done" :

{
  "eventType": "VIEW_CLICKED",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/done"
    }
  ]
}

Poniżej znajduje się przykład akcji skryptu Robo, która polega na kliknięciu "Privacy Policy" wykrytej na ekranie za pomocą funkcji OCR:

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

Poniżej znajduje się przykład akcji skryptu Robo, która klika element klawiatury programowej z opisem treści "Emoji button" :

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

Poniżej znajduje się przykład akcji skryptu Robo, która klika losowe elementy klawiatury programowej do pięciu razy:

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

Wyłącz klawiaturę programową

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "DISABLE_KEYBOARD" --

Poniżej znajduje się przykład akcji skryptu Robo, która wyłącza klawiaturę programową:

{
  "eventType": "DISABLE_KEYBOARD"
}

Wykonaj polecenie powłoki adb

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ADB_SHELL_COMMAND" --
command Polecenie powłoki Android Debug Bridge (adb) do wykonania.

Poniżej znajduje się przykład akcji skryptu Robo, która czyści dane użytkownika testowanej aplikacji:

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

Przyznaj uprawnienia

To działanie jest rejestrowane przez rejestrator skryptów Robo w Android Studio w celu zapewnienia wstecznej zgodności z Espresso Test Recorder . Robo test przyznaje wszystkie uprawnienia testowanej aplikacji na początku każdego indeksowania, dlatego ta czynność jest niewykonalna. NIE używaj tej akcji w swoich skryptach Robo.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "PERMISSIONS_REQUEST" --

Ignoruj ​​wszystkie elementy na ekranie

Ta akcja powoduje, że Robo ignoruje wszystkie elementy na każdym ekranie, który uruchamia zawierający skrypt Robo.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ALL_ELEMENTS_IGNORED" --

Poniżej znajduje się przykład akcji skryptu Robo, która sprawia, że ​​Robo ignoruje wszystkie elementy na ekranie:

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

Ignoruj ​​element

To działanie powoduje, że Robo ignoruje element (lub elementy), które pasują do określonego elementDescriptors .

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Identyfikuje ignorowane widżety interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.

Poniżej znajduje się przykład akcji skryptu Robo, która sprawia, że ​​Robo ignoruje wszystkie elementy, których opisy zawartości zaczynają się od "Avatar" :

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

Wprowadź tekst

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
eventType Określa typ akcji skryptu Robo.
"eventType": "VIEW_TEXT_CHANGED" Wprowadza podany tekst do docelowego widżetu interfejsu użytkownika.
"eventType": "ENTER_TEXT" wprowadza podany tekst do docelowego widżetu interfejsu użytkownika, a następnie wysyła zdarzenie KEYCODE_ENTER do tego widżetu interfejsu użytkownika.
elementDescriptors Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.
replacementText Tekst do wprowadzenia w docelowym widżecie interfejsu użytkownika.

Poniżej znajduje się przykład akcji skryptu Robo, która wprowadza "John" do widżetu interfejsu użytkownika z identyfikatorem zasobu "com.google.samples.apps.topeka:id/first_name" :

{
  "eventType": "VIEW_TEXT_CHANGED",
  "replacementText": "John",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

Długie kliknięcie

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.

Następujący atrybut jest opcjonalny:

  • delayTime - określa, jak długo trwa naciśnięcie długiego kliknięcia w milisekundach.

Poniżej przedstawiono przykład działania skryptu Robo, który wykonuje pięciosekundowe kliknięcie widżetu interfejsu użytkownika z opisem treści "Avatar 8" :

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

Wykonaj jednopunktowy gest

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ONE_POINT_GESTURE" --
coordinates Dwie współrzędne dla gestu jednopunktowego, sformatowane jako „(x1,y1)->(x2,y2)” jako wartości procentowe lub piksele.

Następujący atrybut jest opcjonalny:

  • dragAndDrop — jeśli jest ustawiona na true , gest jednopunktowy wykonuje akcję przeciągania i upuszczania. Domyślnie jest to false .

Poniżej znajduje się przykład jednopunktowego gestu skryptu Robo, który wykonuje przesunięcie w dół:

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

Wykonaj dwupunktowy gest

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "TWO_POINT_GESTURE" --
coordinates Cztery współrzędne gestu dwupunktowego, sformatowane jako „(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)” jako wartości procentowe lub piksele.

Poniżej znajduje się przykład akcji skryptu Robo, która wykonuje gest uszczypnięcia:

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

Wykonaj czynność IME

Ta akcja powoduje naciśnięcie przycisku bieżącej akcji, na przykład dalej, gotowe i wyszukaj, w edytorze metod wprowadzania (IME) dla określonego docelowego widżetu interfejsu użytkownika.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.

Poniżej przedstawiono przykład działania skryptu Robo, który wykonuje działanie edytora IME na widżecie interfejsu użytkownika o identyfikatorze zasobu "com.google.samples.apps.topeka:id/first_name" :

{
  "eventType": "PRESSED_EDITOR_ACTION",
  "elementDescriptors": [
    {
      "resourceId": "com.google.samples.apps.topeka:id/first_name"
    }
  ]
}

Naciśnij wstecz

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
eventType Określa typ akcji skryptu Robo.
"eventType": "PRESSED_BACK" Wysyła zdarzenie KEYCODE_BACK do urządzenia.
"eventType": "PRESSED_BACK_EMULATOR_28" Używany przez rejestrator skryptów Robo w Android Studio do naciskania wstecz na emulatory API 28.

Poniżej znajduje się przykład akcji skryptu Robo, która naciska wstecz:

{
  "eventType": "PRESSED_BACK"
}

Naciśnij do domu

Ta akcja wysyła do urządzenia zdarzenie KEYCODE_HOME .

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "GO_HOME" --

Poniżej znajduje się przykład akcji skryptu Robo, która naciska przycisk home:

{
  "eventType": "GO_HOME"
}

Przewiń element do widoku

To działanie powoduje, że Robo test przewinie do przodu widżet interfejsu użytkownika pasujący do określonych elementDescriptors , dopóki widżet interfejsu użytkownika pasujący do określonych childElementDescriptors nie pojawi się na ekranie lub nie będzie można przewijać przewijanego widżetu lub zostanie osiągnięta maksymalna liczba 50 przewinięć.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Identyfikuje przewijany widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.
childElementDescriptors Identyfikuje widżet interfejsu użytkownika, do którego można przewijać przy użyciu hierarchii interfejsu użytkownika systemu Android.

Poniżej znajduje się przykład akcji skryptu Robo, która przewija widżet interfejsu użytkownika o identyfikatorze zasobu "my.app.package:id/scrollable_card_container" do momentu pojawienia się na ekranie widżetu interfejsu użytkownika z tekstem "Orange" (lub nie można już więcej przewijać zostać wykonane lub osiągnięta zostanie maksymalna liczba 50 zwojów):

{
  "eventType": "ELEMENT_SCROLL_INTO_VIEW",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/scrollable_card_container"
    }
  ],
  "childElementDescriptors": [
    {
      "text": "Orange"
    }
  ]
}

Trzepnąć

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "VIEW_SWIPED" --
swipeDirection Określa kierunek przesunięcia:
  • Left
  • Right
  • Up
  • Down
  • Forward — w Down lub Right , w zależności od możliwości przewijania w pionie lub poziomie docelowego widżetu interfejsu użytkownika.
  • BackwardUp lub Left , w zależności od możliwości przewijania w pionie lub poziomie docelowego widżetu interfejsu użytkownika.
elementDescriptors Identyfikuje docelowy widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.

Poniżej znajduje się przykład akcji skryptu Robo, która przesuwa w górę widżet interfejsu użytkownika o identyfikatorze zasobu "my.app.package:id/custom_content" :

{
  "eventType": "VIEW_SWIPED",
  "swipeDirection": "Up",
  "elementDescriptors": [
    {
      "resourceId": "my.app.package:id/custom_content"
    }
  ]
}

Zrobić zrzut ekranu

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "TAKE_SCREENSHOT" --
screenshotName Określa nazwę pliku zrzutu ekranu.

Poniżej znajduje się przykład akcji skryptu Robo, która wykonuje zrzut ekranu:

{
  "eventType": "TAKE_SCREENSHOT",
  "screenshotName": "my_screenshot"
}

Dotknij punktu na ekranie

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "POINT_TAP" --
pointTapXCoordinate Współrzędna X piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent .
pointTapYCoordinate Współrzędna Y piksela stukniętego punktu. Wzajemnie wykluczające się z pointTapXPercent i pointTapYPercent .
pointTapXPercent Współrzędna procentowa X punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate .
pointTapYPercent Współrzędna procentowa Y punktu stuknięcia. Wzajemnie wykluczające się z pointTapXCoordinate i pointTapYCoordinate .

Poniżej znajduje się przykład akcji skryptu Robo, która dotyka środka ekranu:

{
  "eventType": "POINT_TAP",
  "pointTapXPercent": 50,
  "pointTapYPercent": 50
}

Dotknij punktu w elemencie

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent Współrzędna procentowa X w elemencie docelowym.
pointTapYPercent Współrzędna procentowa Y w elemencie docelowym.
elementDescriptors Identyfikuje docelowy widżet interfejsu użytkownika za pomocą hierarchii interfejsu użytkownika systemu Android.

Poniżej znajduje się przykład akcji skryptu Robo, która przesuwa suwak paska wyszukiwania w prawo:

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

Zakończ indeksowanie

Ta czynność zatrzymuje test Robo.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "TERMINATE_CRAWL" --

Poniżej znajduje się przykład akcji skryptu Robo, która zatrzymuje test Robo:

{
  "eventType": "TERMINATE_CRAWL"
}

Czekać

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime Określa czas oczekiwania w milisekundach.

Poniżej znajduje się przykład akcji skryptu Robo, która czeka przez trzy sekundy:

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

Poczekaj na element

Ta akcja powoduje, że Robo test czeka na pojawienie się elementu na ekranie do określonego limitu czasu.

W poniższej tabeli wymieniono wymagane atrybuty:

Atrybut Opis
"eventType": "WAIT_FOR_ELEMENT" --
delayTime Określa limit czasu oczekiwania w milisekundach.
elementDescriptors Identyfikuje oczekiwany widżet interfejsu użytkownika przy użyciu hierarchii interfejsu użytkownika systemu Android.

Poniżej przedstawiono przykład akcji skryptu Robo, która czeka do 30 sekund na pojawienie się na ekranie widżetu interfejsu użytkownika z identyfikatorem zasobu "my.app.package:id/confirmation_button" :

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

Następne kroki