Guide de référence des scripts Robo

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é (QA) pour les applications mobiles. Ils permettent également d'adopter des stratégies d'intégration continue (CI) et de tests avant lancement. Un script Robo est un fichier JSON qui décrit une séquence d'actions d'interface utilisateur (UI) et d'autres actions.

Vous pouvez créer un script Robo de plusieurs manières :

  • Utilisez la fonctionnalité d'enregistrement de scripts 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, comme le package d'application Android (APK) de l'application testée.

Voici un exemple de script Robo qui connecte un utilisateur à une application, déclenché lorsque l'application testée est lancé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"
          }
        ]
      }
    ]
  }
]

Si un fichier ne contient qu'un seul script Robo et que sa condition de déclenchement est la condition par défaut app_under_test_shown, comme dans l'exemple ci-dessus, vous pouvez spécifier le script Robo dans un fichier en utilisant un format plus simple, c'est-à-dire sous la forme d'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+ avec les scripts Robo

Robo pour iOS+ (bêta) est partiellement compatible 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 homologues 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
  • Mettre fin à l'exploration

Les attributs d'identification suivants dans les descripteurs d'éléments sont acceptés dans 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 dans les descripteurs de contexte suivantes sont acceptées dans iOS+ :

  • Application test affichée
  • Élément présent
  • Action de script non Robo effectuée

Structure

Un script Robo comporte plusieurs attributs qui décrivent la façon dont 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 permettant de suivre ce script Robo dans les résultats d'exploration. Robo dispose de scripts Robo intégrés avec leurs propres id. Bien que le 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 de l'exploration à 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 Indique le nombre de fois où Robo peut exécuter ce script Robo lors d'une exploration. Par défaut, Robo peut exécuter un script Robo une seule 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 fichier unique contient une collection d'un ou plusieurs scripts Robo.

Voici un exemple de fichier avec 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'UI correspondant à elementDescriptors ou au texte spécifié par visionText est présent à l'écran.
"condition": "element_disabled" Vérifie qu'un widget d'UI 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 est en cours d'exécution 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 en cours d'exécution 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, condition est annulé. Par exemple, vous pouvez utiliser cet attribut pour vérifier si un widget d'UI n'est PAS présent à l'écran ou si l'application testée n'est PAS en cours d'exécution au premier plan.
elementDescriptors Un ou plusieurs descripteurs d'éléments qui identifient un widget d'UI à l'écran. Elle est utilisée en combinaison avec les conditions element_present, element_disabled et element_checked. S'exclut mutuellement 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. S'exclut mutuellement avec elementDescriptors.
nonRoboscriptActionCount Nombre d'actions consécutives non liées à un 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 nonRoboscriptActionCount action Robo. Par défaut, il s'agit 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 la 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 liée à un script :

{
  "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 plusieurs paires attribut-valeur, décrites dans le tableau suivant :

Attribut Description
eventType Spécifie le type d'action (clic, modification de texte, etc.). Obligatoire pour chaque action.
elementDescriptors Descripteurs qui identifient un widget d'UI. Obligatoire pour toutes les actions qui ont un widget d'UI 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'UI cible sur un écran, sans que le script Robo contenant échoue. La valeur par défaut est false.
replacementText Texte à saisir dans le widget d'UI 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 délai d'attente, en millisecondes. Obligatoire pour les actions d'attente.
pointTapXCoordinate et pointTapYCoordinate Coordonnées X et Y en pixels du point touché. S'exclut mutuellement avec pointTapXPercent et pointTapYPercent. Obligatoire pour les actions de pression sur un point.
pointTapXPercent et pointTapYPercent Coordonnées X et Y en pourcentage du point touché. S'exclut mutuellement avec pointTapXCoordinate et pointTapYCoordinate. Obligatoire pour les actions de pression sur un point.

Voici un exemple de script Robo avec deux actions sans widgets d'UI cibles, ce qui signifie que ces actions ne fonctionnent pas sur un widget d'UI spécifique :

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

Descripteurs d'éléments

Un descripteur d'élément identifie un widget d'UI à 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'UI 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 à mettre en correspondance avec resourceId.
contentDescription
contentDescriptionRegex Expression régulière Java à mettre en correspondance avec contentDescription.
text (qui s'affiche à l'écran)
textRegex Expression régulière Java à mettre en correspondance avec text.
groupViewChildPosition, recyclerViewChildPosition ou adapterViewChildPosition Représente la position d'un enfant de widget d'UI en fonction du type de son widget parent.

Ces attributs sont souvent non définis. Par exemple, un bouton peut ne pas avoir de description de texte ni de contenu. Même si certaines valeurs d'attributs sont présentes, elles peuvent ne pas être uniques sur un écran d'application donné (y compris resourceId).

Par exemple, il n'est généralement possible de différencier les éléments d'une liste qu'en utilisant les différentes positions de leurs enfants dans leur widget parent. Cela signifie qu'il est généralement insuffisant d'utiliser un seul descripteur d'élément pour identifier un widget d'UI. Par conséquent, l'attribut elementDescriptors d'une action contient une séquence de descripteurs d'éléments qui sont ordonnés de sorte que le premier corresponde au widget d'UI cible, le deuxième au widget parent du widget d'UI cible, et ainsi de suite. Le widget d'UI cible d'une action correspond lorsque tous ses descripteurs d'éléments correspondent à la sous-hiérarchie du widget d'UI correspondant.

Voici un exemple de script Robo avec des actions de modification de texte et 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 lorsqu'un script Robo est en cours d'exécution :
    • strict : si la valeur est définie sur true, le script Robo n'utilise pas la correspondance partielle, l'ignorance de l'action en cours ni la suspension. Autrement dit, le script Robo est exécuté en tant que test d'instrumentation standard et échoue dès que l'une de ses actions ne peut pas être effectuée. Par défaut, il est défini sur false.
    • dismiss_popups : si la valeur est définie sur true, le test Robo ferme toutes les boîtes de dialogue inattendues lors de l'exécution du script Robo, même en mode strict. Cette option n'a aucun effet lorsque vous n'êtes pas en mode strict. Par défaut, il s'agit de false.
    • notify : si la valeur est définie sur false, le script Robo n'affiche pas de notifications à l'écran au début et à la fin de son exécution. Par défaut, la valeur est true.
  • postscript : options d'exécution appliquées une fois un script Robo terminé :
    • terminate : si la valeur est définie sur true, le test Robo arrête l'exploration une fois le script Robo terminé. Par défaut, il s'agit de false.

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 pour l'exécution. 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 commentaires, 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, un script Robo reste actif jusqu'à ce que toutes ses actions soient effectuées (ou au moins tentées). Le test Robo essaie toujours de faire correspondre une action de script Robo lorsqu'il choisit une action à effectuer. Le script Robo utilise les techniques suivantes pour améliorer la robustesse :

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 réessayé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'UI 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 d'écran sont réorganisés.

Ignorer l'action en cours Si l'action de script Robo actuelle ne peut pas être associée entièrement ou partiellement, Robo tente d'associer l'action de script Robo suivante. Si l'action suivante correspond entièrement ou partiellement, le test Robo ignore l'action de script Robo actuelle (et n'y revient jamais) et effectue l'action suivante.

Cette technique est utile dans les scénarios où le comportement de l'application change entre les versions ou est instable, par exemple lorsqu'une boîte de dialogue intermittente peut s'afficher sur différents écrans lors de l'enregistrement par rapport à la relecture d'un script Robo.

Suspendre Si aucune action de script Robo actuelle ou ultérieure ne peut être associée entièrement 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. Ainsi, les scripts Robo ne doivent pas nécessairement être un prologue à un test Robo. Vous pouvez également alterner les actions de script Robo avec les actions de test Robo standards. Cette technique est utile lorsque le comportement de l'application est instable ou lorsque les différences 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 son maxNumberOfRuns, il ne peut plus être déclenché lors d'une analyse 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 :

  1. Comporte un attribut contextDescriptor.
  2. Possède le priority le plus élevé (par défaut, tous les scripts Robo ont le même priority d'exécution, à savoir 1).
  3. Apparaît en premier dans la liste des scripts Robo si les priorités des scripts Robo sont identiques.

Voici un exemple de fichier avec 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 éléments suivants, dans l'ordre :

  1. "Robo script 2", car il a la priorité la plus élevée.
  2. "Robo script 1", car il apparaît plus tôt parmi les scripts Robo applicables restants ayant la même priorité.
  3. "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 l'ajuster à l'aide de l'attribut maxNumberOfRuns.

Voici un exemple de script Robo qui met 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 le lancement de Robo et le début de l'exploration de l'application testée.
post_crawl Une fois que Robo a terminé d'explorer l'application testée. Un script Robo post_crawl ne doit pas durer plus de 15 secondes, sinon l'exploration peut se terminer par un délai d'inactivité.
crawl Il s'agit de la principale étape d'exploration, lorsque Robo explore l'application testée.
close_screen Lorsque Robo tente de revenir en arrière à 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 Retour, ce qui n'est pas souhaitable dans certains scénarios.

Si l'attribut crawlStage d'un script Robo n'est pas spécifié, la valeur crawl est implicite.

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 à 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 la façon dont 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 où cette action conditionnelle peut être effectuée lors d'une exécution de son script Robo parent. Par défaut, toutes les actions conditionnelles ne peuvent être effectuées qu'une seule fois lors d'une même exécution du script Robo qui les contient.
contextDescriptor Contexte/condition qui déclenche cette action conditionnelle. Il a la même structure et offre des fonctionnalités similaires à contextDescriptor du script Robo.

Lorsqu'un script Robo est déclenché, il 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 effectue cette action conditionnelle. 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é lors de 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'UI spécifiques ou tous les widgets d'UI 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'UI ciblé par ses actions d'ignorance (sauf si une autre action de script Robo oblige Robo à effectuer une action sur l'un des widgets d'UI 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 le 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 avec deux scripts Robo. Le premier script Robo demande à Robo d'ignorer tous les widgets d'interface utilisateur sur un écran contenant un widget d'interface utilisateur avec un ID de ressource "my.app.package:id/ignored_screen". Le deuxième script Robo permet à Robo d'ignorer les widgets d'UI dont les ID de ressource correspondent à l'expression régulière Java ".*:id/done" sur un écran contenant un widget d'UI 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 pour différents facteurs de forme d'appareil, il est beaucoup plus robuste de s'appuyer sur la position des données de l'enfant, qui est absolue. Il s'agit d'une approche moins robuste que de s'appuyer sur le nombre de balayages nécessaires pour amener cet enfant à l'écran, puis utiliser sa position à l'écran.

Par conséquent, le script Robo capture les positions absolues des données des enfants RecyclerView qui sont les cibles des actions du script Robo sous la forme recyclerViewChildPosition. Le script Robo capture également les positions absolues des données des enfants AdapterView qui sont les cibles des actions du script Robo sous la forme adapterViewChildPosition.

Les actions sur les enfants RecyclerView et AdapterView sont effectuées en procédant comme suit :

  1. Le test Robo s'assure que l'enfant correspondant est affiché à l'écran grâce à une action de positionnement sur son RecyclerView ou AdapterView parent.

  2. 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 enregistre le script en tant que 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, le test Robo réalise d'abord les actions décrites dans le script, puis explore l'application comme d'habitude.

Pour créer un fichier JSON de script Robo dans Android Studio, suivez les étapes décrites dans Enregistrer un script Robo à l'aide de Test Lab dans Android Studio.

Actions de 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 des tests Robo.

Assertion

Si la condition affirmé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'une assertion ayant échoué.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "ASSERTION" --
contextDescriptor Décrit le contexte ou la condition affirmés. Il a la même structure et offre des fonctionnalités similaires à 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'UI 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 répertorie 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 script Robo dans Android Studio pour cliquer sur les éléments de la liste.
elementDescriptors Identifie le widget d'UI sur lequel l'utilisateur a cliqué à l'aide de la hiérarchie de l'UI Android. S'exclut mutuellement avec visionText.
visionText Identifie l'élément sur lequel l'utilisateur a cliqué à l'aide de l'OCR. S'exclut mutuellement 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, puis 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 fois où cliquer sur un élément aléatoire du clavier logiciel, lorsque eventType est 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ée 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 logiciel 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 du clavier logiciel aléatoires jusqu'à cinq fois :

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

Désactiver le clavier logiciel

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "DISABLE_KEYBOARD" --

Voici un exemple d'action de script Robo qui désactive le clavier logiciel :

{
  "eventType": "DISABLE_KEYBOARD"
}

Exécuter la commande adb shell

Le tableau suivant répertorie 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 forme d'expression régulière Java. Si la sortie 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 script 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 une opération sans effet. N'utilisez PAS cette action dans vos scripts Robo.

Le tableau suivant répertorie 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 l'écran qui déclenchent le script Robo contenant.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "ALL_ELEMENTS_IGNORED" --

Voici un exemple d'action de script Robo qui permet à Robo d'ignorer 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 répertorie les attributs obligatoires :

Attribut Description
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Identifie le ou les widgets d'UI ignorés à l'aide de la hiérarchie de l'UI Android.

L'attribut suivant est facultatif :

  • ignoreChildren : si la valeur est définie sur true, Robo ignore également tous les descendants du ou des widgets d'UI ignorés. Par défaut, il s'agit de false.

Voici un exemple d'action de script Robo qui permet à 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 répertorie 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'UI cible.
"eventType": "ENTER_TEXT" saisit le texte donné dans le widget d'UI cible, puis envoie un événement KEYCODE_ENTER à ce widget d'UI.
elementDescriptors Identifie le widget d'UI cible à l'aide de la hiérarchie de l'UI Android.
replacementText Texte à saisir dans le widget d'UI cible.

Voici un exemple d'action de script Robo qui saisit "John" dans un widget d'UI 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 répertorie les attributs obligatoires :

Attribut Description
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Identifie le widget d'UI cible à l'aide de la hiérarchie de l'UI Android. S'exclut mutuellement avec visionText.
visionText Identifie l'élément sur lequel l'utilisateur a appuyé de manière prolongée à l'aide de l'OCR. S'exclut mutuellement 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, puis 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é pour un clic long, 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 doigt

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "ONE_POINT_GESTURE" --
coordinates Deux coordonnées pour un geste à un doigt, au format "(x1,y1)->(x2,y2)", en pourcentage ou en pixels.

L'attribut suivant est facultatif :

  • dragAndDrop : si la valeur est définie sur true, le geste à un doigt effectue une action de glisser-déposer. Par défaut, il s'agit de false.

Voici un exemple d'action de geste à un point dans un script Robo qui effectue un balayage vers le bas :

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

Effectuer un geste à deux doigts

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "TWO_POINT_GESTURE" --
coordinates Quatre coordonnées pour un geste à deux doigts, au format "(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" en pourcentage ou en pixels.

Voici un exemple d'action de script Robo qui effectue un geste de pincement pour zoomer :

{
  "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é" ou "Rechercher") dans l'éditeur de méthode d'entrée (IME) pour le widget d'UI cible spécifié.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Identifie le widget d'UI cible à l'aide de la hiérarchie de l'UI Android.

Voici un exemple d'action de script Robo qui effectue une action IME sur un widget d'UI 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 "Retour".

Le tableau suivant répertorie 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 script Robo dans Android Studio pour appuyer sur le bouton Retour sur les émulateurs API 28.

Voici un exemple d'action de script Robo qui appuie sur le bouton "Retour" :

{
  "eventType": "PRESSED_BACK"
}

Appuyez sur "Accueil".

Cette action envoie un événement KEYCODE_HOME à l'appareil.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "GO_HOME" --

Voici un exemple d'action de script Robo qui appuie sur le bouton Accueil :

{
  "eventType": "GO_HOME"
}

Faire défiler un élément pour l'afficher

Cette action permet au test Robo de faire défiler le widget d'UI correspondant à elementDescriptors jusqu'à ce que le widget d'UI correspondant à childElementDescriptors 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 répertorie les attributs obligatoires :

Attribut Description
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Identifie le widget d'interface utilisateur défilé à l'aide de la hiérarchie de l'interface utilisateur Android.
childElementDescriptors Identifie le widget d'UI vers lequel faire défiler l'écran à l'aide de la hiérarchie de l'UI Android.

Voici un exemple d'action de script Robo qui fait défiler le widget d'UI avec l'ID de ressource "my.app.package:id/scrollable_card_container" jusqu'à ce que le widget d'UI avec le texte "Orange" soit présent à l'écran (ou qu'il ne soit plus possible de faire défiler l'écran, 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 répertorie les attributs obligatoires :

Attribut Description
"eventType": "VIEW_SWIPED" --
swipeDirection Indique la direction du balayage :
  • Left
  • Right
  • Up
  • Down
  • Forward : Down ou Right selon la possibilité de défilement vertical ou horizontal du widget d'UI cible.
  • Backward : Up ou Left, selon que le widget UI cible est défilable verticalement ou horizontalement.
elementDescriptors Identifie le widget d'UI cible à l'aide de la hiérarchie de l'UI Android.

Voici un exemple d'action de script Robo qui balaye un widget d'interface utilisateur vers le haut 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 répertorie les attributs obligatoires :

Attribut Description
"eventType": "TAKE_SCREENSHOT" --
screenshotName Indique le nom du fichier de capture d'écran.

Voici un exemple d'action de script Robo qui prend une capture d'écran :

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

Appuyez sur un point de l'écran.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "POINT_TAP" --
pointTapXCoordinate Coordonnée X en pixels du point touché. S'exclut mutuellement avec pointTapXPercent et pointTapYPercent.
pointTapYCoordinate Coordonnée Y en pixels du point touché. S'exclut mutuellement avec pointTapXPercent et pointTapYPercent.
pointTapXPercent Coordonnée X (en pourcentage) du point touché. S'exclut mutuellement avec pointTapXCoordinate et pointTapYCoordinate.
pointTapYPercent Coordonnée Y en pourcentage du point touché. S'exclut mutuellement 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 dans un élément

Le tableau suivant répertorie 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'UI cible à l'aide de la hiérarchie de l'UI 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"
    }
  ]
}

Mettre fin à l'exploration

Cette action arrête le test Robo.

Le tableau suivant répertorie 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 répertorie 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 d'attente spécifié.

Le tableau suivant répertorie les attributs obligatoires :

Attribut Description
"eventType": "WAIT_FOR_ELEMENT" --
delayTime Spécifie le délai d'attente, 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" s'affiche à l'écran :

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

Étapes suivantes