Ce document fournit des informations de référence sur les scripts Robo, y compris leur structure, leurs fonctionnalités, leur utilisation, leur enregistrement et leurs actions. Les scripts Robo sont des tests qui automatisent les tâches manuelles d'assurance qualité pour les applications mobiles, et permettent l'intégration continue et les stratégies de test pré-lancement. Un script Robo est un fichier JSON qui décrit une séquence d'actions de l'interface utilisateur (UI) et d'autres actions.
Vous pouvez créer un script Robo de différentes manières :
Utilisez la fonctionnalité d'enregistrement de script Robo. (Android uniquement)
Créez le script Robo manuellement. (Android et iOS+)
Enregistrez le script Robo, puis modifiez-le manuellement. (Android uniquement)
Pour en savoir plus sur l'utilisation des scripts Robo, consultez Exécuter un script Robo.
Introduction
Le script Robo est fourni au test Robo avec d'autres entrées, telles que l'APK (Android Application Package) de l'application testée.
Voici un exemple de script Robo qui connecte un utilisateur à une application, déclenché au lancement de l'application testée :
[
{
"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"
}
]
}
]
}
]
S'il n'y a qu'un seul script Robo dans un fichier et qu'il comporte la condition de déclenchement app_under_test_shown par défaut, comme dans l'exemple ci-dessus, vous pouvez spécifier le script Robo dans un fichier en utilisant un format plus simple, comme une séquence de ses 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"
}
]
}
]
Compatibilité iOS+ pour les scripts Robo
Robo pour iOS+ (bêta) offre une compatibilité limitée avec les scripts Robo. La syntaxe du script Robo pour iOS+ est identique à celle d'Android, et les fonctionnalités iOS+ compatibles se comportent de la même manière que leurs équivalents Android.
Les actions suivantes sont acceptées dans iOS+ :
- Assertion
- Cliquez sur
- Clic long
- Glissé
- Ignorer tous les éléments
- Attente
- Faire une capture d'écran
- Arrêter l'exploration
Les attributs d'identification suivants dans les descripteurs d'éléments sont compatibles avec iOS+ :
- Nom de la classe
- Nom de la classe ancêtre
- Description du contenu (et expression régulière)
- Texte (et expression régulière)
Les conditions de déclenchement suivantes dans les descripteurs de contexte sont compatibles avec iOS+ :
- Application testée affichée
- Élément présent
- Action de script non-Robo effectuée
Structure
Un script Robo possède plusieurs attributs qui décrivent comment Robo l'exécute. La plupart de ces attributs sont facultatifs et ont des valeurs par défaut prédéfinies :
| Attribut | Description |
id
|
Nombre entier qui permet de suivre ce script Robo dans les résultats d'exploration.
Robo intègre des scripts Robo avec leurs propres id. Bien que l'utilisation du même id dans différents scripts Robo n'affecte pas leur comportement, il peut être difficile de distinguer les actions de ces scripts Robo dans les résultats d'exploration. Nous vous recommandons d'attribuer un id unique de 1000 ou plus à vos scripts Robo pour éviter tout conflit.
|
description
|
Semblable à id, mais plus descriptif.
|
crawlStage
|
Étape d'une exploration Robo à laquelle Robo applique ce script Robo. Par défaut, il s'agit de l'étape d'exploration principale. |
priority
|
Priorité de ce script Robo par rapport aux autres scripts Robo.
Par défaut, tous les scripts Robo ont une priorité de 1.
|
maxNumberOfRuns
|
Spécifie le nombre de fois que Robo peut exécuter ce script Robo lors d'une exploration. Par défaut, Robo peut exécuter un script Robo une fois. |
contextDescriptor
|
Décrit le contexte ou la condition qui déclenche ce script Robo. Si elle est omise, la condition de déclenchement de ce script Robo est considérée comme toujours remplie. En d'autres termes, le script Robo est inconditionnel. |
actions
|
Toutes les actions de ce script Robo. |
Un seul fichier contient une collection d'un ou de plusieurs scripts Robo.
Voici un exemple de fichier contenant deux scripts Robo inconditionnels, chacun avec une seule action exécutée une fois au début d'une exploration :
[
{
"id": 1000,
"description": "My first Robo script",
"actions": [
{
"eventType": "DISABLE_KEYBOARD"
}
]
},
{
"id": 1001,
"description": "My second Robo script",
"actions": [
{
"eventType": "PRESSED_BACK"
}
]
}
]
Descripteur de contexte
Un descripteur de contexte définit le contexte ou la condition qui déclenche un script Robo à l'aide d'un ou de plusieurs attributs :
| Attribut | Description |
|---|---|
"condition": "always"
|
Déclenche toujours un script Robo. |
"condition": "element_present"
|
Vérifie qu'un widget d'interface utilisateur correspondant à elementDescriptors ou au texte spécifié par visionText est présent à l'écran.
|
"condition": "element_disabled"
|
Vérifie qu'un widget d'interface utilisateur correspondant à elementDescriptors est présent à l'écran et qu'il n'est pas possible d'interagir avec lui.
|
"condition": "element_checked"
|
Vérifie qu'un widget d'interface utilisateur correspondant à elementDescriptors est présent à l'écran et est coché.
|
"condition": "app_under_test_shown"
|
Vérifie que l'application testée s'exécute au premier plan. |
"condition": "default_launcher_shown"
|
Vérifie que l'écran d'accueil d'un appareil est affiché, ce qui signifie qu'aucune application n'est exécutée au premier plan. |
"condition": "non_roboscript_action_performed"
|
Vérifie que les nonRoboscriptActionCount dernières actions consécutives effectuées par le test Robo ne sont pas des actions de script Robo.
|
negateCondition
|
Si la valeur est définie sur true, elle annule condition. Par exemple, vous pouvez utiliser cet attribut pour vérifier qu'un widget d'interface utilisateur n'est PAS présent à l'écran ou que l'application testée n'est PAS exécutée au premier plan.
|
elementDescriptors
|
Un ou plusieurs descripteurs d'éléments qui identifient un widget d'interface utilisateur à l'écran.
Il est utilisé en combinaison avec les conditions element_present, element_disabled et element_checked. Incompatible avec visionText. Pour en savoir plus, consultez Descripteurs d'éléments.
|
visionText
|
Le texte à l'écran est détecté à l'aide de l'API de reconnaissance optique des caractères (OCR). visionText est utilisé en combinaison avec la condition element_present. Incompatible avec elementDescriptors.
|
nonRoboscriptActionCount
|
Nombre d'actions consécutives n'appartenant pas au script Robo effectuées précédemment. Il est utilisé en combinaison avec la condition non_roboscript_action_performed pour déclencher un script Robo après chaque action Robo nonRoboscriptActionCount. Par défaut, cette valeur est de 1.
|
Voici un exemple de script Robo déclenché par un widget d'interface utilisateur avec un ID de ressource "my.app.package:id/page_header" présent à l'écran :
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/page_header"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Settings"
}
]
}
]
}
Voici un exemple de script Robo déclenché par "Privacy Policy" détecté par reconnaissance optique des caractères (OCR) :
{
"id": 1000,
"description": "Vision text Robo script",
"contextDescriptor": {
"condition": "element_present",
"visionText": "Privacy Policy"
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
]
}
Voici un exemple de script Robo qui attend cinq secondes après chaque action Robo non scriptée :
{
"contextDescriptor": {
"condition": "non_roboscript_action_performed"
},
"maxNumberOfRuns" : 1000,
"actions" : [
{
"eventType" : "WAIT",
"delayTime" : 5000
}]
}
Actions
Chaque action d'un script Robo est représentée par un ensemble d'une ou de plusieurs paires attribut-valeur, décrites dans le tableau suivant :
| Attribut | Description |
eventType
|
Spécifie le type d'action, par exemple, clic, modification de texte, etc. Obligatoire pour chaque action. |
elementDescriptors
|
Descripteurs qui identifient un widget d'interface utilisateur. Obligatoire pour toutes les actions qui ont un widget d'interface utilisateur cible, comme cliquer sur un bouton particulier. |
optional
|
Si la valeur est définie sur true, cette action est ignorée lorsqu'elle ne peut pas être effectuée. Par exemple, cette action est ignorée lorsqu'elle ne trouve pas son widget d'interface utilisateur cible sur un écran, sans que le script Robo contenant l'action échoue. La valeur par défaut est false.
|
replacementText
|
Texte à saisir dans le widget d'interface utilisateur cible. Obligatoire pour les actions de modification de texte. |
swipeDirection
|
Spécifie la direction du balayage. Obligatoire pour les actions de balayage. |
delayTime
|
Spécifie le temps d'attente, en millisecondes. Obligatoire pour les actions d'attente. |
pointTapXCoordinate et pointTapYCoordinate
|
Coordonnées X et Y en pixels du point sélectionné. S'exclut mutuellement avec pointTapXPercent et pointTapYPercent.
Obligatoire pour les actions d'appui sur un point.
|
pointTapXPercent et pointTapYPercent
|
Coordonnées X et Y en pourcentage du point sur lequel l'utilisateur a appuyé. Incompatible avec pointTapXCoordinate et pointTapYCoordinate. Obligatoire pour les actions d'appui sur un point.
|
Voici un exemple de script Robo comportant deux actions sans widgets d'interface utilisateur cibles, ce qui signifie que ces actions ne s'appliquent pas à un widget d'interface utilisateur spécifique :
[
{
"eventType": "WAIT",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
Descripteurs d'éléments
Un descripteur d'élément identifie un widget d'interface utilisateur à l'aide d'un ou de plusieurs des attributs d'identification suivants :
| Attribut | Description |
className
|
– |
ancestorClassName
|
Nom de classe de l'ancêtre de la hiérarchie de l'interface utilisateur de l'élément. Un ancêtre est l'un des nœuds parents de la hiérarchie de l'UI de l'élément, y compris l'élément lui-même. |
resourceId
|
– |
resourceIdRegex
|
Expression régulière Java correspondant à resourceId.
|
contentDescription
|
– |
contentDescriptionRegex
|
Expression régulière Java correspondant à contentDescription.
|
text (qui s'affiche à l'écran)
|
– |
textRegex
|
Expression régulière Java correspondant à text.
|
groupViewChildPosition, recyclerViewChildPosition ou adapterViewChildPosition
|
Représente la position enfant d'un widget d'interface utilisateur en fonction du type de son widget parent. |
Ces attributs ne sont souvent pas définis. Par exemple, un bouton peut ne pas avoir de texte ni de description de contenu. Même si certaines valeurs d'attribut sont présentes, elles peuvent ne pas être uniques sur un écran d'application donné (y compris resourceId).
Par exemple, la différenciation entre les éléments d'une liste n'est généralement possible qu'en utilisant leurs différentes positions enfants dans leur widget parent. Cela signifie qu'il ne suffit généralement pas d'utiliser un seul descripteur d'élément pour identifier un widget d'interface utilisateur. Par conséquent, l'attribut elementDescriptors d'une action contient une séquence de descripteurs d'éléments ordonnés de sorte que le premier corresponde au widget d'interface utilisateur cible, le deuxième au widget parent du widget d'interface utilisateur cible, et ainsi de suite. Le widget d'interface utilisateur cible d'une action est mis en correspondance lorsque tous ses descripteurs d'éléments correspondent à la sous-hiérarchie du widget d'interface utilisateur correspondante.
Voici un exemple de script Robo avec une modification de texte et des actions de clic, qui nécessitent toutes deux d'identifier le widget d'interface utilisateur cible à l'aide des descripteurs d'éléments fournis :
[
{
"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"
}
]
}
]
Options d'exécution
Vous pouvez éventuellement ajouter un préfixe à la liste des actions d'un script Robo avec un objet JSON qui spécifie les options d'exécution de ce script Robo. Cet en-tête de configuration commence par le mot clé roboscript, suivi d'une représentation JSON des options d'exécution souhaitées.
Les scripts Robo sont compatibles avec les options d'exécution suivantes :
executionMode: options d'exécution appliquées lors de l'exécution d'un script Robo :strict: si la valeur est définie surtrue, le script Robo n'utilise pas la correspondance partielle, l'omission de l'action actuelle ni la suspension. En d'autres termes, le script Robo est exécuté comme un test d'instrumentation standard et échoue dès qu'une de ses actions ne peut pas être effectuée. Par défaut, il s'agit defalse.dismiss_popups: si la valeur est définie surtrue, le test Robo ignore toutes les boîtes de dialogue inattendues lors de l'exécution du script Robo, même en modestrict. Cette option n'a aucun effet lorsque vous n'êtes pas en modestrict. Par défaut, cette valeur est defalse.notify: si la valeur est définie surfalse, le script Robo n'affiche pas de notifications à l'écran au début et à la fin de son exécution. Par défaut, il s'agit detrue.
postscript: options d'exécution appliquées après l'exécution d'un script Robo :terminate: si la valeur est définie surtrue, le test Robo arrête l'exploration une fois le script Robo terminé. Par défaut, il s'agit defalse.
Voici un exemple de script Robo exécuté en mode strict sans notifications à l'écran, qui attend trois secondes avant d'arrêter l'exploration :
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "WAIT",
"delayTime": 3000
}
]
Paramètres de modèle
Un paramètre de modèle est un espace réservé dans un script Robo qui est remplacé par la valeur réelle lorsque le test Robo charge ce script Robo pour l'exécuter. Les paramètres de modèle sont précédés d'un double trait de soulignement suivi d'un signe de pourcentage, et sont suivis d'un signe de pourcentage suivi d'un double trait de soulignement.
Les scripts Robo sont compatibles avec le paramètre de modèle suivant :
__%APP_PACKAGE_NAME%__: nom du package de l'application testée.
Voici un exemple de script Robo qui arrête le processus de l'application testée :
[
{
"eventType": "ADB_SHELL_COMMAND",
"command": "am force-stop __%APP_PACKAGE_NAME%__"
}
]
Commentaires
Un script Robo peut contenir des lignes de commentaire, qui commencent par # ou //.
Voici un exemple de script Robo avec quelques commentaires :
# Confirm a user account.
[
{
// Click the DONE button.
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
]
Capacités
Par défaut, le script Robo reste actif jusqu'à ce que toutes ses actions soient terminées (ou du moins tentées). Le test Robo essaie de faire correspondre une action de script Robo chaque fois qu'il choisit une action à effectuer. Le script Robo utilise les techniques suivantes pour améliorer la stabilité :
| Technique | Description |
| Correspondance partielle | Si l'action de script Robo actuelle ne peut pas être entièrement mise en correspondance, les critères de correspondance sont assouplis et la mise en correspondance est relancée. La correspondance partielle ne tient pas compte du descripteur d'élément le plus externe lors de la mise en correspondance du widget d'interface utilisateur cible d'une action de script Robo.
Si la correspondance partielle réussit, l'action de script Robo correspondante est effectuée comme d'habitude. Cette technique est compatible avec les scénarios dans lesquels la structure de l'application change, par exemple entre les versions de l'application, lorsque les éléments de l'écran sont réorganisés. |
| Ignorer l'action actuelle | Si l'action actuelle du script Robo ne peut pas être entièrement ou partiellement mise en correspondance, Robo tente de mettre en correspondance l'action suivante du script Robo. Si l'action suivante correspond entièrement ou partiellement, le test Robo ignore l'action actuelle du script Robo (et n'y revient jamais) et effectue l'action suivante.
Cette technique est compatible avec les scénarios dans lesquels le comportement de l'application change d'une version à l'autre ou est instable, par exemple lorsqu'une boîte de dialogue intermittente peut apparaître sur différents écrans lors de l'enregistrement ou de la lecture d'un script Robo. |
| Suspendre | Si aucune action de script Robo actuelle ou ultérieure ne peut être mise en correspondance, totalement ou partiellement, le script Robo est temporairement suspendu et le test Robo choisit une action à effectuer à l'aide de ses autres stratégies. Une fois cette action terminée, le test Robo reprend l'exécution du script Robo.
Tant que les actions de script Robo actuelles ou ultérieures ne peuvent pas être mises en correspondance, le script Robo reste suspendu pour un nombre quelconque d'actions. Par conséquent, les scripts Robo ne doivent pas nécessairement être un prologue pour un test Robo, et vous pouvez intercaler des actions de script Robo avec des actions de test Robo standards. Cette technique est compatible avec les scénarios dans lesquels le comportement de l'application est instable ou lorsque les modifications entre les versions de l'application sont suffisamment importantes pour que le test Robo doive "combler les lacunes" avec ses actions standards. |
Priorités
Si un script Robo atteint sa maxNumberOfRuns, il ne peut plus être déclenché lors d'une exploration donnée. Si plusieurs scripts Robo peuvent être déclenchés par le contexte actuel, la priorité est accordée en choisissant, dans l'ordre suivant, le script Robo qui :
- Comporte un attribut
contextDescriptor. - Il présente la
priorityla plus élevée (par défaut, tous les scripts Robo ont la mêmepriorityd'exécution de1). - Il apparaît en premier dans la liste des scripts Robo, si les priorités des scripts Robo sont identiques.
Voici un exemple de fichier contenant trois scripts Robo qui effectuent la même action et sont déclenchés par la même condition : l'application testée est au premier plan.
[
{
"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
}
]
}
]
Lorsque l'application testée est au premier plan, Robo déclenche les actions suivantes, dans l'ordre :
"Robo script 2", car il a la priorité la plus élevée."Robo script 1", car il apparaît plus tôt parmi les scripts Robo applicables restants ayant la même priorité."Robo script 3"comme dernier script Robo applicable.
Exécutions répétées
Par défaut, Robo déclenche un script Robo au maximum une fois lors d'une exploration. Vous pouvez ajuster ce paramètre via l'attribut maxNumberOfRuns.
Voici un exemple de script Robo qui place l'application testée en arrière-plan jusqu'à 10 fois :
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Étape d'exploration
Les scripts Robo sont applicables à différentes étapes d'une exploration Robo donnée :
| Étape d'exploration | Description |
pre_crawl
|
Avant que Robo ne lance et ne commence à explorer l'application testée. |
post_crawl
|
Une fois que Robo a terminé l'exploration de l'application testée. La durée d'un script Robo post_crawl ne doit pas dépasser 15 secondes, sinon l'exploration peut se terminer par un délai avant expiration.
|
crawl
|
Étape d'exploration principale, au cours de laquelle Robo explore l'application testée. |
close_screen
|
Lorsque Robo tente de revenir en arrière (backtrack) à partir d'un écran donné, une fois que toutes les actions possibles sur cet écran ont été explorées. Par défaut, Robo appuie sur le bouton de retour, ce qui n'est pas souhaitable dans certains scénarios. |
Si l'attribut crawlStage d'un script Robo n'est pas spécifié, il est implicitement défini sur crawl.
Voici un exemple de script Robo qui efface les données utilisateur de l'application testée avant que Robo ne commence à l'explorer :
{
"id": 1000,
"crawlStage": "pre_crawl",
"actions": [
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
]
}
Voici un exemple de script Robo qui indique à Robo de cliquer sur "Cancel" chaque fois qu'il tente de revenir en arrière (backtrack) à partir d'une boîte de dialogue de confirmation :
{
"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"
}
]
}
]
}
Actions conditionnelles
Un script Robo peut contenir des actions conditionnelles. Les actions conditionnelles comportent trois attributs supplémentaires qui décrivent comment Robo les exécute :
| Attribut | Description |
priority
|
Priorité de cette action conditionnelle par rapport aux autres actions conditionnelles du script Robo qui la contient. Par défaut, toutes les actions conditionnelles ont une priorité de 1.
|
maxNumberOfRuns
|
Nombre de fois que cette action conditionnelle peut être effectuée lors d'une exécution du script Robo qui la contient. Par défaut, toutes les actions conditionnelles peuvent être effectuées au maximum une fois lors d'une même exécution du script Robo qui les contient. |
contextDescriptor
|
Contexte/Condition qui déclenche cette action conditionnelle. Il présente la même structure et offre des fonctionnalités similaires à celles du contextDescriptor du script Robo. |
Lorsqu'il est déclenché, un script Robo effectue ses actions non conditionnelles une par une, dans l'ordre d'apparition. Si un script Robo contient des actions conditionnelles, elles sont prises en compte chaque fois avant de choisir une action non conditionnelle à effectuer. Si une action conditionnelle est déclenchée et sélectionnée en fonction de sa priorité et du nombre d'exécutions restantes, le script Robo l'exécute. Sinon, le script Robo effectue l'action non conditionnelle suivante. Pour être valide, un script Robo doit contenir au moins une action non conditionnelle.
Voici un exemple de script Robo inconditionnel avec une action conditionnelle qui ferme les boîtes de dialogue pop-up si elles s'affichent à un moment donné pendant l'exécution du script 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
}
}
Ignorer des actions
Un script Robo peut contenir des instructions permettant à Robo d'ignorer des widgets d'interface utilisateur spécifiques ou tous les widgets d'interface utilisateur d'un écran particulier. Ces instructions sont représentées comme ignorant les "actions" avec eventType, ELEMENT_IGNORED et ALL_ELEMENTS_IGNORED, respectivement.
Chaque fois que l'attribut contextDescriptor d'un script Robo contenant des actions d'ignorance correspond à un écran donné, Robo n'interagit avec aucun widget d'interface utilisateur ciblé par ses actions d'ignorance (sauf si une autre action de script Robo amène Robo à effectuer une action sur l'un des widgets d'interface utilisateur ignorés).
Un script Robo peut contenir un mélange d'actions d'ignorance, conditionnelles et non conditionnelles. Contrairement aux autres actions de script Robo, les actions d'ignorance sont appliquées tant que l'élément contextDescriptor du script Robo qui les contient correspond à un écran lors d'une exploration Robo, quelles que soient les valeurs des attributs priority et maxNumberOfRuns.
Voici un exemple de fichier contenant deux scripts Robo. Le premier script Robo fait en sorte que Robo ignore tous les widgets d'interface utilisateur sur un écran contenant un widget d'interface utilisateur avec l'ID de ressource "my.app.package:id/ignored_screen". Le deuxième script Robo fait en sorte que Robo ignore les widgets d'interface utilisateur dont les ID de ressource correspondent à l'expression régulière Java ".*:id/done" sur un écran contenant un widget d'interface utilisateur avec un ID de ressource "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"
}
]
}
]
}
]
Compatibilité avec RecyclerView et AdapterView
Les enfants des widgets RecyclerView et AdapterView sont chargés de manière dynamique et peuvent être affichés à plusieurs balayages de l'écran actuel. Étant donné que la taille d'un écran et le nombre de balayages nécessaires pour accéder à cet enfant sont différents selon les facteurs de forme de l'appareil, il est beaucoup plus fiable de s'appuyer sur la position des données de l'enfant, qui est absolue. Il est moins fiable de se fier au nombre de balayages nécessaires pour afficher cet enfant à l'écran, puis d'utiliser sa position à l'écran.
Par conséquent, le script Robo capture les positions absolues des données des enfants RecyclerView qui sont des cibles d'actions de script Robo en tant que recyclerViewChildPosition. Le script Robo capture également les positions absolues des données des enfants AdapterView qui sont les cibles des actions du script Robo en tant que adapterViewChildPosition.
Les actions sur les enfants RecyclerView et AdapterView sont effectuées en procédant comme suit :
Le test Robo s'assure que l'enfant correspondant s'affiche à l'écran via une action de positionnement sur le RecyclerView ou l'AdapterView qui le contient.
Le test Robo effectue l'action enregistrée directement sur l'élément enfant, car il est déjà affiché à l'écran.
Voici un exemple d'action de clic sur un enfant 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
}
]
}
Voici un exemple d'action de clic sur un enfant 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
}
]
}
Enregistrer un script Robo dans Android Studio et l'exécuter dans Test Lab
Vous pouvez créer un script Robo dans Android Studio, qui l'enregistre sous forme de fichier JSON. Vous pouvez ensuite importer le fichier JSON dans Firebase Test Lab avec l'application et exécuter le test en conséquence.
Lorsque vous exécutez un test Robo avec un script associé, le test Robo commence par exécuter les actions pré-scénarisées, puis explore l'application comme d'habitude.
Pour créer un fichier JSON de script Robo dans Android Studio, suivez les étapes de la section Enregistrer un script Robo à l'aide de Test Lab dans Android Studio.
Actions du script Robo
L'attribut facultatif commun suivant s'applique à toutes les actions :
description: permet de suivre l'exécution de cette action de script Robo dans les résultats du test Robo.
Assertion
Si la condition déclarée est vraie, le script Robo passe à l'action suivante, qui peut être une autre assertion. Sinon, l'exécution du script Robo est interrompue en raison d'un échec d'assertion.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "ASSERTION"
|
-- |
contextDescriptor
|
Décrit le contexte ou la condition déclarés. Il présente la même structure et offre des fonctionnalités similaires à celles de contextDescriptor du script Robo. |
Voici un exemple d'assertion de script Robo qui vérifie que l'application testée est au premier plan :
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Voici un exemple d'assertion de script Robo qui vérifie qu'un widget d'interface utilisateur avec l'ID de ressource "com.google.samples.apps.topeka:id/done" est présent sur un écran :
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
Voici un exemple d'assertion de script Robo qui vérifie que "Settings" n'est PAS détecté sur un écran à l'aide de l'OCR :
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"negateCondition": true,
"visionText": "Settings"
}
}
Cliquez sur
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
eventType
|
Spécifie le type d'action du script Robo. |
"eventType": "VIEW_CLICKED"
|
Clique sur l'élément cible de l'application testée. |
"eventType": "SOFT_KEYBOARD_CLICK"
|
Clique sur l'élément cible du clavier virtuel. |
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK"
|
Clique sur des éléments aléatoires du clavier virtuel jusqu'à maxNumberOfRuns fois.
|
"eventType": "LIST_ITEM_CLICKED"
|
Utilisé par l'enregistreur de scripts Robo dans Android Studio pour cliquer sur des éléments de liste. |
elementDescriptors
|
Identifie le widget d'interface utilisateur sur lequel l'utilisateur a cliqué à l'aide de la hiérarchie de l'interface utilisateur Android.
Incompatible avec visionText.
|
visionText
|
Identifie l'élément cliqué à l'aide de l'OCR. Incompatible avec elementDescriptors.
|
matchIndex
|
Spécifie l'index de l'occurrence de l'élément cible correspondant, lorsque l'élément cible est identifié à l'aide de visionText. Si la valeur est 0, l'action du script Robo sélectionne le premier élément correspondant. Si la valeur est 1, l'action du script Robo sélectionne le deuxième élément correspondant, et ainsi de suite. L'ordre est déterminé de gauche à droite, de haut en bas. La valeur par défaut est 0 (la première correspondance est sélectionnée).
|
maxNumberOfRuns
|
Spécifie le nombre de clics sur un élément aléatoire du clavier virtuel, lorsque eventType est défini sur SOFT_KEYBOARD_RANDOM_CLICK.
La valeur par défaut est 1.
|
Voici un exemple d'action de script Robo qui clique sur un bouton avec l'ID de ressource "com.google.samples.apps.topeka:id/done" :
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
Voici un exemple d'action de script Robo qui clique sur la deuxième occurrence du mot "Search" détecté sur un écran à l'aide de l'OCR :
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
Voici un exemple d'action de script Robo qui clique sur un élément de clavier virtuel avec une description de contenu "Emoji button" :
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
Voici un exemple d'action de script Robo qui clique sur des éléments aléatoires du clavier virtuel jusqu'à cinq fois :
{
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
"maxNumberOfRuns": 5
}
Désactiver le clavier virtuel
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "DISABLE_KEYBOARD"
|
-- |
Voici un exemple d'action de script Robo qui désactive le clavier virtuel :
{
"eventType": "DISABLE_KEYBOARD"
}
Exécuter une commande shell adb
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "ADB_SHELL_COMMAND"
|
-- |
command
|
Commande shell Android Debug Bridge (adb) à exécuter. |
L'attribut suivant est facultatif :
expectedOutputRegex: résultat attendu de la commande sous la forme d'une expression régulière Java. Si le résultat ne correspond pas, l'action du script Robo échoue. Par défaut, il s'agit d'une chaîne vide, ce qui signifie que la sortie n'est pas vérifiée.
Voici un exemple d'action de script Robo qui efface les données utilisateur de l'application testée :
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Octroyer des autorisations
Cette action est enregistrée par l'enregistreur de scripts Robo dans Android Studio pour assurer la rétrocompatibilité avec Espresso Test Recorder. Le test Robo accorde toutes les autorisations à l'application testée au début de chaque exploration. Cette action est donc sans effet. N'utilisez PAS cette action dans vos scripts Robo.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "PERMISSIONS_REQUEST"
|
-- |
Ignorer tous les éléments d'un écran
Cette action permet à Robo d'ignorer tous les éléments de n'importe quel écran qui déclenche le script Robo contenant.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "ALL_ELEMENTS_IGNORED"
|
-- |
Voici un exemple d'action de script Robo qui fait en sorte que Robo ignore tous les éléments d'un écran :
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Ignorer un élément
Cette action permet à Robo d'ignorer un ou plusieurs éléments correspondant au elementDescriptors spécifié.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "ELEMENT_IGNORED"
|
-- |
elementDescriptors
|
Identifie les widgets d'interface utilisateur ignorés à l'aide de la hiérarchie de l'interface utilisateur Android. |
L'attribut suivant est facultatif :
ignoreChildren: si la valeur est définie surtrue, Robo ignore également tous les descendants des widgets d'interface utilisateur ignorés. Par défaut, il s'agit defalse.
Voici un exemple d'action de script Robo qui indique à Robo d'ignorer tous les éléments dont la description du contenu commence par "Avatar" :
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"contentDescriptionRegex": "Avatar.*"
}
]
}
Texte d'entrée
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
eventType
|
Spécifie le type d'action du script Robo. |
"eventType": "VIEW_TEXT_CHANGED"
|
Saisit le texte donné dans le widget d'interface utilisateur cible. |
"eventType": "ENTER_TEXT"
|
Saisit le texte donné dans le widget d'interface utilisateur cible, puis envoie un événement KEYCODE_ENTER à ce widget d'interface utilisateur.
|
elementDescriptors
|
Identifie le widget d'interface utilisateur cible à l'aide de la hiérarchie de l'interface utilisateur Android. |
replacementText
|
Texte à saisir dans le widget d'interface utilisateur cible. |
Voici un exemple d'action de script Robo qui saisit "John" dans un widget d'interface utilisateur avec l'ID de ressource "com.google.samples.apps.topeka:id/first_name" :
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Clic long
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "VIEW_LONG_CLICKED"
|
-- |
elementDescriptors
|
Identifie le widget d'interface utilisateur cible à l'aide de la hiérarchie de l'interface utilisateur Android. S'exclut mutuellement avec visionText.
|
visionText
|
Identifie l'élément ayant fait l'objet d'un clic prolongé à l'aide de l'OCR. Incompatible avec elementDescriptors.
|
matchIndex
|
Spécifie l'index de l'occurrence de l'élément cible correspondant, lorsque l'élément cible est identifié à l'aide de visionText. Si la valeur est 0, l'action du script Robo sélectionne le premier élément correspondant. Si la valeur est 1, l'action du script Robo sélectionne le deuxième élément correspondant, et ainsi de suite. L'ordre est déterminé de gauche à droite, de haut en bas. La valeur par défaut est 0 (la première correspondance est sélectionnée).
|
L'attribut suivant est facultatif :
delayTime: spécifie la durée de l'appui prolongé, en millisecondes.
Voici un exemple d'action de script Robo qui effectue un clic de cinq secondes sur un widget d'interface utilisateur avec la description de contenu "Avatar 8" :
{
"eventType": "VIEW_LONG_CLICKED",
"elementDescriptors": [
{
"contentDescription": "Avatar 8"
}
],
"delayTime": 5000
}
Effectuer un geste à un point
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "ONE_POINT_GESTURE"
|
-- |
coordinates
|
Deux coordonnées pour un geste à un point, au format "(x1,y1)->(x2,y2)" en pourcentages ou en pixels. |
L'attribut suivant est facultatif :
dragAndDrop: si la valeur est définie surtrue, le geste à un point effectue une action de glisser-déposer. Par défaut, il s'agit defalse.
Voici un exemple d'action de geste à un point d'un script Robo qui effectue un balayage vers le bas :
{
"eventType": "ONE_POINT_GESTURE",
"coordinates": "(50%,25%)->(50%,75%)"
}
Effectuer un geste à deux points
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "TWO_POINT_GESTURE"
|
-- |
coordinates
|
Quatre coordonnées pour un geste à deux points, au format "(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" en pourcentages ou en pixels. |
Voici un exemple d'action de script Robo qui effectue un geste de pincement :
{
"eventType": "TWO_POINT_GESTURE",
"coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}
Effectuer une action IME
Cette action appuie sur le bouton d'action actuel (par exemple, "Suivant", "Terminé" et "Rechercher") dans l'éditeur de mode de saisie (IME) pour le widget d'interface utilisateur cible spécifié.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "PRESSED_EDITOR_ACTION"
|
-- |
elementDescriptors
|
Identifie le widget d'interface utilisateur cible à l'aide de la hiérarchie de l'interface utilisateur Android. |
Voici un exemple d'action de script Robo qui effectue une action IME sur un widget d'interface utilisateur avec l'ID de ressource "com.google.samples.apps.topeka:id/first_name" :
{
"eventType": "PRESSED_EDITOR_ACTION",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Appuyez sur la touche Retour
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
eventType
|
Spécifie le type d'action du script Robo. |
"eventType": "PRESSED_BACK"
|
Envoie un événement KEYCODE_BACK à l'appareil.
|
"eventType": "PRESSED_BACK_EMULATOR_28"
|
Utilisé par l'enregistreur de scripts Robo dans Android Studio pour appuyer sur "Retour" sur les émulateurs d'API 28. |
Voici un exemple d'action de script Robo qui appuie sur le bouton Retour :
{
"eventType": "PRESSED_BACK"
}
Appuyez sur le bouton d'accueil
Cette action envoie un événement KEYCODE_HOME à l'appareil.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "GO_HOME"
|
-- |
Voici un exemple d'action de script Robo qui appuie sur l'écran d'accueil :
{
"eventType": "GO_HOME"
}
Faire défiler un élément pour l'afficher
Cette action permet au test Robo de faire défiler vers l'avant le widget d'interface utilisateur correspondant au elementDescriptors spécifié jusqu'à ce que le widget d'interface utilisateur correspondant au childElementDescriptors spécifié soit présent à l'écran, ou que le widget défilé ne puisse plus être défilé, ou que le nombre maximal de 50 défilements soit atteint.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "ELEMENT_SCROLL_INTO_VIEW"
|
-- |
elementDescriptors
|
Identifie le widget d'interface utilisateur ayant fait l'objet d'un défilement à l'aide de la hiérarchie de l'interface utilisateur Android. |
childElementDescriptors
|
Identifie le widget d'interface utilisateur vers lequel faire défiler l'écran à l'aide de la hiérarchie de l'interface utilisateur Android. |
Voici un exemple d'action de script Robo qui fait défiler le widget d'interface utilisateur avec l'ID de ressource "my.app.package:id/scrollable_card_container" jusqu'à ce que le widget d'interface utilisateur avec le texte "Orange" soit présent à l'écran (ou jusqu'à ce qu'aucun autre défilement ne puisse être effectué, ou que le nombre maximal de 50 défilements soit atteint) :
{
"eventType": "ELEMENT_SCROLL_INTO_VIEW",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/scrollable_card_container"
}
],
"childElementDescriptors": [
{
"text": "Orange"
}
]
}
Glissé
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "VIEW_SWIPED"
|
-- |
swipeDirection
|
Spécifie la direction du balayage :
|
elementDescriptors
|
Identifie le widget d'interface utilisateur cible à l'aide de la hiérarchie de l'interface utilisateur Android. |
Voici un exemple d'action de script Robo qui balaie vers le haut un widget d'interface utilisateur avec l'ID de ressource "my.app.package:id/custom_content" :
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Faire une capture d'écran
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "TAKE_SCREENSHOT"
|
-- |
screenshotName
|
Spécifie le nom du fichier de capture d'écran. |
Voici un exemple d'action de script Robo qui effectue une capture d'écran :
{
"eventType": "TAKE_SCREENSHOT",
"screenshotName": "my_screenshot"
}
Appuyez sur un point de l'écran
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "POINT_TAP"
|
-- |
pointTapXCoordinate
|
Coordonnée X en pixels du point sélectionné. Incompatible avec pointTapXPercent et pointTapYPercent.
|
pointTapYCoordinate
|
Coordonnée Y en pixels du point sélectionné. Incompatible avec pointTapXPercent et pointTapYPercent.
|
pointTapXPercent
|
Coordonnée X en pourcentage du point sur lequel l'utilisateur a appuyé. Incompatible avec pointTapXCoordinate et pointTapYCoordinate.
|
pointTapYPercent
|
Coordonnée Y en pourcentage du point sélectionné. Incompatible avec pointTapXCoordinate et pointTapYCoordinate.
|
Voici un exemple d'action de script Robo qui appuie au milieu d'un écran :
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Appuyer sur un point d'un élément
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "POINT_TAP_ELEMENT"
|
-- |
pointTapXPercent
|
Coordonnée X en pourcentage dans l'élément cible. |
pointTapYPercent
|
Coordonnée Y en pourcentage dans l'élément cible. |
elementDescriptors
|
Identifie le widget d'interface utilisateur cible à l'aide de la hiérarchie de l'interface utilisateur Android. |
Voici un exemple d'action de script Robo qui déplace le curseur d'une barre de recherche vers la droite :
{
"eventType": "POINT_TAP_ELEMENT",
"pointTapXPercent": 80,
"pointTapYPercent": 50,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/my_seekbar"
}
]
}
Arrêter l'exploration
Cette action arrête le test Robo.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
|---|---|
"eventType": "TERMINATE_CRAWL"
|
-- |
Voici un exemple d'action de script Robo qui arrête un test Robo :
{
"eventType": "TERMINATE_CRAWL"
}
Attente
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "WAIT" (or "DELAYED_MESSAGE_POSTED")
|
-- |
delayTime
|
Spécifie le délai d'attente, en millisecondes. |
Voici un exemple d'action de script Robo qui attend trois secondes :
{
"eventType": "WAIT",
"delayTime": 3000
}
Attendre un élément
Cette action permet au test Robo d'attendre qu'un élément apparaisse à l'écran jusqu'au délai avant expiration spécifié.
Le tableau suivant liste les attributs obligatoires :
| Attribut | Description |
"eventType": "WAIT_FOR_ELEMENT"
|
-- |
delayTime
|
Spécifie le délai d'attente avant expiration, en millisecondes. |
elementDescriptors
|
Identifie le widget d'interface utilisateur attendu à l'aide de la hiérarchie de l'interface utilisateur Android. |
Voici un exemple d'action de script Robo qui attend jusqu'à 30 secondes qu'un widget d'interface utilisateur avec l'ID de ressource "my.app.package:id/confirmation_button" apparaisse à l'écran :
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}