Guia de referência de scripts Robo

Neste documento, fornecemos informações de referência sobre scripts Robo, incluindo estrutura, recursos, uso, gravação e ações. Os scripts Robo são testes que automatizam tarefas de controle de qualidade manual de apps para dispositivos móveis e permitem estratégias de teste de pré-lançamento e integração contínua (CI). Um script Robo é um arquivo JSON que descreve uma sequência da interface do usuário (IU) e outras ações.

Um script Robo pode ser criado das seguintes maneiras:

  • Use o recurso de gravação de script Robo. (Somente Android)

  • Crie o script Robo manualmente. (Android e iOS+)

  • Grave e edite o script Robo manualmente. (Somente Android)

Para saber mais sobre como usar scripts Robo, consulte Executar um script Robo.

Introdução

O script Robo é fornecido para o Teste Robo com outras entradas, como o pacote de aplicativo Android (APK) em teste no app.

Confira a seguir um exemplo de script Robo que faz a conexão de um usuário a um app e que é acionado quando o app em teste é iniciado:

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

Se houver apenas um script Robo em um arquivo e ele tiver a condição de acionamento app_under_test_shown padrão, como no exemplo acima, vai ser possível especificar o script Robo em um arquivo usando um formato mais simples, como consequência das ações realizadas:

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

Suporte do iOS+ para scripts Robo

O Robo para iOS+ (Beta) tem suporte limitado para scripts Robo. A sintaxe do script Robo para iOS+ é idêntica à sintaxe do Android, e os recursos compatíveis do iOS+ se comportam de maneira semelhante aos equivalentes do Android.

As ações a seguir têm suporte ao iOS+:

  • Declaração
  • Clique
  • Clique longo
  • Deslizar
  • Ignorar todos os elementos
  • Espera
  • Fazer uma captura de tela
  • Encerrar rastreamento

Os seguintes atributos de identificação em descritores de elementos oferecem suporte ao iOS+:

  • Nome da classe
  • Nome da classe ancestral
  • Descrição do conteúdo (e regex)
  • Texto (e regex)

As condições de acionamento nos descritores de contexto são compatíveis com o iOS+:

  • App em fase de teste exibido
  • Elemento presente
  • Ação de script não Robo realizada

Estrutura

Um script Robo tem vários atributos que descrevem como ele é executado. A maioria desses atributos é opcional e tem valores padrão definidos previamente:

Atributo Descrição
id Um número inteiro que ajuda a rastrear o script Robo nas saídas de rastreamento.
description Semelhante a id, porém mais descritivo.
crawlStage O estágio de rastreamento em que o Robo aplica este script Robo. Por padrão, é o estágio de rastreamento principal.
priority A prioridade deste script Robo em comparação com outros. Por padrão, todos os scripts Robo têm prioridade 1.
maxNumberOfRuns Especifica quantas vezes durante um rastreamento o Robo pode executar este script Robo. Por padrão, o Robo pode executar um script Robo uma vez.
contextDescriptor Descreve o contexto ou condição que aciona o script Robo. Se omitido, a condição de acionamento do script Robo vai ser considerada sempre atendida, ou seja, o script Robo é incondicional.
actions Todas as ações deste script Robo.

Um único arquivo possui um conjunto de um ou mais scripts Robo.

Confira a seguir o exemplo de um arquivo com dois scripts Robo não condicionais, cada um com uma só ação, que é executada uma vez no início de um rastreamento:

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

Descritor de contexto

Um descritor de contexto define o contexto ou a condição que aciona um script Robo usando um atributo ou uma combinação deles:

Atributo Descrição
"condition": "always" Sempre aciona um script Robo.
"condition": "element_present" Verifica se um widget de IU correspondente a elementDescriptors ou um texto especificado por visionText é exibido na tela.
"condition": "element_disabled" Verifica se um widget de IU correspondente a elementDescriptors está presente na tela e não pode ser usado para interagir.
"condition": "element_checked" Verifica se um widget de IU correspondente a elementDescriptors está presente na tela e marcado.
"condition": "app_under_test_shown" Verifica se o app em teste está em execução em primeiro plano.
"condition": "default_launcher_shown" Verifica se a tela de início de um dispositivo está sendo exibida, isto é, nenhum app está sendo executado em primeiro plano.
"condition": "non_roboscript_action_performed" Verifica se as últimas nonRoboscriptActionCount ações consecutivas executadas pelo teste Robo não são ações de script Robo.
negateCondition Se definido como true, o condition é negado. Por exemplo, você pode usar esse atributo para verificar se um widget de IU NÃO está em exibição na tela ou se o app em teste NÃO está em execução em primeiro plano.
elementDescriptors Um ou mais descritores de elementos que identificam um widget de interface na tela. É usado em combinação com as condições element_present, element_disabled e element_checked. Mutuamente exclusivo com visionText. Para mais informações, consulte Descritores de elementos.
visionText O texto na tela é detectado usando a API OCR (de reconhecimento óptico de caracteres). visionText é usado em combinação com a condição element_present. Mutuamente exclusivo com elementDescriptors.
nonRoboscriptActionCount O número de ações consecutivas de script não Robo realizadas anteriormente. Ele é usado em combinação com a condição non_roboscript_action_performed para acionar um script Robo após cada nonRoboscriptActionCount ação do Robo. Por padrão, ele é 1.

Confira a seguir o exemplo de um script Robo que é acionado por um widget de IU com um ID de recurso "my.app.package:id/page_header" na tela:

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

Confira a seguir o exemplo de um script Robo que é acionado pelo "Privacy Policy" detectado por reconhecimento óptico de caracteres (OCR):

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

Confira a seguir o exemplo de um script Robo que aguarda cinco segundos após cada ação que não seja de um script Robo:

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

Ações

Cada ação em um script Robo é representada por um pacote de um ou mais pares de valor e atributo, descritos na tabela a seguir:

Atributo Descrição
eventType Especifica o tipo da ação, por exemplo, clique, edição de texto etc. Obrigatório para cada ação.
elementDescriptors Descritores que identificam um widget de IU. Obrigatório para todas as ações que têm um widget de IU de destino, como clicar em um botão específico.
optional Se for definida como true, a ação será ignorada quando não puder ser realizada. Por exemplo, essa ação é ignorada quando não é possível encontrar o widget da IU de destino em uma tela sem falhar no script em que o Robo está. Por padrão, o valor é false.
replacementText O texto a ser inserido no widget da IU de destino. Obrigatório para ações de edição de texto.
swipeDirection Especifica em que direção deslizar. Obrigatório para ações de deslizar.
delayTime Especifica o tempo de espera, em milissegundos. Obrigatório para ações de espera.
pointTapXCoordinate e pointTapYCoordinate As coordenadas de pixel X e Y do ponto de toque. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent. Obrigatório para ações de toque no ponto.
pointTapXPercent e pointTapYPercent É a porcentagem de coordenadas X e Y do ponto de toque. Ele é mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate. Obrigatório para ações de toque no ponto.

Veja a seguir o exemplo de script Robo com duas ações sem widgets de IU de destino. Isso significa que essas ações não operam em um widget de IU específico:

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

Descritores de elemento

Um descritor de elemento identifica um widget de IU usando um ou mais dos seguintes atributos de identificação:

Atributo Descrição
className
ancestorClassName Nome da classe do ancestral da hierarquia de IU do elemento. Um ancestral é qualquer um dos nós pais na hierarquia de IU do elemento, incluindo o próprio elemento.
resourceId
resourceIdRegex Expressão regular Java correspondente a resourceId.
contentDescription
contentDescriptionRegex Expressão regular Java correspondente a contentDescription.
text (que aparece na tela)
textRegex Expressão regular Java correspondente a text.
groupViewChildPosition, recyclerViewChildPosition ou adapterViewChildPosition Representa a posição filha de um widget de IU, dependendo do tipo de widget pai.

Muitas vezes, esses atributos são indefinidos. Por exemplo, um botão pode não ter descrição de texto e conteúdo. Mesmo que alguns valores de atributos estejam presentes, eles podem não ser exclusivos em uma determinada tela do app (incluindo resourceId).

Por exemplo, a diferenciação entre itens de uma lista geralmente só é possível quando são usadas as diferentes posições filhas no widget pai. Isto é, usar apenas um descritor de elemento para identificar um widget de IU geralmente é insuficiente. Portanto, o atributo elementDescriptors de uma ação contém uma sequência de descritores de elementos ordenados de maneira que o primeiro corresponda ao widget da IU de destino. O segundo corresponde ao widget pai do widget da IU de destino e assim por diante. O widget de IU de destino de uma ação é correspondido quando todos os descritores de elemento correspondem à sub-hierarquia de widget de IU correspondente.

Veja a seguir o exemplo de script Robo com alteração de texto e ações de clique. Ambos exigem a identificação do widget da IU de destino usando os descritores de elemento fornecidos:

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

Opções de execução

Como opção, é possível prefixar a lista de ações em um script Robo com um objeto JSON que especifica as opções de execução para esse script Robo. Esse cabeçalho de configuração começa com a palavra-chave roboscript, seguida por uma representação JSON das opções de execução pretendidas.

Os scripts Robo são compatíveis com as seguintes opções de execução:

  • executionMode: opções de execução aplicadas quando um script Robo está em execução:
    • strict: se configurado como true, o script Robo não emprega correspondência parcial, ignorando a ação atual e suspensão. Ou seja, o script Robo é executado como um teste de instrumentação regular e falha tão logo não seja possível executar qualquer uma das ações dele. Por padrão, ela equivale a false.
    • notify: se definido como false, o script Robo não vai mostrar notificações na tela no início e no fim da execução. Por padrão, ele é true.
  • postscript: opções de execução aplicadas após a conclusão de um script Robo:
    • terminate: se for definido como true, o teste Robo deixará de rastrear depois que o script Robo for concluído. Por padrão, ele é false.

Confira a seguir o exemplo de script Robo executado no modo strict sem notificações na tela. Ele fica suspenso por três segundos. Depois disso, o rastreamento é interrompido:

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

Parâmetros do modelo

Um parâmetro do modelo é um marcador de posição em um script Robo que é substituído pelo valor real quando o teste Robo carrega esse script para execução. Os parâmetros do modelo são prefixados com um sublinhado duplo seguido por um sinal de porcentagem e são sufixados com um sinal de porcentagem seguido por um sublinhado duplo.

Os scripts Robo são compatíveis com o seguinte parâmetro de modelo:

  • __%APP_PACKAGE_NAME%__: nome do pacote do app em teste.

Veja a seguir o exemplo de script Robo que interrompe o processo do app em teste:

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

Comentários

Um script Robo pode conter linhas de comentários, iniciadas com # ou //.

Veja a seguir o exemplo de script Robo com alguns comentários:

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

Funções

Por padrão, até que todas as ações de um script Robo sejam concluídas (ou pelo menos tentadas), ele permanece ativo. O teste Robo continua tentando fazer a correspondência com uma ação de script Robo sempre que está escolhendo uma ação a ser executada. O script Robo emprega as seguintes técnicas para aumentar a robustez:

Técnica Descrição
Correspondência parcial Se a ação atual do script Robo não puder ser totalmente correspondida, os critérios de correspondência serão afrouxados e a correspondência será repetida. A correspondência parcial não considera o descritor de elemento mais externo ao corresponder ao widget de IU de destino de uma ação do script Robo.

Se a correspondência parcial for bem-sucedida, a ação correspondente do script Robo é executada normalmente. Essa técnica é compatível com cenários em que a estrutura do app muda, por exemplo, entre versões do app, quando os elementos da tela são reorganizados.

Pular a ação atual Se a ação atual do script Robo não for total ou parcialmente correspondida, o Robo tentará fazer a correspondência com a ação seguinte do script Robo. Se a ação subsequente corresponder total ou parcialmente, o teste Robo ignora permanentemente a ação atual do script Robo e executa a ação seguinte.

Essa técnica é compatível com cenários em que o comportamento do app muda entre versões ou é inconsistente. Por exemplo, quando uma caixa de diálogo intermitente pode aparecer em telas diferentes durante a gravação ou a repetição de um script Robo.

Suspender Quando as ações de script Robo atuais ou subsequentes não correspondem total ou parcialmente, elas são suspensas temporariamente, e o teste Robo escolhe uma ação a ser executada usando as outras estratégias. Depois que essa ação é concluída, o teste Robo retoma a execução do script Robo.

Desde que as ações atuais ou subsequentes do script Robo não sejam correspondentes, o script Robo permanece suspenso, independentemente da quantidade de ações. Assim, os scripts Robo não precisam ser um prólogo para um teste Robo. Você pode intercalar as ações de script Robo com as ações de teste Robo padrão. Essa técnica suporta casos em que o comportamento do app é instável ou quando as alterações nas versões do app são grandes o suficiente para que o teste Robo precise "preencher as lacunas" com as ações padrão.

Prioridades

Depois que um script Robo atingir maxNumberOfRuns, ele não vai poder mais ser acionado em um determinado rastreamento. Se mais de um script Robo puder ser acionado pelo contexto atual, a prioridade vai ser dada, na ordem a seguir, ao script que:

  1. Tiver um atributo contextDescriptor.
  2. Tiver o priority mais alto. Por padrão, todos os scripts Robo têm a mesma execução priority de 1.
  3. For o primeiro deles na lista de scripts Robo, se as prioridades forem as mesmas.

Confira a seguir o exemplo de um arquivo com três scripts Robo que executam a mesma ação e são acionados pela mesma condição: o app em teste estar em primeiro plano:

[
  {
    "id": 1000,
    "description": "Robo script 1",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1001,
    "description": "Robo script 2",
    "priority": "2",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  },
  {
    "id": 1002,
    "description": "Robo script 3",
    "contextDescriptor": {
      "condition": "app_under_test_shown"
    },
    "actions": [
      {
        "eventType": "DELAYED_MESSAGE_POSTED",
        "delayTime": 3000
      }
    ]
  }
]

Quando o app em teste está em primeiro plano, o Robo aciona o seguinte nesta ordem:

  1. "Robo script 2" por ter a prioridade mais alta.
  2. "Robo script 1" por estar listado antes dos scripts Robo restantes e aplicáveis com a mesma prioridade.
  3. "Robo script 3" como o último script Robo aplicável.

Execuções repetidas

Por padrão, o Robo aciona um script Robo no máximo uma vez durante um rastreamento. Isso pode ser ajustado pelo atributo maxNumberOfRuns.

Confira a seguir um exemplo de script Robo que coloca o app em teste em segundo plano até 10 vezes:

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

Estágio de rastreamento

Os scripts Robo são aplicáveis em diferentes estágios de um rastreamento do Robo:

Estágio de rastreamento Descrição
pre_crawl Antes do Robo iniciar e rastrear o app em teste.
post_crawl Depois que o Robo concluir o rastreamento do app em teste.
crawl O estágio de rastreamento principal, quando o Robo rastreia o app em teste.
close_screen Quando o Robo tenta retornar (recuar) de uma determinada tela, quando todas as ações possíveis nessa tela forem analisadas. Por padrão, o Robo pressiona de volta, o que é indesejável em alguns casos.

Se o atributo crawlStage de um script Robo não for especificado, ele vai ser considerado como crawl.

Confira a seguir o exemplo de um script Robo que limpa os dados do usuário do app em teste antes que o Robo comece o rastreamento:

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

Este é um exemplo de script Robo que instrui o Robo a clicar em "Cancel" sempre que ele tentar retornar (recuar) de uma caixa de diálogo de confirmação:

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

Ações condicionais

Um script Robo pode conter ações condicionais. As ações condicionais possuem três atributos adicionais que descrevem como o Robo as realiza:

Atributo Descrição
priority A prioridade dessa ação condicional em comparação com as outras no script Robo onde elas estão. Por padrão, todas as ações condicionais têm prioridade 1.
maxNumberOfRuns Quantas vezes a ação condicional pode ser realizada durante uma execução do script Robo onde ela está. Por padrão, todas as ações condicionais podem ser realizadas no máximo uma vez em uma única execução do script Robo onde elas estão.
contextDescriptor O contexto ou a condição que aciona essa ação condicional. Tem a mesma estrutura e oferece recursos semelhantes ao [contextDescriptor do script Robo](#context-descriptor).

Quando acionado, um script Robo realiza as ações não condicionais uma a uma, na ordem em que aparecem. Se um script Robo contiver ações condicionais, elas sempre vão ser consideradas antes que uma ação não condicional seja escolhida para execução. Se qualquer ação condicional for acionada e selecionada com base na prioridade e no número restante de execuções, o script Robo vai executar essa ação condicional. Caso contrário, o script Robo vai executar a ação não condicional seguinte. Para um script Robo ser válido, ele precisa conter pelo menos uma ação não condicional.

Confira a seguir o exemplo de um script Robo incondicional com uma ação condicional que dispensa caixas de diálogo pop-up se elas aparecerem em qualquer ponto durante a execução do 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": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    },
    {
      "description": "Screen on",
      "eventType": "ADB_SHELL_COMMAND",
      "command": "input keyevent 82"
    },
    {
      "description": "Wait for 10 seconds",
      "eventType": "DELAYED_MESSAGE_POSTED",
      "delayTime": 10000
    }
}

Ações de ignorar

Um script Robo pode conter instruções para que o Robo ignore widgets da IU específicos ou todos em uma tela específica. Essas instruções são representadas como "ações" de ignorar com eventType ELEMENT_IGNORED e ALL_ELEMENTS_IGNORED correspondentes.

Sempre que o atributo contextDescriptor de um script Robo com ações de ignorar corresponder a uma determinada tela, o Robo não vai interagir com os widgets de IU segmentados pelas ações de ignorar, a menos que outra ação do script Robo faça com que o Robo realize uma ação em um dos widgets de IU ignorados.

Um script Robo pode conter uma combinação de ações condicionais, não condicionais e de ignorar. Ao contrário de outras ações do script Robo, as ações de ignorar são aplicadas se o contextDescriptor dele corresponder a uma tela durante um rastreamento Robo, independentemente dos atributos priority e maxNumberOfRuns.

Confira a seguir um exemplo de arquivo com dois scripts Robo. O primeiro script Robo faz com que ele ignore todos os widgets de IU em uma tela que tenha um widget de IU com um ID de recurso "my.app.package:id/ignored_screen". O segundo faz com que ele ignore widgets de IU com IDs de recurso que correspondam ao regex Java ".*:id/done" em uma tela que tenha um widget de IU com um ID de recurso "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"
          }
        ]
      }
    ]
  }
]

Suporte a RecyclerView e AdapterView

Os filhos dos widgets RecyclerView e AdapterView são carregados dinamicamente e podem ser exibidos com muitas ações de deslizar para fora da tela atual. Como o tamanho de uma tela e o número de ações de deslizar necessários para chegar a esse filho são diferentes para formatos de dispositivos que também diferem, é muito mais seguro confiar na posição de dados do filho, que é absoluta. É uma abordagem menos segura confiar no número de ações de deslizar, necessárias para levar esse filho à tela e usar a posição dele.

Portanto, o script Robo captura as posições absolutas dos dados dos filhos RecyclerView que são destinos de ações do script Robo, como recyclerViewChildPosition. O script Robo também captura as posições absolutas dos dados dos filhos do AdapterView, que são destinos das ações do script Robo, como adapterViewChildPosition.

As ações nos filhos do RecyclerView e AdapterView são realizadas nas seguintes etapas:

  1. O teste Robo garante que o filho correspondente seja exibido na tela com uma ação de posicionamento no respectivo RecyclerView ou AdapterView.

  2. O teste Robo executa a ação gravada diretamente no elemento filho, uma vez que ele já é exibido na tela.

Este exemplo é da ação de clique em um filho (android.widget.GridView) do AdapterView:

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

Veja a seguir o exemplo de uma ação de clique em um filho (android.support.v7.widget.RecyclerView) do 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
    }
  ]
}

Gravar um script Robo no Android Studio para execução no Test Lab

Você pode criar um script Robo no Android Studio, que o salva como um arquivo JSON. Em seguida, é possível fazer o upload do arquivo JSON para o Firebase Test Lab com o aplicativo e executar o teste conforme esperado.

Ao executar um teste Robo com um script anexado, primeiro o Robo lê as ações programadas para depois analisar o app normalmente.

Para criar um arquivo JSON de script Robo no Android Studio, siga as etapas em Gravar um script Robo usando o Test Lab no Android Studio.

Ações do script Robo

O atributo opcional comum a seguir se aplica a todas as ações:

  • description: ajuda a monitorar a execução dessa ação do script Robo nas saídas do teste Robo.

Declaração

Se a condição declarada for verdadeira, o script Robo segue para a ação seguinte, que pode ser outra declaração. Caso contrário, a execução do script Robo vai ser interrompida devido a uma declaração com falha.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ASSERTION" --
contextDescriptor Descreve o contexto ou a condição declarados. Tem a mesma estrutura e oferece recursos semelhantes ao contextDescriptor do script Robo.

Veja a seguir o exemplo de uma declaração de script Robo que verifica se o app em teste está no primeiro plano:

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

Veja a seguir o exemplo de uma declaração de script Robo que verifica se um widget de IU com o ID do recurso "com.google.samples.apps.topeka:id/done" é exibido em uma tela:

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

Veja a seguir o exemplo de uma declaração de script Robo que verifica se "Settings" NÃO é detectado em uma tela usando OCR:

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

Clique

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
eventType Especifica o tipo de ação do script Robo.
"eventType": "VIEW_CLICKED" Clica no elemento de destino do app em teste.
"eventType": "SOFT_KEYBOARD_CLICK" Clica no elemento de destino do teclado de virtual.
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" Clica em elementos aleatórios do teclado de virtual até maxNumberOfRuns vezes.
"eventType": "LIST_ITEM_CLICKED" Usado pelo gravador de script Robo no Android Studio para clicar em itens de lista.
elementDescriptors Identifica o widget de IU clicado usando a hierarquia de IU do Android. Mutuamente exclusivo com visionText.
visionText Identifica o elemento clicado usando o OCR. Mutuamente exclusivo com elementDescriptors.
maxNumberOfRuns Especifica quantas vezes clicar em um elemento aleatório do teclado de virtual, quando eventType for SOFT_KEYBOARD_RANDOM_CLICK. O valor padrão é 1.

Veja a seguir o exemplo de uma ação de script Robo que clica em um botão com o ID do recurso "com.google.samples.apps.topeka:id/done":

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

Veja a seguir o exemplo de ação de script do Robo que clica no "Privacy Policy" detectado em uma tela usando o OCR:

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

Veja a seguir o exemplo de uma ação de script Robo que clica em um elemento de teclado virtual com uma descrição de conteúdo "Emoji button":

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

Veja a seguir o exemplo de uma ação de script Robo que clica em elementos aleatórios do teclado virtual até cinco vezes:

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

Desativar o teclado virtual

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "DISABLE_KEYBOARD" --

Veja a seguir o exemplo de uma ação de script Robo que desativa o teclado de virtual:

{
  "eventType": "DISABLE_KEYBOARD"
}

Executar o comando adb shell

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ADB_SHELL_COMMAND" --
command O comando shell do Android Debug Bridge (adb) para executar.

O atributo a seguir é opcional:

  • expectedOutputRegex: a saída esperada do comando como uma expressão regular Java. Se a saída não for correspondente, a ação do script Robo falhará. Por padrão, é uma string vazia, o que significa que a saída não está marcada.

Veja a seguir o exemplo de ação de script Robo que limpa os dados do usuário do app em teste:

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

Conceder permissões

Esta ação é gravada pelo gravador de scripts Robo no Android Studio para compatibilidade com versões anteriores com o Espresso Test Recorder. O teste Robo concede todas as permissões para o app em teste no início de cada rastreamento, portanto, esta ação é não é operacional. NÃO use esta ação nos scripts Robo.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "PERMISSIONS_REQUEST" --

Ignorar todos os elementos em uma tela

Essa ação faz com que o Robo ignore todos os elementos em qualquer tela que acione o script Robo onde ela está.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ALL_ELEMENTS_IGNORED" --

Confira a seguir o exemplo de uma ação de script Robo que faz com que ele ignore todos os elementos em uma tela:

{
  "eventType": "ALL_ELEMENTS_IGNORED"
}

Ignorar um elemento

Esta ação faz com que o Robo ignore um ou mais elementos correspondentes ao elementDescriptors especificado.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ELEMENT_IGNORED" --
elementDescriptors Identifica widget(s) de interface ignorado(s) usando a hierarquia de interface do Android.

O atributo a seguir é opcional:

  • ignoreChildren: se definido como true, o Robo também ignorará todos os descendentes dos widgets de interface ignorados. Por padrão, ele é false.

Confira a seguir o exemplo de uma ação do script Robo que faz com que ele ignore todos os elementos com descrições de conteúdo que comecem com "Avatar":

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

Entrada de texto

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
eventType Especifica o tipo de ação do script Robo.
"eventType": "VIEW_TEXT_CHANGED" Insere o texto fornecido no widget da IU de destino.
"eventType": "ENTER_TEXT" Insere o texto fornecido no widget da IU de destino e, em seguida, envia um evento KEYCODE_ENTER para esse widget de IU.
elementDescriptors Identifica o widget da IU de destino usando a hierarquia de IU do Android.
replacementText O texto a ser inserido no widget da IU de destino.

Veja a seguir o exemplo de uma ação de script Robo que insere "John" em um widget de IU com o ID do recurso "com.google.samples.apps.topeka:id/first_name":

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

Clique longo

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "VIEW_LONG_CLICKED" --
elementDescriptors Identifica o widget da IU de destino usando a hierarquia de IU do Android. Mutuamente exclusivo com visionText.
visionText Identifica o elemento selecionado com clique longo usando o OCR. Mutuamente exclusivo com elementDescriptors.

O atributo a seguir é opcional:

  • delayTime: especifica a duração de um clique longo em milissegundos.

Confira a seguir o exemplo de uma ação de script Robo que executa um clique de cinco segundos em um widget de IU com descrição de conteúdo "Avatar 8":

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

Executar um gesto de um ponto

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ONE_POINT_GESTURE" --
coordinates Duas coordenadas para um gesto de um ponto, formatado como "(x1,y1)->(x2,y2)" como porcentagens ou pixels.

O atributo a seguir é opcional:

  • dragAndDrop: se definido como true, o gesto de um ponto vai realizar uma ação de arrastar e soltar. Por padrão, ele é false.

Veja a seguir o exemplo de uma ação de gesto de um ponto do script Robo que executa a ação de deslizar para baixo:

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

Executar um gesto de dois pontos

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "TWO_POINT_GESTURE" --
coordinates Quatro coordenadas para um gesto de dois pontos, formatado como "(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" como porcentagens ou pixels.

Veja a seguir o exemplo de uma ação de script Robo que executa um gesto de pinça:

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

Executar uma ação do IME

Esta ação pressiona o botão de ação atual, como "próximo", "concluído" e "pesquisar", no Editor de método de entrada (IME, na sigla em inglês) do widget de IU de destino especificado.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "PRESSED_EDITOR_ACTION" --
elementDescriptors Identifica o widget da IU de destino usando a hierarquia de IU do Android.

Veja a seguir o exemplo de uma ação de script Robo que executa uma ação do IME em um widget de IU com o ID do recurso "com.google.samples.apps.topeka:id/first_name":

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

Pressionar "Voltar"

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
eventType Especifica o tipo de ação do script Robo.
"eventType": "PRESSED_BACK" Envia um evento KEYCODE_BACK para o dispositivo.
"eventType": "PRESSED_BACK_EMULATOR_28" Usado pelo Gravador de script Robo no Android Studio para pressionar de volta no nível de API 28 dos emuladores.

Veja a seguir o exemplo de ação de script Robo que pressiona de volta:

{
  "eventType": "PRESSED_BACK"
}

Pressionar "Início"

Esta ação envia um evento KEYCODE_HOME para o dispositivo.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "GO_HOME" --

Veja a seguir o exemplo de ação de script Robo que pressiona "Início":

{
  "eventType": "GO_HOME"
}

Rolar um elemento para visualização

Esta ação faz o teste Robo avançar o widget da IU correspondente ao elementDescriptors especificado até que o widget da IU correspondente aos childElementDescriptors especificados esteja na tela ou que o widget rolado não possa mais ser rolado ou o número máximo de 50 rolagens seja atingido.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "ELEMENT_SCROLL_INTO_VIEW" --
elementDescriptors Identifica o widget de IU rolado usando a hierarquia de IU do Android.
childElementDescriptors Identifica o widget de IU a ser rolado usando a hierarquia de IU do Android.

Este exemplo é de uma ação de script Robo que faz a rolagem do widget da IU com o ID do recurso "my.app.package:id/scrollable_card_container" até que o widget da IU com texto "Orange" seja exibido na tela ou que não seja mais possível realizar nenhuma rolagem ou que o número máximo de 50 rolagens seja atingido:

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

Deslizar

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "VIEW_SWIPED" --
swipeDirection Especifica em que direção deslizar:
  • Left
  • Right
  • Up
  • Down
  • Forward: Down ou Right, dependendo da capacidade de rolagem vertical ou horizontal do widget da IU de destino.
  • Backward: Up ou Left, dependendo da capacidade de rolagem vertical ou horizontal do widget da IU de destino.
elementDescriptors Identifica o widget da IU de destino usando a hierarquia de IU do Android.

Veja a seguir o exemplo de uma ação de script Robo que desliza para cima um widget de IU com o ID do recurso "my.app.package:id/custom_content":

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

Fazer uma captura de tela

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "TAKE_SCREENSHOT" --
screenshotName Especifica o nome do arquivo de captura de tela.

Veja a seguir o exemplo de uma ação de script Robo que faz uma captura de tela:

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

Tocar em um ponto na tela

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "POINT_TAP" --
pointTapXCoordinate A coordenada do pixel X do ponto de toque. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent.
pointTapYCoordinate A coordenada do pixel Y do ponto de toque. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent.
pointTapXPercent É a coordenada X percentual do ponto de toque. Mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate.
pointTapYPercent É a coordenada Y percentual do ponto de toque. Mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate.

Veja a seguir o exemplo de uma ação de script Robo que toca no meio de uma tela:

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

Tocar em um ponto em um elemento

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "POINT_TAP_ELEMENT" --
pointTapXPercent É a coordenada X percentual no elemento de destino.
pointTapYPercent É a coordenada Y percentual no elemento de destino.
elementDescriptors Identifica o widget da IU de destino usando a hierarquia de IU do Android.

Veja a seguir o exemplo de uma ação de script Robo que move o controle deslizante de uma barra de busca para a direita:

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

Encerrar rastreamento

Esta ação interrompe o teste Robo.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "TERMINATE_CRAWL" --

Veja a seguir o exemplo de uma ação de script Robo que interrompe um teste Robo:

{
  "eventType": "TERMINATE_CRAWL"
}

Espera

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "DELAYED_MESSAGE_POSTED" --
delayTime Especifica o tempo de espera, em milissegundos.

Veja a seguir o exemplo de uma ação de script Robo que aguarda três segundos:

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

Aguardar um elemento

Esta ação faz o teste Robo aguardar a exibição de um elemento na tela até o tempo limite especificado.

A tabela a seguir lista os atributos obrigatórios:

Atributo Descrição
"eventType": "WAIT_FOR_ELEMENT" --
delayTime Especifica o tempo limite de espera em milissegundos.
elementDescriptors Identifica o widget de IU esperado usando a hierarquia de IU do Android.

Veja a seguir o exemplo de uma ação de script Robo que aguarda até 30 segundos para que um widget de IU com o ID do recurso "my.app.package:id/confirmation_button" seja exibido na tela:

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

Próximas etapas